From 55c52aa7c47148ece65585ae6f9b611b7e00e927 Mon Sep 17 00:00:00 2001 From: cvs2git Date: Wed, 19 Apr 2006 14:25:03 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'rtems-addon- packages-4-6-99-3'. Sprout from ncurses-gnu 2002-12-19 15:34:54 UTC Eric Norum 'Latest ncurses add-on' Cherrypick from addons 2002-06-28 21:58:41 UTC Eric Norum 'Useful add-on libraries': README RTEMS_Makefiles/Makefile.avl RTEMS_Makefiles/Makefile.common RTEMS_Makefiles/Makefile.site avl-1.4.0/AUTHORS avl-1.4.0/COPYING avl-1.4.0/ChangeLog avl-1.4.0/INSTALL avl-1.4.0/Makefile.am avl-1.4.0/Makefile.in avl-1.4.0/NEWS avl-1.4.0/README avl-1.4.0/THANKS avl-1.4.0/TODO avl-1.4.0/aclocal.m4 avl-1.4.0/avl.c avl-1.4.0/avl.h avl-1.4.0/avl.html avl-1.4.0/avl.info avl-1.4.0/avl.texinfo avl-1.4.0/avl.text avl-1.4.0/avlt.c avl-1.4.0/avlt.h avl-1.4.0/avltr.c avl-1.4.0/avltr.h avl-1.4.0/configure avl-1.4.0/configure.in avl-1.4.0/install-sh avl-1.4.0/missing avl-1.4.0/mkinstalldirs avl-1.4.0/rb.c avl-1.4.0/rb.h avl-1.4.0/texinfo.tex avl-1.4.0/thread-test.c examples/avl/BuildTests.sh examples/avl/Makefile examples/avl/README examples/avl/init.c examples/ncurses/BuildTests.sh examples/ncurses/Makefile examples/ncurses/README examples/ncurses/init.c examples/readline/.gdbinit examples/readline/Makefile examples/readline/init.c examples/readline/rlgeneric.c ncurses-5.2/ANNOUNCE ncurses-5.2/Ada95/Makefile.in ncurses-5.2/Ada95/README ncurses-5.2/Ada95/TODO ncurses-5.2/Ada95/gen/Makefile.in ncurses-5.2/Ada95/gen/gen.c ncurses-5.2/Ada95/gen/html.m4 ncurses-5.2/Ada95/gen/normal.m4 ncurses-5.2/Ada95/gen/table.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-aux.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-mouse.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses-panels.ads.m4 ncurses-5.2/Ada95/gen/terminal_interface-curses.ads.m4 ncurses-5.2/Ada95/samples/Makefile.in ncurses-5.2/Ada95/samples/README ncurses-5.2/Ada95/samples/explain.txt ncurses-5.2/Ada95/samples/rain.adb ncurses-5.2/Ada95/samples/rain.ads ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.adb ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.ads ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.adb ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.ads ncurses-5.2/Ada95/samples/sample-curses_demo.adb ncurses-5.2/Ada95/samples/sample-curses_demo.ads ncurses-5.2/Ada95/samples/sample-explanation.adb ncurses-5.2/Ada95/samples/sample-explanation.ads ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads ncurses-5.2/Ada95/samples/sample-form_demo-handler.adb ncurses-5.2/Ada95/samples/sample-form_demo-handler.ads ncurses-5.2/Ada95/samples/sample-form_demo.adb ncurses-5.2/Ada95/samples/sample-form_demo.ads ncurses-5.2/Ada95/samples/sample-function_key_setting.adb ncurses-5.2/Ada95/samples/sample-function_key_setting.ads ncurses-5.2/Ada95/samples/sample-header_handler.adb ncurses-5.2/Ada95/samples/sample-header_handler.ads ncurses-5.2/Ada95/samples/sample-helpers.adb ncurses-5.2/Ada95/samples/sample-helpers.ads ncurses-5.2/Ada95/samples/sample-keyboard_handler.adb ncurses-5.2/Ada95/samples/sample-keyboard_handler.ads ncurses-5.2/Ada95/samples/sample-manifest.ads ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads ncurses-5.2/Ada95/samples/sample-menu_demo-handler.adb ncurses-5.2/Ada95/samples/sample-menu_demo-handler.ads ncurses-5.2/Ada95/samples/sample-menu_demo.adb ncurses-5.2/Ada95/samples/sample-menu_demo.ads ncurses-5.2/Ada95/samples/sample-my_field_type.adb ncurses-5.2/Ada95/samples/sample-my_field_type.ads ncurses-5.2/Ada95/samples/sample-text_io_demo.adb ncurses-5.2/Ada95/samples/sample-text_io_demo.ads ncurses-5.2/Ada95/samples/sample.adb ncurses-5.2/Ada95/samples/sample.ads ncurses-5.2/Ada95/samples/status.adb ncurses-5.2/Ada95/samples/status.ads ncurses-5.2/Ada95/samples/tour.adb ncurses-5.2/Ada95/samples/tour.ads ncurses-5.2/Ada95/src/Makefile.in ncurses-5.2/Ada95/src/terminal_interface-curses-aux.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.ads ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_user_data.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms-form_user_data.adb ncurses-5.2/Ada95/src/terminal_interface-curses-forms.adb ncurses-5.2/Ada95/src/terminal_interface-curses-menus-item_user_data.adb ncurses-5.2/Ada95/src/terminal_interface-curses-menus-menu_user_data.adb ncurses-5.2/Ada95/src/terminal_interface-curses-menus.adb ncurses-5.2/Ada95/src/terminal_interface-curses-mouse.adb ncurses-5.2/Ada95/src/terminal_interface-curses-panels-user_data.adb ncurses-5.2/Ada95/src/terminal_interface-curses-panels.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.adb ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.ads ncurses-5.2/Ada95/src/terminal_interface-curses.adb ncurses-5.2/Ada95/src/terminal_interface.ads ncurses-5.2/INSTALL ncurses-5.2/MANIFEST ncurses-5.2/Makefile.glibc ncurses-5.2/Makefile.in ncurses-5.2/Makefile.os2 ncurses-5.2/NEWS ncurses-5.2/README ncurses-5.2/README.emx ncurses-5.2/README.glibc ncurses-5.2/TO-DO ncurses-5.2/aclocal.m4 ncurses-5.2/announce.html.in ncurses-5.2/c++/Makefile.in ncurses-5.2/c++/NEWS ncurses-5.2/c++/PROBLEMS ncurses-5.2/c++/README-first ncurses-5.2/c++/cursesapp.cc ncurses-5.2/c++/cursesapp.h ncurses-5.2/c++/cursesf.cc ncurses-5.2/c++/cursesf.h ncurses-5.2/c++/cursesm.cc ncurses-5.2/c++/cursesm.h ncurses-5.2/c++/cursesmain.cc ncurses-5.2/c++/cursesp.cc ncurses-5.2/c++/cursesp.h ncurses-5.2/c++/cursespad.cc ncurses-5.2/c++/cursesw.cc ncurses-5.2/c++/cursesw.h ncurses-5.2/c++/cursslk.cc ncurses-5.2/c++/cursslk.h ncurses-5.2/c++/demo.cc ncurses-5.2/c++/edit_cfg.sh ncurses-5.2/c++/etip.h.in ncurses-5.2/c++/headers ncurses-5.2/c++/internal.h ncurses-5.2/c++/modules ncurses-5.2/config.guess ncurses-5.2/config.sub ncurses-5.2/configure ncurses-5.2/configure.in ncurses-5.2/convert_configure.pl ncurses-5.2/dist.mk ncurses-5.2/doc/hackguide.doc ncurses-5.2/doc/html/Ada95.html ncurses-5.2/doc/html/ada/files.htm ncurses-5.2/doc/html/ada/files/T.htm ncurses-5.2/doc/html/ada/funcs.htm ncurses-5.2/doc/html/ada/funcs/A.htm ncurses-5.2/doc/html/ada/funcs/B.htm ncurses-5.2/doc/html/ada/funcs/C.htm ncurses-5.2/doc/html/ada/funcs/D.htm ncurses-5.2/doc/html/ada/funcs/E.htm ncurses-5.2/doc/html/ada/funcs/F.htm ncurses-5.2/doc/html/ada/funcs/G.htm ncurses-5.2/doc/html/ada/funcs/H.htm ncurses-5.2/doc/html/ada/funcs/I.htm ncurses-5.2/doc/html/ada/funcs/K.htm ncurses-5.2/doc/html/ada/funcs/L.htm ncurses-5.2/doc/html/ada/funcs/M.htm ncurses-5.2/doc/html/ada/funcs/N.htm ncurses-5.2/doc/html/ada/funcs/O.htm ncurses-5.2/doc/html/ada/funcs/P.htm ncurses-5.2/doc/html/ada/funcs/Q.htm ncurses-5.2/doc/html/ada/funcs/R.htm ncurses-5.2/doc/html/ada/funcs/S.htm ncurses-5.2/doc/html/ada/funcs/T.htm ncurses-5.2/doc/html/ada/funcs/U.htm ncurses-5.2/doc/html/ada/funcs/V.htm ncurses-5.2/doc/html/ada/funcs/W.htm ncurses-5.2/doc/html/ada/index.htm ncurses-5.2/doc/html/ada/main.htm ncurses-5.2/doc/html/ada/table.html ncurses-5.2/doc/html/ada/terminal_interface-curses-aux__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-aux__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alpha__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alpha__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-intfield__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-intfield__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-numeric__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-numeric__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-regexp__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-regexp__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_user_data__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_user_data__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-form_user_data__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-form_user_data__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-forms__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-item_user_data__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-item_user_data__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-menu_user_data__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-menu_user_data__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-menus__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-mouse__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-mouse__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-panels-user_data__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-panels-user_data__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-panels__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-panels__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-aux__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-aux__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-complex_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-complex_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-decimal_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-decimal_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-enumeration_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-enumeration_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-fixed_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-fixed_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-float_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-float_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-integer_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-integer_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-modular_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-modular_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io__ads.htm ncurses-5.2/doc/html/ada/terminal_interface-curses__adb.htm ncurses-5.2/doc/html/ada/terminal_interface-curses__ads.htm ncurses-5.2/doc/html/ada/terminal_interface__ads.htm ncurses-5.2/doc/html/announce.html ncurses-5.2/doc/html/hackguide.html ncurses-5.2/doc/html/index.html ncurses-5.2/doc/html/man/captoinfo.1m.html ncurses-5.2/doc/html/man/clear.1.html ncurses-5.2/doc/html/man/curs_addch.3x.html ncurses-5.2/doc/html/man/curs_addchstr.3x.html ncurses-5.2/doc/html/man/curs_addstr.3x.html ncurses-5.2/doc/html/man/curs_attr.3x.html ncurses-5.2/doc/html/man/curs_beep.3x.html ncurses-5.2/doc/html/man/curs_bkgd.3x.html ncurses-5.2/doc/html/man/curs_border.3x.html ncurses-5.2/doc/html/man/curs_clear.3x.html ncurses-5.2/doc/html/man/curs_color.3x.html ncurses-5.2/doc/html/man/curs_delch.3x.html ncurses-5.2/doc/html/man/curs_deleteln.3x.html ncurses-5.2/doc/html/man/curs_extend.3x.html ncurses-5.2/doc/html/man/curs_getch.3x.html ncurses-5.2/doc/html/man/curs_getstr.3x.html ncurses-5.2/doc/html/man/curs_getyx.3x.html ncurses-5.2/doc/html/man/curs_inch.3x.html ncurses-5.2/doc/html/man/curs_inchstr.3x.html ncurses-5.2/doc/html/man/curs_initscr.3x.html ncurses-5.2/doc/html/man/curs_inopts.3x.html ncurses-5.2/doc/html/man/curs_insch.3x.html ncurses-5.2/doc/html/man/curs_insstr.3x.html ncurses-5.2/doc/html/man/curs_instr.3x.html ncurses-5.2/doc/html/man/curs_kernel.3x.html ncurses-5.2/doc/html/man/curs_mouse.3x.html ncurses-5.2/doc/html/man/curs_move.3x.html ncurses-5.2/doc/html/man/curs_outopts.3x.html ncurses-5.2/doc/html/man/curs_overlay.3x.html ncurses-5.2/doc/html/man/curs_pad.3x.html ncurses-5.2/doc/html/man/curs_print.3x.html ncurses-5.2/doc/html/man/curs_printw.3x.html ncurses-5.2/doc/html/man/curs_refresh.3x.html ncurses-5.2/doc/html/man/curs_scanw.3x.html ncurses-5.2/doc/html/man/curs_scr_dump.3x.html ncurses-5.2/doc/html/man/curs_scroll.3x.html ncurses-5.2/doc/html/man/curs_slk.3x.html ncurses-5.2/doc/html/man/curs_termattrs.3x.html ncurses-5.2/doc/html/man/curs_termcap.3x.html ncurses-5.2/doc/html/man/curs_terminfo.3x.html ncurses-5.2/doc/html/man/curs_touch.3x.html ncurses-5.2/doc/html/man/curs_trace.3x.html ncurses-5.2/doc/html/man/curs_util.3x.html ncurses-5.2/doc/html/man/curs_window.3x.html ncurses-5.2/doc/html/man/default_colors.3x.html ncurses-5.2/doc/html/man/define_key.3x.html ncurses-5.2/doc/html/man/form.3x.html ncurses-5.2/doc/html/man/form_cursor.3x.html ncurses-5.2/doc/html/man/form_data.3x.html ncurses-5.2/doc/html/man/form_driver.3x.html ncurses-5.2/doc/html/man/form_field.3x.html ncurses-5.2/doc/html/man/form_field_attributes.3x.html ncurses-5.2/doc/html/man/form_field_buffer.3x.html ncurses-5.2/doc/html/man/form_field_info.3x.html ncurses-5.2/doc/html/man/form_field_just.3x.html ncurses-5.2/doc/html/man/form_field_new.3x.html ncurses-5.2/doc/html/man/form_field_opts.3x.html ncurses-5.2/doc/html/man/form_field_userptr.3x.html ncurses-5.2/doc/html/man/form_field_validation.3x.html ncurses-5.2/doc/html/man/form_fieldtype.3x.html ncurses-5.2/doc/html/man/form_hook.3x.html ncurses-5.2/doc/html/man/form_new.3x.html ncurses-5.2/doc/html/man/form_new_page.3x.html ncurses-5.2/doc/html/man/form_opts.3x.html ncurses-5.2/doc/html/man/form_page.3x.html ncurses-5.2/doc/html/man/form_post.3x.html ncurses-5.2/doc/html/man/form_requestname.3x.html ncurses-5.2/doc/html/man/form_userptr.3x.html ncurses-5.2/doc/html/man/form_win.3x.html ncurses-5.2/doc/html/man/infocmp.1m.html ncurses-5.2/doc/html/man/infotocap.1m.html ncurses-5.2/doc/html/man/keybound.3x.html ncurses-5.2/doc/html/man/keyok.3x.html ncurses-5.2/doc/html/man/menu.3x.html ncurses-5.2/doc/html/man/menu_attributes.3x.html ncurses-5.2/doc/html/man/menu_cursor.3x.html ncurses-5.2/doc/html/man/menu_driver.3x.html ncurses-5.2/doc/html/man/menu_format.3x.html ncurses-5.2/doc/html/man/menu_hook.3x.html ncurses-5.2/doc/html/man/menu_items.3x.html ncurses-5.2/doc/html/man/menu_mark.3x.html ncurses-5.2/doc/html/man/menu_new.3x.html ncurses-5.2/doc/html/man/menu_opts.3x.html ncurses-5.2/doc/html/man/menu_pattern.3x.html ncurses-5.2/doc/html/man/menu_post.3x.html ncurses-5.2/doc/html/man/menu_requestname.3x.html ncurses-5.2/doc/html/man/menu_spacing.3x.html ncurses-5.2/doc/html/man/menu_userptr.3x.html ncurses-5.2/doc/html/man/menu_win.3x.html ncurses-5.2/doc/html/man/mitem_current.3x.html ncurses-5.2/doc/html/man/mitem_name.3x.html ncurses-5.2/doc/html/man/mitem_new.3x.html ncurses-5.2/doc/html/man/mitem_opts.3x.html ncurses-5.2/doc/html/man/mitem_userptr.3x.html ncurses-5.2/doc/html/man/mitem_value.3x.html ncurses-5.2/doc/html/man/mitem_visible.3x.html ncurses-5.2/doc/html/man/ncurses.3x.html ncurses-5.2/doc/html/man/panel.3x.html ncurses-5.2/doc/html/man/resizeterm.3x.html ncurses-5.2/doc/html/man/term.5.html ncurses-5.2/doc/html/man/term.7.html ncurses-5.2/doc/html/man/terminfo.5.html ncurses-5.2/doc/html/man/tic.1m.html ncurses-5.2/doc/html/man/toe.1m.html ncurses-5.2/doc/html/man/tput.1.html ncurses-5.2/doc/html/man/tset.1.html ncurses-5.2/doc/html/man/wresize.3x.html ncurses-5.2/doc/html/ncurses-intro.html ncurses-5.2/doc/ncurses-intro.doc ncurses-5.2/form/Makefile.in ncurses-5.2/form/READ.ME ncurses-5.2/form/fld_arg.c ncurses-5.2/form/fld_attr.c ncurses-5.2/form/fld_current.c ncurses-5.2/form/fld_def.c ncurses-5.2/form/fld_dup.c ncurses-5.2/form/fld_ftchoice.c ncurses-5.2/form/fld_ftlink.c ncurses-5.2/form/fld_info.c ncurses-5.2/form/fld_just.c ncurses-5.2/form/fld_link.c ncurses-5.2/form/fld_max.c ncurses-5.2/form/fld_move.c ncurses-5.2/form/fld_newftyp.c ncurses-5.2/form/fld_opts.c ncurses-5.2/form/fld_pad.c ncurses-5.2/form/fld_page.c ncurses-5.2/form/fld_stat.c ncurses-5.2/form/fld_type.c ncurses-5.2/form/fld_user.c ncurses-5.2/form/form.h ncurses-5.2/form/form.priv.h ncurses-5.2/form/frm_cursor.c ncurses-5.2/form/frm_data.c ncurses-5.2/form/frm_def.c ncurses-5.2/form/frm_driver.c ncurses-5.2/form/frm_hook.c ncurses-5.2/form/frm_opts.c ncurses-5.2/form/frm_page.c ncurses-5.2/form/frm_post.c ncurses-5.2/form/frm_req_name.c ncurses-5.2/form/frm_scale.c ncurses-5.2/form/frm_sub.c ncurses-5.2/form/frm_user.c ncurses-5.2/form/frm_win.c ncurses-5.2/form/fty_alnum.c ncurses-5.2/form/fty_alpha.c ncurses-5.2/form/fty_enum.c ncurses-5.2/form/fty_int.c ncurses-5.2/form/fty_ipv4.c ncurses-5.2/form/fty_num.c ncurses-5.2/form/fty_regex.c ncurses-5.2/form/headers ncurses-5.2/form/llib-lform ncurses-5.2/form/modules ncurses-5.2/include/Caps ncurses-5.2/include/MKhashsize.sh ncurses-5.2/include/MKncurses_def.sh ncurses-5.2/include/MKparametrized.sh ncurses-5.2/include/MKterm.h.awk.in ncurses-5.2/include/Makefile.in ncurses-5.2/include/capdefaults.c ncurses-5.2/include/curses.h.in ncurses-5.2/include/edit_cfg.sh ncurses-5.2/include/headers ncurses-5.2/include/nc_alloc.h ncurses-5.2/include/nc_panel.h ncurses-5.2/include/ncurses_cfg.hin ncurses-5.2/include/ncurses_defs ncurses-5.2/include/term_entry.h ncurses-5.2/include/termcap.h.in ncurses-5.2/include/tic.h ncurses-5.2/include/unctrl.h.in ncurses-5.2/install-sh ncurses-5.2/man/MKterminfo.sh ncurses-5.2/man/Makefile.in ncurses-5.2/man/captoinfo.1m ncurses-5.2/man/clear.1 ncurses-5.2/man/curs_addch.3x ncurses-5.2/man/curs_addchstr.3x ncurses-5.2/man/curs_addstr.3x ncurses-5.2/man/curs_attr.3x ncurses-5.2/man/curs_beep.3x ncurses-5.2/man/curs_bkgd.3x ncurses-5.2/man/curs_border.3x ncurses-5.2/man/curs_clear.3x ncurses-5.2/man/curs_color.3x ncurses-5.2/man/curs_delch.3x ncurses-5.2/man/curs_deleteln.3x ncurses-5.2/man/curs_extend.3x ncurses-5.2/man/curs_getch.3x ncurses-5.2/man/curs_getstr.3x ncurses-5.2/man/curs_getyx.3x ncurses-5.2/man/curs_inch.3x ncurses-5.2/man/curs_inchstr.3x ncurses-5.2/man/curs_initscr.3x ncurses-5.2/man/curs_inopts.3x ncurses-5.2/man/curs_insch.3x ncurses-5.2/man/curs_insstr.3x ncurses-5.2/man/curs_instr.3x ncurses-5.2/man/curs_kernel.3x ncurses-5.2/man/curs_mouse.3x ncurses-5.2/man/curs_move.3x ncurses-5.2/man/curs_outopts.3x ncurses-5.2/man/curs_overlay.3x ncurses-5.2/man/curs_pad.3x ncurses-5.2/man/curs_print.3x ncurses-5.2/man/curs_printw.3x ncurses-5.2/man/curs_refresh.3x ncurses-5.2/man/curs_scanw.3x ncurses-5.2/man/curs_scr_dump.3x ncurses-5.2/man/curs_scroll.3x ncurses-5.2/man/curs_slk.3x ncurses-5.2/man/curs_termattrs.3x ncurses-5.2/man/curs_termcap.3x ncurses-5.2/man/curs_terminfo.3x ncurses-5.2/man/curs_touch.3x ncurses-5.2/man/curs_trace.3x ncurses-5.2/man/curs_util.3x ncurses-5.2/man/curs_window.3x ncurses-5.2/man/default_colors.3x ncurses-5.2/man/define_key.3x ncurses-5.2/man/form.3x ncurses-5.2/man/form_cursor.3x ncurses-5.2/man/form_data.3x ncurses-5.2/man/form_driver.3x ncurses-5.2/man/form_field.3x ncurses-5.2/man/form_field_attributes.3x ncurses-5.2/man/form_field_buffer.3x ncurses-5.2/man/form_field_info.3x ncurses-5.2/man/form_field_just.3x ncurses-5.2/man/form_field_new.3x ncurses-5.2/man/form_field_opts.3x ncurses-5.2/man/form_field_userptr.3x ncurses-5.2/man/form_field_validation.3x ncurses-5.2/man/form_fieldtype.3x ncurses-5.2/man/form_hook.3x ncurses-5.2/man/form_new.3x ncurses-5.2/man/form_new_page.3x ncurses-5.2/man/form_opts.3x ncurses-5.2/man/form_page.3x ncurses-5.2/man/form_post.3x ncurses-5.2/man/form_requestname.3x ncurses-5.2/man/form_userptr.3x ncurses-5.2/man/form_win.3x ncurses-5.2/man/infocmp.1m ncurses-5.2/man/infotocap.1m ncurses-5.2/man/keybound.3x ncurses-5.2/man/keyok.3x ncurses-5.2/man/make_sed.sh ncurses-5.2/man/man_db.renames ncurses-5.2/man/manlinks.sed ncurses-5.2/man/menu.3x ncurses-5.2/man/menu_attributes.3x ncurses-5.2/man/menu_cursor.3x ncurses-5.2/man/menu_driver.3x ncurses-5.2/man/menu_format.3x ncurses-5.2/man/menu_hook.3x ncurses-5.2/man/menu_items.3x ncurses-5.2/man/menu_mark.3x ncurses-5.2/man/menu_new.3x ncurses-5.2/man/menu_opts.3x ncurses-5.2/man/menu_pattern.3x ncurses-5.2/man/menu_post.3x ncurses-5.2/man/menu_requestname.3x ncurses-5.2/man/menu_spacing.3x ncurses-5.2/man/menu_userptr.3x ncurses-5.2/man/menu_win.3x ncurses-5.2/man/mitem_current.3x ncurses-5.2/man/mitem_name.3x ncurses-5.2/man/mitem_new.3x ncurses-5.2/man/mitem_opts.3x ncurses-5.2/man/mitem_userptr.3x ncurses-5.2/man/mitem_value.3x ncurses-5.2/man/mitem_visible.3x ncurses-5.2/man/ncurses.3x ncurses-5.2/man/panel.3x ncurses-5.2/man/resizeterm.3x ncurses-5.2/man/term.5 ncurses-5.2/man/term.7 ncurses-5.2/man/terminfo.head ncurses-5.2/man/terminfo.tail ncurses-5.2/man/tic.1m ncurses-5.2/man/toe.1m ncurses-5.2/man/tput.1 ncurses-5.2/man/tset.1 ncurses-5.2/man/wresize.3x ncurses-5.2/menu/Makefile.in ncurses-5.2/menu/READ.ME ncurses-5.2/menu/eti.h ncurses-5.2/menu/headers ncurses-5.2/menu/llib-lmenu ncurses-5.2/menu/m_attribs.c ncurses-5.2/menu/m_cursor.c ncurses-5.2/menu/m_driver.c ncurses-5.2/menu/m_format.c ncurses-5.2/menu/m_global.c ncurses-5.2/menu/m_hook.c ncurses-5.2/menu/m_item_cur.c ncurses-5.2/menu/m_item_nam.c ncurses-5.2/menu/m_item_new.c ncurses-5.2/menu/m_item_opt.c ncurses-5.2/menu/m_item_top.c ncurses-5.2/menu/m_item_use.c ncurses-5.2/menu/m_item_val.c ncurses-5.2/menu/m_item_vis.c ncurses-5.2/menu/m_items.c ncurses-5.2/menu/m_new.c ncurses-5.2/menu/m_opts.c ncurses-5.2/menu/m_pad.c ncurses-5.2/menu/m_pattern.c ncurses-5.2/menu/m_post.c ncurses-5.2/menu/m_req_name.c ncurses-5.2/menu/m_scale.c ncurses-5.2/menu/m_spacing.c ncurses-5.2/menu/m_sub.c ncurses-5.2/menu/m_userptr.c ncurses-5.2/menu/m_win.c ncurses-5.2/menu/menu.h ncurses-5.2/menu/menu.priv.h ncurses-5.2/menu/mf_common.h ncurses-5.2/menu/modules ncurses-5.2/misc/Makefile.in ncurses-5.2/misc/chkdef.cmd ncurses-5.2/misc/cleantic.cmd ncurses-5.2/misc/cmpdef.cmd ncurses-5.2/misc/emx.src ncurses-5.2/misc/form.def ncurses-5.2/misc/form.ref ncurses-5.2/misc/indent.pro ncurses-5.2/misc/makedef.cmd ncurses-5.2/misc/makellib ncurses-5.2/misc/menu.def ncurses-5.2/misc/menu.ref ncurses-5.2/misc/ncurses.def ncurses-5.2/misc/ncurses.ref ncurses-5.2/misc/panel.def ncurses-5.2/misc/panel.ref ncurses-5.2/misc/run_tic.in ncurses-5.2/misc/shlib ncurses-5.2/misc/tabset/std ncurses-5.2/misc/tabset/stdcrt ncurses-5.2/misc/tabset/vt100 ncurses-5.2/misc/tabset/vt300 ncurses-5.2/misc/tdlint ncurses-5.2/misc/terminfo.src ncurses-5.2/mk-0th.awk ncurses-5.2/mk-1st.awk ncurses-5.2/mk-2nd.awk ncurses-5.2/mkinstalldirs ncurses-5.2/ncurses/Makefile.in ncurses-5.2/ncurses/README ncurses-5.2/ncurses/SigAction.h ncurses-5.2/ncurses/base/MKkeyname.awk ncurses-5.2/ncurses/base/MKlib_gen.sh ncurses-5.2/ncurses/base/MKunctrl.awk ncurses-5.2/ncurses/base/README ncurses-5.2/ncurses/base/define_key.c ncurses-5.2/ncurses/base/keybound.c ncurses-5.2/ncurses/base/keyok.c ncurses-5.2/ncurses/base/lib_addch.c ncurses-5.2/ncurses/base/lib_addstr.c ncurses-5.2/ncurses/base/lib_beep.c ncurses-5.2/ncurses/base/lib_bkgd.c ncurses-5.2/ncurses/base/lib_box.c ncurses-5.2/ncurses/base/lib_chgat.c ncurses-5.2/ncurses/base/lib_clear.c ncurses-5.2/ncurses/base/lib_clearok.c ncurses-5.2/ncurses/base/lib_clrbot.c ncurses-5.2/ncurses/base/lib_clreol.c ncurses-5.2/ncurses/base/lib_color.c ncurses-5.2/ncurses/base/lib_colorset.c ncurses-5.2/ncurses/base/lib_delch.c ncurses-5.2/ncurses/base/lib_delwin.c ncurses-5.2/ncurses/base/lib_dft_fgbg.c ncurses-5.2/ncurses/base/lib_echo.c ncurses-5.2/ncurses/base/lib_endwin.c ncurses-5.2/ncurses/base/lib_erase.c ncurses-5.2/ncurses/base/lib_flash.c ncurses-5.2/ncurses/base/lib_freeall.c ncurses-5.2/ncurses/base/lib_getch.c ncurses-5.2/ncurses/base/lib_getstr.c ncurses-5.2/ncurses/base/lib_hline.c ncurses-5.2/ncurses/base/lib_immedok.c ncurses-5.2/ncurses/base/lib_inchstr.c ncurses-5.2/ncurses/base/lib_initscr.c ncurses-5.2/ncurses/base/lib_insch.c ncurses-5.2/ncurses/base/lib_insdel.c ncurses-5.2/ncurses/base/lib_insstr.c ncurses-5.2/ncurses/base/lib_instr.c ncurses-5.2/ncurses/base/lib_isendwin.c ncurses-5.2/ncurses/base/lib_leaveok.c ncurses-5.2/ncurses/base/lib_mouse.c ncurses-5.2/ncurses/base/lib_move.c ncurses-5.2/ncurses/base/lib_mvwin.c ncurses-5.2/ncurses/base/lib_newterm.c ncurses-5.2/ncurses/base/lib_newwin.c ncurses-5.2/ncurses/base/lib_nl.c ncurses-5.2/ncurses/base/lib_overlay.c ncurses-5.2/ncurses/base/lib_pad.c ncurses-5.2/ncurses/base/lib_printw.c ncurses-5.2/ncurses/base/lib_redrawln.c ncurses-5.2/ncurses/base/lib_refresh.c ncurses-5.2/ncurses/base/lib_restart.c ncurses-5.2/ncurses/base/lib_scanw.c ncurses-5.2/ncurses/base/lib_screen.c ncurses-5.2/ncurses/base/lib_scroll.c ncurses-5.2/ncurses/base/lib_scrollok.c ncurses-5.2/ncurses/base/lib_scrreg.c ncurses-5.2/ncurses/base/lib_set_term.c ncurses-5.2/ncurses/base/lib_slk.c ncurses-5.2/ncurses/base/lib_slkatr_set.c ncurses-5.2/ncurses/base/lib_slkatrof.c ncurses-5.2/ncurses/base/lib_slkatron.c ncurses-5.2/ncurses/base/lib_slkatrset.c ncurses-5.2/ncurses/base/lib_slkattr.c ncurses-5.2/ncurses/base/lib_slkclear.c ncurses-5.2/ncurses/base/lib_slkcolor.c ncurses-5.2/ncurses/base/lib_slkinit.c ncurses-5.2/ncurses/base/lib_slklab.c ncurses-5.2/ncurses/base/lib_slkrefr.c ncurses-5.2/ncurses/base/lib_slkset.c ncurses-5.2/ncurses/base/lib_slktouch.c ncurses-5.2/ncurses/base/lib_touch.c ncurses-5.2/ncurses/base/lib_ungetch.c ncurses-5.2/ncurses/base/lib_vline.c ncurses-5.2/ncurses/base/lib_wattroff.c ncurses-5.2/ncurses/base/lib_wattron.c ncurses-5.2/ncurses/base/lib_winch.c ncurses-5.2/ncurses/base/lib_window.c ncurses-5.2/ncurses/base/memmove.c ncurses-5.2/ncurses/base/nc_panel.c ncurses-5.2/ncurses/base/resizeterm.c ncurses-5.2/ncurses/base/safe_sprintf.c ncurses-5.2/ncurses/base/sigaction.c ncurses-5.2/ncurses/base/tries.c ncurses-5.2/ncurses/base/version.c ncurses-5.2/ncurses/base/vsscanf.c ncurses-5.2/ncurses/base/wresize.c ncurses-5.2/ncurses/curses.priv.h ncurses-5.2/ncurses/fifo_defs.h ncurses-5.2/ncurses/llib-lncurses ncurses-5.2/ncurses/modules ncurses-5.2/ncurses/tinfo/MKcaptab.awk ncurses-5.2/ncurses/tinfo/MKfallback.sh ncurses-5.2/ncurses/tinfo/MKnames.awk ncurses-5.2/ncurses/tinfo/README ncurses-5.2/ncurses/tinfo/access.c ncurses-5.2/ncurses/tinfo/add_tries.c ncurses-5.2/ncurses/tinfo/alloc_entry.c ncurses-5.2/ncurses/tinfo/alloc_ttype.c ncurses-5.2/ncurses/tinfo/captoinfo.c ncurses-5.2/ncurses/tinfo/comp_error.c ncurses-5.2/ncurses/tinfo/comp_expand.c ncurses-5.2/ncurses/tinfo/comp_hash.c ncurses-5.2/ncurses/tinfo/comp_parse.c ncurses-5.2/ncurses/tinfo/comp_scan.c ncurses-5.2/ncurses/tinfo/doalloc.c ncurses-5.2/ncurses/tinfo/free_ttype.c ncurses-5.2/ncurses/tinfo/getenv_num.c ncurses-5.2/ncurses/tinfo/home_terminfo.c ncurses-5.2/ncurses/tinfo/init_keytry.c ncurses-5.2/ncurses/tinfo/keys.list ncurses-5.2/ncurses/tinfo/lib_acs.c ncurses-5.2/ncurses/tinfo/lib_baudrate.c ncurses-5.2/ncurses/tinfo/lib_cur_term.c ncurses-5.2/ncurses/tinfo/lib_data.c ncurses-5.2/ncurses/tinfo/lib_has_cap.c ncurses-5.2/ncurses/tinfo/lib_kernel.c ncurses-5.2/ncurses/tinfo/lib_longname.c ncurses-5.2/ncurses/tinfo/lib_napms.c ncurses-5.2/ncurses/tinfo/lib_options.c ncurses-5.2/ncurses/tinfo/lib_print.c ncurses-5.2/ncurses/tinfo/lib_raw.c ncurses-5.2/ncurses/tinfo/lib_setup.c ncurses-5.2/ncurses/tinfo/lib_termcap.c ncurses-5.2/ncurses/tinfo/lib_termname.c ncurses-5.2/ncurses/tinfo/lib_tgoto.c ncurses-5.2/ncurses/tinfo/lib_ti.c ncurses-5.2/ncurses/tinfo/lib_tparm.c ncurses-5.2/ncurses/tinfo/lib_tputs.c ncurses-5.2/ncurses/tinfo/lib_ttyflags.c ncurses-5.2/ncurses/tinfo/make_keys.c ncurses-5.2/ncurses/tinfo/name_match.c ncurses-5.2/ncurses/tinfo/parse_entry.c ncurses-5.2/ncurses/tinfo/read_entry.c ncurses-5.2/ncurses/tinfo/read_termcap.c ncurses-5.2/ncurses/tinfo/setbuf.c ncurses-5.2/ncurses/tinfo/strings.c ncurses-5.2/ncurses/tinfo/write_entry.c ncurses-5.2/ncurses/trace/README ncurses-5.2/ncurses/trace/lib_trace.c ncurses-5.2/ncurses/trace/lib_traceatr.c ncurses-5.2/ncurses/trace/lib_tracebits.c ncurses-5.2/ncurses/trace/lib_tracechr.c ncurses-5.2/ncurses/trace/lib_tracedmp.c ncurses-5.2/ncurses/trace/lib_tracemse.c ncurses-5.2/ncurses/trace/trace_buf.c ncurses-5.2/ncurses/trace/trace_tries.c ncurses-5.2/ncurses/trace/trace_xnames.c ncurses-5.2/ncurses/tty/MKexpanded.sh ncurses-5.2/ncurses/tty/hardscroll.c ncurses-5.2/ncurses/tty/hashmap.c ncurses-5.2/ncurses/tty/lib_mvcur.c ncurses-5.2/ncurses/tty/lib_tstp.c ncurses-5.2/ncurses/tty/lib_twait.c ncurses-5.2/ncurses/tty/lib_vidattr.c ncurses-5.2/ncurses/tty/tty_display.h ncurses-5.2/ncurses/tty/tty_input.h ncurses-5.2/ncurses/tty/tty_update.c ncurses-5.2/panel/Makefile.in ncurses-5.2/panel/headers ncurses-5.2/panel/llib-lpanel ncurses-5.2/panel/modules ncurses-5.2/panel/p_above.c ncurses-5.2/panel/p_below.c ncurses-5.2/panel/p_bottom.c ncurses-5.2/panel/p_delete.c ncurses-5.2/panel/p_hidden.c ncurses-5.2/panel/p_hide.c ncurses-5.2/panel/p_move.c ncurses-5.2/panel/p_new.c ncurses-5.2/panel/p_replace.c ncurses-5.2/panel/p_show.c ncurses-5.2/panel/p_top.c ncurses-5.2/panel/p_update.c ncurses-5.2/panel/p_user.c ncurses-5.2/panel/p_win.c ncurses-5.2/panel/panel.c ncurses-5.2/panel/panel.h ncurses-5.2/panel/panel.priv.h ncurses-5.2/progs/MKtermsort.sh ncurses-5.2/progs/Makefile.in ncurses-5.2/progs/capconvert ncurses-5.2/progs/clear.c ncurses-5.2/progs/clear.sh ncurses-5.2/progs/dump_entry.c ncurses-5.2/progs/dump_entry.h ncurses-5.2/progs/infocmp.c ncurses-5.2/progs/modules ncurses-5.2/progs/progs.priv.h ncurses-5.2/progs/tic.c ncurses-5.2/progs/toe.c ncurses-5.2/progs/tput.c ncurses-5.2/progs/tset.c ncurses-5.2/sysdeps/unix/sysv/linux/Makefile ncurses-5.2/sysdeps/unix/sysv/linux/alpha/configure ncurses-5.2/sysdeps/unix/sysv/linux/configure ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sed ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sh ncurses-5.2/sysdeps/unix/sysv/linux/run_tic.sh ncurses-5.2/tack/COPYING ncurses-5.2/tack/HISTORY ncurses-5.2/tack/Makefile.in ncurses-5.2/tack/README ncurses-5.2/tack/ansi.c ncurses-5.2/tack/charset.c ncurses-5.2/tack/color.c ncurses-5.2/tack/control.c ncurses-5.2/tack/crum.c ncurses-5.2/tack/edit.c ncurses-5.2/tack/fun.c ncurses-5.2/tack/init.c ncurses-5.2/tack/menu.c ncurses-5.2/tack/modes.c ncurses-5.2/tack/modules ncurses-5.2/tack/output.c ncurses-5.2/tack/pad.c ncurses-5.2/tack/scan.c ncurses-5.2/tack/sync.c ncurses-5.2/tack/sysdep.c ncurses-5.2/tack/tack.1 ncurses-5.2/tack/tack.c ncurses-5.2/tack/tack.h ncurses-5.2/tar-copy.sh ncurses-5.2/test/Makefile.in ncurses-5.2/test/README ncurses-5.2/test/blue.c ncurses-5.2/test/bs.6 ncurses-5.2/test/bs.c ncurses-5.2/test/cardfile.c ncurses-5.2/test/cardfile.dat ncurses-5.2/test/configure ncurses-5.2/test/configure.in ncurses-5.2/test/ditto.c ncurses-5.2/test/dots.c ncurses-5.2/test/filter.c ncurses-5.2/test/firework.c ncurses-5.2/test/firstlast.c ncurses-5.2/test/gdc.6 ncurses-5.2/test/gdc.c ncurses-5.2/test/hanoi.c ncurses-5.2/test/hashtest.c ncurses-5.2/test/keynames.c ncurses-5.2/test/knight.c ncurses-5.2/test/lrtest.c ncurses-5.2/test/modules ncurses-5.2/test/ncurses.c ncurses-5.2/test/ncurses_tst.hin ncurses-5.2/test/newdemo.c ncurses-5.2/test/railroad.c ncurses-5.2/test/rain.c ncurses-5.2/test/tclock.c ncurses-5.2/test/test.priv.h ncurses-5.2/test/testaddch.c ncurses-5.2/test/testcurs.c ncurses-5.2/test/testscanw.c ncurses-5.2/test/tracemunch ncurses-5.2/test/view.c ncurses-5.2/test/worm.c ncurses-5.2/test/xmas.c Cherrypick from master 2006-04-19 14:25:02 UTC Joel Sherrill '2006-04-19 Joel Sherrill ': ChangeLog RTEMS_Makefiles/Makefile.bfd RTEMS_Makefiles/Makefile.libtecla RTEMS_Makefiles/Makefile.ncurses RTEMS_Makefiles/Makefile.ncurses-5.3 RTEMS_Makefiles/Makefile.readline-4.3 RTEMS_Makefiles/Makefile.zlib SUPPORT VERSION bit bit_bfd libtecla-1.4.1/CHANGES libtecla-1.4.1/INSTALL libtecla-1.4.1/LICENSE.TERMS libtecla-1.4.1/Makefile libtecla-1.4.1/Makefile.in libtecla-1.4.1/Makefile.rules libtecla-1.4.1/Makefile.stub libtecla-1.4.1/PORTING libtecla-1.4.1/README libtecla-1.4.1/RELEASE.NOTES libtecla-1.4.1/config.guess libtecla-1.4.1/config.sub libtecla-1.4.1/configure libtecla-1.4.1/configure.in libtecla-1.4.1/cplfile.c libtecla-1.4.1/cplfile.h libtecla-1.4.1/cplmatch.c libtecla-1.4.1/demo.c libtecla-1.4.1/demo2.c libtecla-1.4.1/direader.c libtecla-1.4.1/direader.h libtecla-1.4.1/enhance.c libtecla-1.4.1/expand.c libtecla-1.4.1/freelist.c libtecla-1.4.1/freelist.h libtecla-1.4.1/getline.c libtecla-1.4.1/getline.h libtecla-1.4.1/hash.c libtecla-1.4.1/hash.h libtecla-1.4.1/history.c libtecla-1.4.1/history.h libtecla-1.4.1/homedir.c libtecla-1.4.1/homedir.h libtecla-1.4.1/html/changes.html libtecla-1.4.1/html/cpl_complete_word.html libtecla-1.4.1/html/ef_expand_file.html libtecla-1.4.1/html/enhance.html libtecla-1.4.1/html/gl_get_line.html libtecla-1.4.1/html/index.html libtecla-1.4.1/html/libtecla.html libtecla-1.4.1/html/pca_lookup_file.html libtecla-1.4.1/html/release.html libtecla-1.4.1/install-sh libtecla-1.4.1/keytab.c libtecla-1.4.1/keytab.h libtecla-1.4.1/libtecla.h libtecla-1.4.1/libtecla.map libtecla-1.4.1/man3/cfc_file_start.3 libtecla-1.4.1/man3/cfc_literal_escapes.3 libtecla-1.4.1/man3/cfc_set_check_fn.3 libtecla-1.4.1/man3/cpl_add_completion.3 libtecla-1.4.1/man3/cpl_complete_word.3 libtecla-1.4.1/man3/cpl_file_completions.3 libtecla-1.4.1/man3/cpl_last_error.3 libtecla-1.4.1/man3/cpl_list_completions.3 libtecla-1.4.1/man3/cpl_record_error.3 libtecla-1.4.1/man3/del_CplFileConf.3 libtecla-1.4.1/man3/del_ExpandFile.3 libtecla-1.4.1/man3/del_GetLine.3 libtecla-1.4.1/man3/del_PathCache.3 libtecla-1.4.1/man3/del_PcaPathConf.3 libtecla-1.4.1/man3/del_WordCompletion.3 libtecla-1.4.1/man3/ef_expand_file.3 libtecla-1.4.1/man3/ef_last_error.3 libtecla-1.4.1/man3/ef_list_expansions.3 libtecla-1.4.1/man3/enhance.3 libtecla-1.4.1/man3/gl_change_terminal.3 libtecla-1.4.1/man3/gl_clear_history.3 libtecla-1.4.1/man3/gl_configure_getline.3 libtecla-1.4.1/man3/gl_customize_completion.3 libtecla-1.4.1/man3/gl_echo_mode.3 libtecla-1.4.1/man3/gl_get_line.3 libtecla-1.4.1/man3/gl_group_history.3 libtecla-1.4.1/man3/gl_ignore_signal.3 libtecla-1.4.1/man3/gl_last_signal.3 libtecla-1.4.1/man3/gl_limit_history.3 libtecla-1.4.1/man3/gl_load_history.3 libtecla-1.4.1/man3/gl_lookup_history.3 libtecla-1.4.1/man3/gl_prompt_style.3 libtecla-1.4.1/man3/gl_range_of_history.3 libtecla-1.4.1/man3/gl_resize_history.3 libtecla-1.4.1/man3/gl_save_history.3 libtecla-1.4.1/man3/gl_show_history.3 libtecla-1.4.1/man3/gl_size_of_history.3 libtecla-1.4.1/man3/gl_state_of_history.3 libtecla-1.4.1/man3/gl_terminal_size.3 libtecla-1.4.1/man3/gl_toggle_history.3 libtecla-1.4.1/man3/gl_trap_signal.3 libtecla-1.4.1/man3/gl_watch_fd.3 libtecla-1.4.1/man3/libtecla.3 libtecla-1.4.1/man3/libtecla_version.3 libtecla-1.4.1/man3/new_CplFileConf.3 libtecla-1.4.1/man3/new_ExpandFile.3 libtecla-1.4.1/man3/new_GetLine.3 libtecla-1.4.1/man3/new_PathCache.3 libtecla-1.4.1/man3/new_PcaPathConf.3 libtecla-1.4.1/man3/new_WordCompletion.3 libtecla-1.4.1/man3/pca_last_error.3 libtecla-1.4.1/man3/pca_lookup_file.3 libtecla-1.4.1/man3/pca_path_completions.3 libtecla-1.4.1/man3/pca_scan_path.3 libtecla-1.4.1/man3/pca_set_check_fn.3 libtecla-1.4.1/man3/ppc_file_start.3 libtecla-1.4.1/man3/ppc_literal_escapes.3 libtecla-1.4.1/pathutil.c libtecla-1.4.1/pathutil.h libtecla-1.4.1/pcache.c libtecla-1.4.1/stringrp.c libtecla-1.4.1/stringrp.h libtecla-1.4.1/strngmem.c libtecla-1.4.1/strngmem.h libtecla-1.4.1/update_html libtecla-1.4.1/update_version libtecla-1.4.1/version.c ncurses-5.3/misc/run_tic.sh readline-4.3.orig/CHANGELOG readline-4.3.orig/CHANGES readline-4.3.orig/COPYING readline-4.3.orig/INSTALL readline-4.3.orig/MANIFEST readline-4.3.orig/Makefile.in readline-4.3.orig/README readline-4.3.orig/USAGE readline-4.3.orig/aclocal.m4 readline-4.3.orig/ansi_stdlib.h readline-4.3.orig/bind.c readline-4.3.orig/callback.c readline-4.3.orig/chardefs.h readline-4.3.orig/compat.c readline-4.3.orig/complete.c readline-4.3.orig/config.h.in readline-4.3.orig/configure readline-4.3.orig/configure.in readline-4.3.orig/display.c readline-4.3.orig/doc/Makefile.in readline-4.3.orig/doc/hist.texinfo readline-4.3.orig/doc/history.0 readline-4.3.orig/doc/history.3 readline-4.3.orig/doc/history.dvi readline-4.3.orig/doc/history.html readline-4.3.orig/doc/history.info readline-4.3.orig/doc/history.ps readline-4.3.orig/doc/history_3.ps readline-4.3.orig/doc/hstech.texinfo readline-4.3.orig/doc/hsuser.texinfo readline-4.3.orig/doc/manvers.texinfo readline-4.3.orig/doc/readline.0 readline-4.3.orig/doc/readline.3 readline-4.3.orig/doc/readline.dvi readline-4.3.orig/doc/readline.html readline-4.3.orig/doc/readline.info readline-4.3.orig/doc/readline.ps readline-4.3.orig/doc/readline_3.ps readline-4.3.orig/doc/rlman.texinfo readline-4.3.orig/doc/rltech.texinfo readline-4.3.orig/doc/rluser.texinfo readline-4.3.orig/doc/rluserman.dvi readline-4.3.orig/doc/rluserman.html readline-4.3.orig/doc/rluserman.info readline-4.3.orig/doc/rluserman.ps readline-4.3.orig/doc/rluserman.texinfo readline-4.3.orig/doc/texi2dvi readline-4.3.orig/doc/texi2html readline-4.3.orig/doc/texinfo.tex readline-4.3.orig/emacs_keymap.c readline-4.3.orig/examples/Inputrc readline-4.3.orig/examples/Makefile.in readline-4.3.orig/examples/excallback.c readline-4.3.orig/examples/fileman.c readline-4.3.orig/examples/histexamp.c readline-4.3.orig/examples/manexamp.c readline-4.3.orig/examples/readlinebuf.h readline-4.3.orig/examples/rl.c readline-4.3.orig/examples/rlcat.c readline-4.3.orig/examples/rlfe.c readline-4.3.orig/examples/rltest.c readline-4.3.orig/examples/rlversion.c readline-4.3.orig/funmap.c readline-4.3.orig/histexpand.c readline-4.3.orig/histfile.c readline-4.3.orig/histlib.h readline-4.3.orig/history.c readline-4.3.orig/history.h readline-4.3.orig/histsearch.c readline-4.3.orig/input.c readline-4.3.orig/isearch.c readline-4.3.orig/keymaps.c readline-4.3.orig/keymaps.h readline-4.3.orig/kill.c readline-4.3.orig/macro.c readline-4.3.orig/mbutil.c readline-4.3.orig/misc.c readline-4.3.orig/nls.c readline-4.3.orig/parens.c readline-4.3.orig/posixdir.h readline-4.3.orig/posixjmp.h readline-4.3.orig/posixstat.h readline-4.3.orig/readline.c readline-4.3.orig/readline.h readline-4.3.orig/rlconf.h readline-4.3.orig/rldefs.h readline-4.3.orig/rlmbutil.h readline-4.3.orig/rlprivate.h readline-4.3.orig/rlshell.h readline-4.3.orig/rlstdc.h readline-4.3.orig/rltty.c readline-4.3.orig/rltty.h readline-4.3.orig/rltypedefs.h readline-4.3.orig/rlwinsize.h readline-4.3.orig/savestring.c readline-4.3.orig/search.c readline-4.3.orig/shell.c readline-4.3.orig/shlib/Makefile.in readline-4.3.orig/signals.c readline-4.3.orig/support/config.guess readline-4.3.orig/support/config.sub readline-4.3.orig/support/install.sh readline-4.3.orig/support/mkdirs readline-4.3.orig/support/mkdist readline-4.3.orig/support/shlib-install readline-4.3.orig/support/shobj-conf readline-4.3.orig/support/wcwidth.c readline-4.3.orig/tcap.h readline-4.3.orig/terminal.c readline-4.3.orig/text.c readline-4.3.orig/tilde.c readline-4.3.orig/tilde.h readline-4.3.orig/undo.c readline-4.3.orig/util.c readline-4.3.orig/vi_keymap.c readline-4.3.orig/vi_mode.c readline-4.3.orig/xmalloc.c readline-4.3.orig/xmalloc.h readline-4.3/CHANGELOG-ReadLine readline-4.3/CHANGES readline-4.3/COPYING readline-4.3/INSTALL readline-4.3/MANIFEST readline-4.3/Makefile.in readline-4.3/README readline-4.3/USAGE readline-4.3/aclocal.m4 readline-4.3/ansi_stdlib.h readline-4.3/bind.c readline-4.3/callback.c readline-4.3/chardefs.h readline-4.3/compat.c readline-4.3/complete.c readline-4.3/config.h.in readline-4.3/configure readline-4.3/configure.in readline-4.3/display.c readline-4.3/doc/Makefile.in readline-4.3/doc/hist.texinfo readline-4.3/doc/history.3 readline-4.3/doc/hstech.texinfo readline-4.3/doc/hsuser.texinfo readline-4.3/doc/manvers.texinfo readline-4.3/doc/readline.3 readline-4.3/doc/rlman.texinfo readline-4.3/doc/rltech.texinfo readline-4.3/doc/rluser.texinfo readline-4.3/doc/rluserman.texinfo readline-4.3/doc/texi2dvi readline-4.3/doc/texi2html readline-4.3/doc/texinfo.tex readline-4.3/emacs_keymap.c readline-4.3/examples/Inputrc readline-4.3/examples/Makefile.in readline-4.3/examples/excallback.c readline-4.3/examples/fileman.c readline-4.3/examples/histexamp.c readline-4.3/examples/manexamp.c readline-4.3/examples/readlinebuf.h readline-4.3/examples/rl.c readline-4.3/examples/rlcat.c readline-4.3/examples/rlfe.c readline-4.3/examples/rltest.c readline-4.3/examples/rlversion.c readline-4.3/funmap.c readline-4.3/histexpand.c readline-4.3/histfile.c readline-4.3/histlib.h readline-4.3/history.c readline-4.3/history.h readline-4.3/histsearch.c readline-4.3/input.c readline-4.3/isearch.c readline-4.3/keymaps.c readline-4.3/keymaps.h readline-4.3/kill.c readline-4.3/macro.c readline-4.3/mbutil.c readline-4.3/misc.c readline-4.3/nls.c readline-4.3/parens.c readline-4.3/posixdir.h readline-4.3/posixjmp.h readline-4.3/posixstat.h readline-4.3/readline.c readline-4.3/readline.h readline-4.3/rlconf.h readline-4.3/rldefs.h readline-4.3/rlmbutil.h readline-4.3/rlprivate.h readline-4.3/rlshell.h readline-4.3/rlstdc.h readline-4.3/rltty.c readline-4.3/rltty.h readline-4.3/rltypedefs.h readline-4.3/rlwinsize.h readline-4.3/savestring.c readline-4.3/search.c readline-4.3/shell.c readline-4.3/shlib/Makefile.in readline-4.3/signals.c readline-4.3/support/config.guess readline-4.3/support/config.sub readline-4.3/support/install.sh readline-4.3/support/mkdirs readline-4.3/support/mkdist readline-4.3/support/shlib-install readline-4.3/support/shobj-conf readline-4.3/support/wcwidth.c readline-4.3/tcap.h readline-4.3/terminal.c readline-4.3/text.c readline-4.3/tilde.c readline-4.3/tilde.h readline-4.3/undo.c readline-4.3/util.c readline-4.3/vi_keymap.c readline-4.3/vi_mode.c readline-4.3/xmalloc.c readline-4.3/xmalloc.h readline-doc-4.3/MANIFEST.doc readline-doc-4.3/doc/history.0 readline-doc-4.3/doc/history.dvi readline-doc-4.3/doc/history.html readline-doc-4.3/doc/history.info readline-doc-4.3/doc/history.ps readline-doc-4.3/doc/history_3.ps readline-doc-4.3/doc/readline.0 readline-doc-4.3/doc/readline.dvi readline-doc-4.3/doc/readline.html readline-doc-4.3/doc/readline.info readline-doc-4.3/doc/readline.ps readline-doc-4.3/doc/readline_3.ps readline-doc-4.3/doc/rluserman.dvi readline-doc-4.3/doc/rluserman.html readline-doc-4.3/doc/rluserman.info readline-doc-4.3/doc/rluserman.ps rtemsNfs/ChangeLog rtemsNfs/LICENSE rtemsNfs/Makefile rtemsNfs/README rtemsNfs/proto/Makefile rtemsNfs/proto/mount_prot.h rtemsNfs/proto/mount_prot.x rtemsNfs/proto/mount_prot_xdr.c rtemsNfs/proto/nfs_prot.h rtemsNfs/proto/nfs_prot.x rtemsNfs/proto/nfs_prot_xdr.c rtemsNfs/rtems-filesystem-patch rtemsNfs/src/Makefile rtemsNfs/src/cexphelp.c rtemsNfs/src/dirutils.c rtemsNfs/src/librtemsNfs.h rtemsNfs/src/nfs.c rtemsNfs/src/nfs.modini.c rtemsNfs/src/rpcio.c rtemsNfs/src/rpcio.h rtemsNfs/src/rpcio.modini.c rtemsNfs/src/sock_mbuf.c rtemsNfs/src/xdr_mbuf.c zlib-1.1.4/ChangeLog zlib-1.1.4/FAQ zlib-1.1.4/INDEX zlib-1.1.4/Make_vms.com zlib-1.1.4/Makefile zlib-1.1.4/Makefile.in zlib-1.1.4/Makefile.riscos zlib-1.1.4/README zlib-1.1.4/adler32.c zlib-1.1.4/algorithm.txt zlib-1.1.4/amiga/Makefile.pup zlib-1.1.4/amiga/Makefile.sas zlib-1.1.4/compress.c zlib-1.1.4/configure zlib-1.1.4/contrib/README.contrib zlib-1.1.4/contrib/asm386/gvmat32.asm zlib-1.1.4/contrib/asm386/gvmat32c.c zlib-1.1.4/contrib/asm386/mkgvmt32.bat zlib-1.1.4/contrib/asm386/zlibvc.def zlib-1.1.4/contrib/asm386/zlibvc.dsp zlib-1.1.4/contrib/asm386/zlibvc.dsw zlib-1.1.4/contrib/asm586/README.586 zlib-1.1.4/contrib/asm586/match.S zlib-1.1.4/contrib/asm686/README.686 zlib-1.1.4/contrib/asm686/match.S zlib-1.1.4/contrib/delphi/zlib.mak zlib-1.1.4/contrib/delphi/zlibdef.pas zlib-1.1.4/contrib/delphi2/d_zlib.bpr zlib-1.1.4/contrib/delphi2/d_zlib.cpp zlib-1.1.4/contrib/delphi2/readme.txt zlib-1.1.4/contrib/delphi2/zlib.bpg zlib-1.1.4/contrib/delphi2/zlib.bpr zlib-1.1.4/contrib/delphi2/zlib.cpp zlib-1.1.4/contrib/delphi2/zlib.pas zlib-1.1.4/contrib/delphi2/zlib32.bpr zlib-1.1.4/contrib/delphi2/zlib32.cpp zlib-1.1.4/contrib/iostream/test.cpp zlib-1.1.4/contrib/iostream/zfstream.cpp zlib-1.1.4/contrib/iostream/zfstream.h zlib-1.1.4/contrib/iostream2/zstream.h zlib-1.1.4/contrib/iostream2/zstream_test.cpp zlib-1.1.4/contrib/minizip/ChangeLogUnzip zlib-1.1.4/contrib/minizip/Makefile zlib-1.1.4/contrib/minizip/miniunz.c zlib-1.1.4/contrib/minizip/minizip.c zlib-1.1.4/contrib/minizip/readme.txt zlib-1.1.4/contrib/minizip/unzip.c zlib-1.1.4/contrib/minizip/unzip.def zlib-1.1.4/contrib/minizip/unzip.h zlib-1.1.4/contrib/minizip/zip.c zlib-1.1.4/contrib/minizip/zip.def zlib-1.1.4/contrib/minizip/zip.h zlib-1.1.4/contrib/minizip/zlibvc.def zlib-1.1.4/contrib/minizip/zlibvc.dsp zlib-1.1.4/contrib/minizip/zlibvc.dsw zlib-1.1.4/contrib/untgz/Makefile zlib-1.1.4/contrib/untgz/makefile.w32 zlib-1.1.4/contrib/untgz/untgz.c zlib-1.1.4/contrib/visual-basic.txt zlib-1.1.4/crc32.c zlib-1.1.4/deflate.c zlib-1.1.4/deflate.h zlib-1.1.4/descrip.mms zlib-1.1.4/example.c zlib-1.1.4/gzio.c zlib-1.1.4/infblock.c zlib-1.1.4/infblock.h zlib-1.1.4/infcodes.c zlib-1.1.4/infcodes.h zlib-1.1.4/inffast.c zlib-1.1.4/inffast.h zlib-1.1.4/inffixed.h zlib-1.1.4/inflate.c zlib-1.1.4/inftrees.c zlib-1.1.4/inftrees.h zlib-1.1.4/infutil.c zlib-1.1.4/infutil.h zlib-1.1.4/maketree.c zlib-1.1.4/minigzip.c zlib-1.1.4/msdos/Makefile.b32 zlib-1.1.4/msdos/Makefile.bor zlib-1.1.4/msdos/Makefile.dj2 zlib-1.1.4/msdos/Makefile.emx zlib-1.1.4/msdos/Makefile.msc zlib-1.1.4/msdos/Makefile.tc zlib-1.1.4/msdos/Makefile.w32 zlib-1.1.4/msdos/Makefile.wat zlib-1.1.4/msdos/zlib.def zlib-1.1.4/msdos/zlib.rc zlib-1.1.4/nt/Makefile.emx zlib-1.1.4/nt/Makefile.gcc zlib-1.1.4/nt/Makefile.nt zlib-1.1.4/nt/zlib.dnt zlib-1.1.4/os2/Makefile.os2 zlib-1.1.4/os2/zlib.def zlib-1.1.4/trees.c zlib-1.1.4/trees.h zlib-1.1.4/uncompr.c zlib-1.1.4/zconf.h zlib-1.1.4/zlib.3 zlib-1.1.4/zlib.h zlib-1.1.4/zlib.html zlib-1.1.4/zutil.c zlib-1.1.4/zutil.h --- ChangeLog | 97 + README | 24 + RTEMS_Makefiles/Makefile.avl | 12 + RTEMS_Makefiles/Makefile.bfd | 14 + RTEMS_Makefiles/Makefile.common | 23 + RTEMS_Makefiles/Makefile.libtecla | 15 + RTEMS_Makefiles/Makefile.ncurses | 28 + RTEMS_Makefiles/Makefile.ncurses-5.3 | 30 + RTEMS_Makefiles/Makefile.readline-4.3 | 18 + RTEMS_Makefiles/Makefile.site | 3 + RTEMS_Makefiles/Makefile.zlib | 13 + SUPPORT | 22 + VERSION | 7 + avl-1.4.0/AUTHORS | 1 + avl-1.4.0/COPYING | 340 + avl-1.4.0/ChangeLog | 181 + avl-1.4.0/INSTALL | 182 + avl-1.4.0/Makefile.am | 28 + avl-1.4.0/Makefile.in | 572 + avl-1.4.0/NEWS | 98 + avl-1.4.0/README | 37 + avl-1.4.0/THANKS | 15 + avl-1.4.0/TODO | 92 + avl-1.4.0/aclocal.m4 | 104 + avl-1.4.0/avl.c | 1154 ++ avl-1.4.0/avl.h | 148 + avl-1.4.0/avl.html | 1046 ++ avl-1.4.0/avl.info | 708 + avl-1.4.0/avl.texinfo | 679 + avl-1.4.0/avl.text | 636 + avl-1.4.0/avlt.c | 1597 ++ avl-1.4.0/avlt.h | 142 + avl-1.4.0/avltr.c | 1538 ++ avl-1.4.0/avltr.h | 142 + avl-1.4.0/configure | 1297 ++ avl-1.4.0/configure.in | 5 + avl-1.4.0/install-sh | 251 + avl-1.4.0/missing | 190 + avl-1.4.0/mkinstalldirs | 40 + avl-1.4.0/rb.c | 1083 ++ avl-1.4.0/rb.h | 155 + avl-1.4.0/texinfo.tex | 5484 ++++++ avl-1.4.0/thread-test.c | 142 + bit | 36 + bit_bfd | 18 + examples/avl/BuildTests.sh | 13 + examples/avl/Makefile | 70 + examples/avl/README | 4 + examples/avl/init.c | 51 + examples/ncurses/BuildTests.sh | 36 + examples/ncurses/Makefile | 70 + examples/ncurses/README | 4 + examples/ncurses/init.c | 52 + examples/readline/.gdbinit | 1 + examples/readline/Makefile | 70 + examples/readline/init.c | 51 + examples/readline/rlgeneric.c | 30 + libtecla-1.4.1/CHANGES | 1492 ++ libtecla-1.4.1/INSTALL | 168 + libtecla-1.4.1/LICENSE.TERMS | 28 + libtecla-1.4.1/Makefile | 3 + libtecla-1.4.1/Makefile.in | 225 + libtecla-1.4.1/Makefile.rules | 142 + libtecla-1.4.1/Makefile.stub | 3 + libtecla-1.4.1/PORTING | 38 + libtecla-1.4.1/README | 53 + libtecla-1.4.1/RELEASE.NOTES | 357 + libtecla-1.4.1/config.guess | 1183 ++ libtecla-1.4.1/config.sub | 1268 ++ libtecla-1.4.1/configure | 1939 ++ libtecla-1.4.1/configure.in | 412 + libtecla-1.4.1/cplfile.c | 874 + libtecla-1.4.1/cplfile.h | 96 + libtecla-1.4.1/cplmatch.c | 927 + libtecla-1.4.1/demo.c | 109 + libtecla-1.4.1/demo2.c | 352 + libtecla-1.4.1/direader.c | 299 + libtecla-1.4.1/direader.h | 44 + libtecla-1.4.1/enhance.c | 689 + libtecla-1.4.1/expand.c | 1265 ++ libtecla-1.4.1/freelist.c | 393 + libtecla-1.4.1/freelist.h | 82 + libtecla-1.4.1/getline.c | 8346 +++++++++ libtecla-1.4.1/getline.h | 88 + libtecla-1.4.1/hash.c | 748 + libtecla-1.4.1/hash.h | 157 + libtecla-1.4.1/history.c | 2003 ++ libtecla-1.4.1/history.h | 159 + libtecla-1.4.1/homedir.c | 399 + libtecla-1.4.1/homedir.h | 81 + libtecla-1.4.1/html/changes.html | 1495 ++ libtecla-1.4.1/html/cpl_complete_word.html | 423 + libtecla-1.4.1/html/ef_expand_file.html | 267 + libtecla-1.4.1/html/enhance.html | 111 + libtecla-1.4.1/html/gl_get_line.html | 2295 +++ libtecla-1.4.1/html/index.html | 116 + libtecla-1.4.1/html/libtecla.html | 163 + libtecla-1.4.1/html/pca_lookup_file.html | 371 + libtecla-1.4.1/html/release.html | 360 + libtecla-1.4.1/install-sh | 251 + libtecla-1.4.1/keytab.c | 827 + libtecla-1.4.1/keytab.h | 146 + libtecla-1.4.1/libtecla.h | 1194 ++ libtecla-1.4.1/libtecla.map | 124 + libtecla-1.4.1/man3/cfc_file_start.3 | 1 + libtecla-1.4.1/man3/cfc_literal_escapes.3 | 1 + libtecla-1.4.1/man3/cfc_set_check_fn.3 | 1 + libtecla-1.4.1/man3/cpl_add_completion.3 | 1 + libtecla-1.4.1/man3/cpl_complete_word.3 | 405 + libtecla-1.4.1/man3/cpl_file_completions.3 | 1 + libtecla-1.4.1/man3/cpl_last_error.3 | 1 + libtecla-1.4.1/man3/cpl_list_completions.3 | 1 + libtecla-1.4.1/man3/cpl_record_error.3 | 1 + libtecla-1.4.1/man3/del_CplFileConf.3 | 1 + libtecla-1.4.1/man3/del_ExpandFile.3 | 1 + libtecla-1.4.1/man3/del_GetLine.3 | 1 + libtecla-1.4.1/man3/del_PathCache.3 | 1 + libtecla-1.4.1/man3/del_PcaPathConf.3 | 1 + libtecla-1.4.1/man3/del_WordCompletion.3 | 1 + libtecla-1.4.1/man3/ef_expand_file.3 | 245 + libtecla-1.4.1/man3/ef_last_error.3 | 1 + libtecla-1.4.1/man3/ef_list_expansions.3 | 1 + libtecla-1.4.1/man3/enhance.3 | 86 + libtecla-1.4.1/man3/gl_change_terminal.3 | 1 + libtecla-1.4.1/man3/gl_clear_history.3 | 1 + libtecla-1.4.1/man3/gl_configure_getline.3 | 1 + libtecla-1.4.1/man3/gl_customize_completion.3 | 1 + libtecla-1.4.1/man3/gl_echo_mode.3 | 1 + libtecla-1.4.1/man3/gl_get_line.3 | 2329 +++ libtecla-1.4.1/man3/gl_group_history.3 | 1 + libtecla-1.4.1/man3/gl_ignore_signal.3 | 1 + libtecla-1.4.1/man3/gl_last_signal.3 | 1 + libtecla-1.4.1/man3/gl_limit_history.3 | 1 + libtecla-1.4.1/man3/gl_load_history.3 | 1 + libtecla-1.4.1/man3/gl_lookup_history.3 | 1 + libtecla-1.4.1/man3/gl_prompt_style.3 | 1 + libtecla-1.4.1/man3/gl_range_of_history.3 | 1 + libtecla-1.4.1/man3/gl_resize_history.3 | 1 + libtecla-1.4.1/man3/gl_save_history.3 | 1 + libtecla-1.4.1/man3/gl_show_history.3 | 1 + libtecla-1.4.1/man3/gl_size_of_history.3 | 1 + libtecla-1.4.1/man3/gl_state_of_history.3 | 1 + libtecla-1.4.1/man3/gl_terminal_size.3 | 1 + libtecla-1.4.1/man3/gl_toggle_history.3 | 1 + libtecla-1.4.1/man3/gl_trap_signal.3 | 1 + libtecla-1.4.1/man3/gl_watch_fd.3 | 1 + libtecla-1.4.1/man3/libtecla.3 | 160 + libtecla-1.4.1/man3/libtecla_version.3 | 1 + libtecla-1.4.1/man3/new_CplFileConf.3 | 1 + libtecla-1.4.1/man3/new_ExpandFile.3 | 1 + libtecla-1.4.1/man3/new_GetLine.3 | 1 + libtecla-1.4.1/man3/new_PathCache.3 | 1 + libtecla-1.4.1/man3/new_PcaPathConf.3 | 1 + libtecla-1.4.1/man3/new_WordCompletion.3 | 1 + libtecla-1.4.1/man3/pca_last_error.3 | 1 + libtecla-1.4.1/man3/pca_lookup_file.3 | 361 + libtecla-1.4.1/man3/pca_path_completions.3 | 1 + libtecla-1.4.1/man3/pca_scan_path.3 | 1 + libtecla-1.4.1/man3/pca_set_check_fn.3 | 1 + libtecla-1.4.1/man3/ppc_file_start.3 | 1 + libtecla-1.4.1/man3/ppc_literal_escapes.3 | 1 + libtecla-1.4.1/pathutil.c | 532 + libtecla-1.4.1/pathutil.h | 122 + libtecla-1.4.1/pcache.c | 1688 ++ libtecla-1.4.1/stringrp.c | 285 + libtecla-1.4.1/stringrp.h | 84 + libtecla-1.4.1/strngmem.c | 226 + libtecla-1.4.1/strngmem.h | 80 + libtecla-1.4.1/update_html | 35 + libtecla-1.4.1/update_version | 82 + libtecla-1.4.1/version.c | 30 + ncurses-5.2/ANNOUNCE | 486 + ncurses-5.2/Ada95/Makefile.in | 67 + ncurses-5.2/Ada95/README | 33 + ncurses-5.2/Ada95/TODO | 27 + ncurses-5.2/Ada95/gen/Makefile.in | 429 + ncurses-5.2/Ada95/gen/gen.c | 1381 ++ ncurses-5.2/Ada95/gen/html.m4 | 11 + ncurses-5.2/Ada95/gen/normal.m4 | 8 + ncurses-5.2/Ada95/gen/table.m4 | 6 + .../Ada95/gen/terminal_interface-curses-aux.ads.m4 | 104 + ...minal_interface-curses-forms-field_types.ads.m4 | 238 + ...l_interface-curses-forms-field_user_data.ads.m4 | 70 + ...al_interface-curses-forms-form_user_data.ads.m4 | 70 + .../gen/terminal_interface-curses-forms.ads.m4 | 696 + ...al_interface-curses-menus-item_user_data.ads.m4 | 75 + ...al_interface-curses-menus-menu_user_data.ads.m4 | 70 + .../gen/terminal_interface-curses-menus.ads.m4 | 594 + .../gen/terminal_interface-curses-mouse.ads.m4 | 173 + ...rminal_interface-curses-panels-user_data.ads.m4 | 70 + .../gen/terminal_interface-curses-panels.ads.m4 | 146 + .../Ada95/gen/terminal_interface-curses.ads.m4 | 1388 ++ ncurses-5.2/Ada95/samples/Makefile.in | 137 + ncurses-5.2/Ada95/samples/README | 6 + ncurses-5.2/Ada95/samples/explain.txt | 186 + ncurses-5.2/Ada95/samples/rain.adb | 161 + ncurses-5.2/Ada95/samples/rain.ads | 42 + .../samples/sample-curses_demo-attributes.adb | 122 + .../samples/sample-curses_demo-attributes.ads | 45 + .../Ada95/samples/sample-curses_demo-mouse.adb | 220 + .../Ada95/samples/sample-curses_demo-mouse.ads | 45 + ncurses-5.2/Ada95/samples/sample-curses_demo.adb | 142 + ncurses-5.2/Ada95/samples/sample-curses_demo.ads | 45 + ncurses-5.2/Ada95/samples/sample-explanation.adb | 408 + ncurses-5.2/Ada95/samples/sample-explanation.ads | 59 + ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb | 259 + ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads | 92 + .../Ada95/samples/sample-form_demo-handler.adb | 97 + .../Ada95/samples/sample-form_demo-handler.ads | 64 + ncurses-5.2/Ada95/samples/sample-form_demo.adb | 134 + ncurses-5.2/Ada95/samples/sample-form_demo.ads | 45 + .../Ada95/samples/sample-function_key_setting.adb | 213 + .../Ada95/samples/sample-function_key_setting.ads | 82 + .../Ada95/samples/sample-header_handler.adb | 180 + .../Ada95/samples/sample-header_handler.ads | 53 + ncurses-5.2/Ada95/samples/sample-helpers.adb | 69 + ncurses-5.2/Ada95/samples/sample-helpers.ads | 54 + .../Ada95/samples/sample-keyboard_handler.adb | 191 + .../Ada95/samples/sample-keyboard_handler.ads | 55 + ncurses-5.2/Ada95/samples/sample-manifest.ads | 67 + ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb | 204 + ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads | 71 + .../Ada95/samples/sample-menu_demo-handler.adb | 107 + .../Ada95/samples/sample-menu_demo-handler.ads | 64 + ncurses-5.2/Ada95/samples/sample-menu_demo.adb | 390 + ncurses-5.2/Ada95/samples/sample-menu_demo.ads | 45 + ncurses-5.2/Ada95/samples/sample-my_field_type.adb | 65 + ncurses-5.2/Ada95/samples/sample-my_field_type.ads | 62 + ncurses-5.2/Ada95/samples/sample-text_io_demo.adb | 180 + ncurses-5.2/Ada95/samples/sample-text_io_demo.ads | 45 + ncurses-5.2/Ada95/samples/sample.adb | 218 + ncurses-5.2/Ada95/samples/sample.ads | 43 + ncurses-5.2/Ada95/samples/status.adb | 56 + ncurses-5.2/Ada95/samples/status.ads | 59 + ncurses-5.2/Ada95/samples/tour.adb | 46 + ncurses-5.2/Ada95/samples/tour.ads | 41 + ncurses-5.2/Ada95/src/Makefile.in | 352 + .../Ada95/src/terminal_interface-curses-aux.adb | 116 + ...al_interface-curses-forms-field_types-alpha.adb | 68 + ...al_interface-curses-forms-field_types-alpha.ads | 53 + ...rface-curses-forms-field_types-alphanumeric.adb | 68 + ...rface-curses-forms-field_types-alphanumeric.ads | 54 + ...ce-curses-forms-field_types-enumeration-ada.adb | 80 + ...ce-curses-forms-field_types-enumeration-ada.ads | 59 + ...erface-curses-forms-field_types-enumeration.adb | 119 + ...erface-curses-forms-field_types-enumeration.ads | 98 + ...interface-curses-forms-field_types-intfield.adb | 72 + ...interface-curses-forms-field_types-intfield.ads | 55 + ...rface-curses-forms-field_types-ipv4_address.adb | 68 + ...rface-curses-forms-field_types-ipv4_address.ads | 51 + ..._interface-curses-forms-field_types-numeric.adb | 74 + ..._interface-curses-forms-field_types-numeric.ads | 55 + ...l_interface-curses-forms-field_types-regexp.adb | 71 + ...l_interface-curses-forms-field_types-regexp.ads | 55 + ...erface-curses-forms-field_types-user-choice.adb | 110 + ...erface-curses-forms-field_types-user-choice.ads | 96 + ...nal_interface-curses-forms-field_types-user.adb | 132 + ...nal_interface-curses-forms-field_types-user.ads | 97 + ...terminal_interface-curses-forms-field_types.adb | 296 + ...inal_interface-curses-forms-field_user_data.adb | 85 + ...minal_interface-curses-forms-form_user_data.adb | 86 + .../Ada95/src/terminal_interface-curses-forms.adb | 1160 ++ ...minal_interface-curses-menus-item_user_data.adb | 77 + ...minal_interface-curses-menus-menu_user_data.adb | 76 + .../Ada95/src/terminal_interface-curses-menus.adb | 1021 + .../Ada95/src/terminal_interface-curses-mouse.adb | 214 + .../terminal_interface-curses-panels-user_data.adb | 78 + .../Ada95/src/terminal_interface-curses-panels.adb | 164 + .../src/terminal_interface-curses-text_io-aux.adb | 128 + .../src/terminal_interface-curses-text_io-aux.ads | 55 + ...erminal_interface-curses-text_io-complex_io.adb | 73 + ...erminal_interface-curses-text_io-complex_io.ads | 70 + ...erminal_interface-curses-text_io-decimal_io.adb | 75 + ...erminal_interface-curses-text_io-decimal_io.ads | 66 + ...nal_interface-curses-text_io-enumeration_io.adb | 80 + ...nal_interface-curses-text_io-enumeration_io.ads | 63 + .../terminal_interface-curses-text_io-fixed_io.adb | 75 + .../terminal_interface-curses-text_io-fixed_io.ads | 66 + .../terminal_interface-curses-text_io-float_io.adb | 76 + .../terminal_interface-curses-text_io-float_io.ads | 66 + ...erminal_interface-curses-text_io-integer_io.adb | 70 + ...erminal_interface-curses-text_io-integer_io.ads | 63 + ...erminal_interface-curses-text_io-modular_io.adb | 70 + ...erminal_interface-curses-text_io-modular_io.ads | 63 + .../src/terminal_interface-curses-text_io.adb | 336 + .../src/terminal_interface-curses-text_io.ads | 136 + .../Ada95/src/terminal_interface-curses.adb | 2414 +++ ncurses-5.2/Ada95/src/terminal_interface.ads | 48 + ncurses-5.2/INSTALL | 1059 ++ ncurses-5.2/MANIFEST | 866 + ncurses-5.2/Makefile.glibc | 403 + ncurses-5.2/Makefile.in | 92 + ncurses-5.2/Makefile.os2 | 234 + ncurses-5.2/NEWS | 4584 +++++ ncurses-5.2/README | 175 + ncurses-5.2/README.emx | 45 + ncurses-5.2/README.glibc | 5 + ncurses-5.2/TO-DO | 251 + ncurses-5.2/aclocal.m4 | 2573 +++ ncurses-5.2/announce.html.in | 593 + ncurses-5.2/c++/Makefile.in | 213 + ncurses-5.2/c++/NEWS | 42 + ncurses-5.2/c++/PROBLEMS | 5 + ncurses-5.2/c++/README-first | 58 + ncurses-5.2/c++/cursesapp.cc | 146 + ncurses-5.2/c++/cursesapp.h | 163 + ncurses-5.2/c++/cursesf.cc | 426 + ncurses-5.2/c++/cursesf.h | 824 + ncurses-5.2/c++/cursesm.cc | 383 + ncurses-5.2/c++/cursesm.h | 592 + ncurses-5.2/c++/cursesmain.cc | 51 + ncurses-5.2/c++/cursesp.cc | 124 + ncurses-5.2/c++/cursesp.h | 218 + ncurses-5.2/c++/cursespad.cc | 270 + ncurses-5.2/c++/cursesw.cc | 434 + ncurses-5.2/c++/cursesw.h | 1375 ++ ncurses-5.2/c++/cursslk.cc | 122 + ncurses-5.2/c++/cursslk.h | 205 + ncurses-5.2/c++/demo.cc | 449 + ncurses-5.2/c++/edit_cfg.sh | 67 + ncurses-5.2/c++/etip.h.in | 273 + ncurses-5.2/c++/headers | 39 + ncurses-5.2/c++/internal.h | 47 + ncurses-5.2/c++/modules | 43 + ncurses-5.2/config.guess | 1276 ++ ncurses-5.2/config.sub | 1328 ++ ncurses-5.2/configure | 8083 ++++++++ ncurses-5.2/configure.in | 1171 ++ ncurses-5.2/convert_configure.pl | 90 + ncurses-5.2/dist.mk | 118 + ncurses-5.2/doc/hackguide.doc | 687 + ncurses-5.2/doc/html/Ada95.html | 172 + ncurses-5.2/doc/html/ada/files.htm | 5 + ncurses-5.2/doc/html/ada/files/T.htm | 69 + ncurses-5.2/doc/html/ada/funcs.htm | 27 + ncurses-5.2/doc/html/ada/funcs/A.htm | 18 + ncurses-5.2/doc/html/ada/funcs/B.htm | 10 + ncurses-5.2/doc/html/ada/funcs/C.htm | 33 + ncurses-5.2/doc/html/ada/funcs/D.htm | 22 + ncurses-5.2/doc/html/ada/funcs/E.htm | 11 + ncurses-5.2/doc/html/ada/funcs/F.htm | 46 + ncurses-5.2/doc/html/ada/funcs/G.htm | 21 + ncurses-5.2/doc/html/ada/funcs/H.htm | 12 + ncurses-5.2/doc/html/ada/funcs/I.htm | 31 + ncurses-5.2/doc/html/ada/funcs/K.htm | 10 + ncurses-5.2/doc/html/ada/funcs/L.htm | 14 + ncurses-5.2/doc/html/ada/funcs/M.htm | 44 + ncurses-5.2/doc/html/ada/funcs/N.htm | 28 + ncurses-5.2/doc/html/ada/funcs/O.htm | 9 + ncurses-5.2/doc/html/ada/funcs/P.htm | 39 + ncurses-5.2/doc/html/ada/funcs/Q.htm | 7 + ncurses-5.2/doc/html/ada/funcs/R.htm | 20 + ncurses-5.2/doc/html/ada/funcs/S.htm | 93 + ncurses-5.2/doc/html/ada/funcs/T.htm | 19 + ncurses-5.2/doc/html/ada/funcs/U.htm | 11 + ncurses-5.2/doc/html/ada/funcs/V.htm | 7 + ncurses-5.2/doc/html/ada/funcs/W.htm | 51 + ncurses-5.2/doc/html/ada/index.htm | 41 + ncurses-5.2/doc/html/ada/main.htm | 66 + ncurses-5.2/doc/html/ada/table.html | 325 + .../ada/terminal_interface-curses-aux__adb.htm | 121 + .../ada/terminal_interface-curses-aux__ads.htm | 130 + ...terface-curses-forms-field_types-alpha__adb.htm | 73 + ...terface-curses-forms-field_types-alpha__ads.htm | 58 + ...-curses-forms-field_types-alphanumeric__adb.htm | 73 + ...-curses-forms-field_types-alphanumeric__ads.htm | 59 + ...rses-forms-field_types-enumeration-ada__adb.htm | 85 + ...rses-forms-field_types-enumeration-ada__ads.htm | 64 + ...e-curses-forms-field_types-enumeration__adb.htm | 124 + ...e-curses-forms-field_types-enumeration__ads.htm | 103 + ...face-curses-forms-field_types-intfield__adb.htm | 77 + ...face-curses-forms-field_types-intfield__ads.htm | 60 + ...-curses-forms-field_types-ipv4_address__adb.htm | 73 + ...-curses-forms-field_types-ipv4_address__ads.htm | 56 + ...rface-curses-forms-field_types-numeric__adb.htm | 79 + ...rface-curses-forms-field_types-numeric__ads.htm | 60 + ...erface-curses-forms-field_types-regexp__adb.htm | 76 + ...erface-curses-forms-field_types-regexp__ads.htm | 60 + ...e-curses-forms-field_types-user-choice__adb.htm | 115 + ...e-curses-forms-field_types-user-choice__ads.htm | 101 + ...nterface-curses-forms-field_types-user__adb.htm | 137 + ...nterface-curses-forms-field_types-user__ads.htm | 102 + ...nal_interface-curses-forms-field_types__adb.htm | 301 + ...nal_interface-curses-forms-field_types__ads.htm | 245 + ...interface-curses-forms-field_user_data__adb.htm | 90 + ...interface-curses-forms-field_user_data__ads.htm | 75 + ..._interface-curses-forms-form_user_data__adb.htm | 91 + ..._interface-curses-forms-form_user_data__ads.htm | 75 + .../ada/terminal_interface-curses-forms__adb.htm | 1165 ++ .../ada/terminal_interface-curses-forms__ads.htm | 783 + ..._interface-curses-menus-item_user_data__adb.htm | 82 + ..._interface-curses-menus-item_user_data__ads.htm | 80 + ..._interface-curses-menus-menu_user_data__adb.htm | 81 + ..._interface-curses-menus-menu_user_data__ads.htm | 75 + .../ada/terminal_interface-curses-menus__adb.htm | 1026 + .../ada/terminal_interface-curses-menus__ads.htm | 673 + .../ada/terminal_interface-curses-mouse__adb.htm | 219 + .../ada/terminal_interface-curses-mouse__ads.htm | 225 + ...inal_interface-curses-panels-user_data__adb.htm | 83 + ...inal_interface-curses-panels-user_data__ads.htm | 75 + .../ada/terminal_interface-curses-panels__adb.htm | 169 + .../ada/terminal_interface-curses-panels__ads.htm | 152 + .../terminal_interface-curses-text_io-aux__adb.htm | 133 + .../terminal_interface-curses-text_io-aux__ads.htm | 60 + ...al_interface-curses-text_io-complex_io__adb.htm | 78 + ...al_interface-curses-text_io-complex_io__ads.htm | 75 + ...al_interface-curses-text_io-decimal_io__adb.htm | 80 + ...al_interface-curses-text_io-decimal_io__ads.htm | 71 + ...nterface-curses-text_io-enumeration_io__adb.htm | 85 + ...nterface-curses-text_io-enumeration_io__ads.htm | 68 + ...inal_interface-curses-text_io-fixed_io__adb.htm | 80 + ...inal_interface-curses-text_io-fixed_io__ads.htm | 71 + ...inal_interface-curses-text_io-float_io__adb.htm | 81 + ...inal_interface-curses-text_io-float_io__ads.htm | 71 + ...al_interface-curses-text_io-integer_io__adb.htm | 75 + ...al_interface-curses-text_io-integer_io__ads.htm | 68 + ...al_interface-curses-text_io-modular_io__adb.htm | 75 + ...al_interface-curses-text_io-modular_io__ads.htm | 68 + .../ada/terminal_interface-curses-text_io__adb.htm | 341 + .../ada/terminal_interface-curses-text_io__ads.htm | 141 + .../html/ada/terminal_interface-curses__adb.htm | 2419 +++ .../html/ada/terminal_interface-curses__ads.htm | 1744 ++ .../doc/html/ada/terminal_interface__ads.htm | 53 + ncurses-5.2/doc/html/announce.html | 593 + ncurses-5.2/doc/html/hackguide.html | 890 + ncurses-5.2/doc/html/index.html | 30 + ncurses-5.2/doc/html/man/captoinfo.1m.html | 190 + ncurses-5.2/doc/html/man/clear.1.html | 74 + ncurses-5.2/doc/html/man/curs_addch.3x.html | 189 + ncurses-5.2/doc/html/man/curs_addchstr.3x.html | 80 + ncurses-5.2/doc/html/man/curs_addstr.3x.html | 80 + ncurses-5.2/doc/html/man/curs_attr.3x.html | 186 + ncurses-5.2/doc/html/man/curs_beep.3x.html | 80 + ncurses-5.2/doc/html/man/curs_bkgd.3x.html | 134 + ncurses-5.2/doc/html/man/curs_border.3x.html | 135 + ncurses-5.2/doc/html/man/curs_clear.3x.html | 134 + ncurses-5.2/doc/html/man/curs_color.3x.html | 242 + ncurses-5.2/doc/html/man/curs_delch.3x.html | 80 + ncurses-5.2/doc/html/man/curs_deleteln.3x.html | 80 + ncurses-5.2/doc/html/man/curs_extend.3x.html | 78 + ncurses-5.2/doc/html/man/curs_getch.3x.html | 296 + ncurses-5.2/doc/html/man/curs_getstr.3x.html | 134 + ncurses-5.2/doc/html/man/curs_getyx.3x.html | 80 + ncurses-5.2/doc/html/man/curs_inch.3x.html | 78 + ncurses-5.2/doc/html/man/curs_inchstr.3x.html | 80 + ncurses-5.2/doc/html/man/curs_initscr.3x.html | 134 + ncurses-5.2/doc/html/man/curs_inopts.3x.html | 242 + ncurses-5.2/doc/html/man/curs_insch.3x.html | 80 + ncurses-5.2/doc/html/man/curs_insstr.3x.html | 135 + ncurses-5.2/doc/html/man/curs_instr.3x.html | 80 + ncurses-5.2/doc/html/man/curs_kernel.3x.html | 188 + ncurses-5.2/doc/html/man/curs_mouse.3x.html | 242 + ncurses-5.2/doc/html/man/curs_move.3x.html | 80 + ncurses-5.2/doc/html/man/curs_outopts.3x.html | 188 + ncurses-5.2/doc/html/man/curs_overlay.3x.html | 80 + ncurses-5.2/doc/html/man/curs_pad.3x.html | 134 + ncurses-5.2/doc/html/man/curs_print.3x.html | 80 + ncurses-5.2/doc/html/man/curs_printw.3x.html | 78 + ncurses-5.2/doc/html/man/curs_refresh.3x.html | 134 + ncurses-5.2/doc/html/man/curs_scanw.3x.html | 78 + ncurses-5.2/doc/html/man/curs_scr_dump.3x.html | 134 + ncurses-5.2/doc/html/man/curs_scroll.3x.html | 80 + ncurses-5.2/doc/html/man/curs_slk.3x.html | 188 + ncurses-5.2/doc/html/man/curs_termattrs.3x.html | 134 + ncurses-5.2/doc/html/man/curs_termcap.3x.html | 134 + ncurses-5.2/doc/html/man/curs_terminfo.3x.html | 296 + ncurses-5.2/doc/html/man/curs_touch.3x.html | 135 + ncurses-5.2/doc/html/man/curs_trace.3x.html | 132 + ncurses-5.2/doc/html/man/curs_util.3x.html | 134 + ncurses-5.2/doc/html/man/curs_window.3x.html | 190 + ncurses-5.2/doc/html/man/default_colors.3x.html | 136 + ncurses-5.2/doc/html/man/define_key.3x.html | 80 + ncurses-5.2/doc/html/man/form.3x.html | 245 + ncurses-5.2/doc/html/man/form_cursor.3x.html | 82 + ncurses-5.2/doc/html/man/form_data.3x.html | 80 + ncurses-5.2/doc/html/man/form_driver.3x.html | 299 + ncurses-5.2/doc/html/man/form_field.3x.html | 136 + .../doc/html/man/form_field_attributes.3x.html | 136 + ncurses-5.2/doc/html/man/form_field_buffer.3x.html | 137 + ncurses-5.2/doc/html/man/form_field_info.3x.html | 82 + ncurses-5.2/doc/html/man/form_field_just.3x.html | 82 + ncurses-5.2/doc/html/man/form_field_new.3x.html | 136 + ncurses-5.2/doc/html/man/form_field_opts.3x.html | 134 + .../doc/html/man/form_field_userptr.3x.html | 82 + .../doc/html/man/form_field_validation.3x.html | 190 + ncurses-5.2/doc/html/man/form_fieldtype.3x.html | 136 + ncurses-5.2/doc/html/man/form_hook.3x.html | 136 + ncurses-5.2/doc/html/man/form_new.3x.html | 82 + ncurses-5.2/doc/html/man/form_new_page.3x.html | 82 + ncurses-5.2/doc/html/man/form_opts.3x.html | 136 + ncurses-5.2/doc/html/man/form_page.3x.html | 136 + ncurses-5.2/doc/html/man/form_post.3x.html | 136 + ncurses-5.2/doc/html/man/form_requestname.3x.html | 82 + ncurses-5.2/doc/html/man/form_userptr.3x.html | 82 + ncurses-5.2/doc/html/man/form_win.3x.html | 136 + ncurses-5.2/doc/html/man/infocmp.1m.html | 406 + ncurses-5.2/doc/html/man/infotocap.1m.html | 78 + ncurses-5.2/doc/html/man/keybound.3x.html | 80 + ncurses-5.2/doc/html/man/keyok.3x.html | 80 + ncurses-5.2/doc/html/man/menu.3x.html | 244 + ncurses-5.2/doc/html/man/menu_attributes.3x.html | 136 + ncurses-5.2/doc/html/man/menu_cursor.3x.html | 82 + ncurses-5.2/doc/html/man/menu_driver.3x.html | 190 + ncurses-5.2/doc/html/man/menu_format.3x.html | 136 + ncurses-5.2/doc/html/man/menu_hook.3x.html | 136 + ncurses-5.2/doc/html/man/menu_items.3x.html | 136 + ncurses-5.2/doc/html/man/menu_mark.3x.html | 82 + ncurses-5.2/doc/html/man/menu_new.3x.html | 82 + ncurses-5.2/doc/html/man/menu_opts.3x.html | 136 + ncurses-5.2/doc/html/man/menu_pattern.3x.html | 82 + ncurses-5.2/doc/html/man/menu_post.3x.html | 136 + ncurses-5.2/doc/html/man/menu_requestname.3x.html | 82 + ncurses-5.2/doc/html/man/menu_spacing.3x.html | 82 + ncurses-5.2/doc/html/man/menu_userptr.3x.html | 82 + ncurses-5.2/doc/html/man/menu_win.3x.html | 136 + ncurses-5.2/doc/html/man/mitem_current.3x.html | 137 + ncurses-5.2/doc/html/man/mitem_name.3x.html | 82 + ncurses-5.2/doc/html/man/mitem_new.3x.html | 82 + ncurses-5.2/doc/html/man/mitem_opts.3x.html | 82 + ncurses-5.2/doc/html/man/mitem_userptr.3x.html | 82 + ncurses-5.2/doc/html/man/mitem_value.3x.html | 82 + ncurses-5.2/doc/html/man/mitem_visible.3x.html | 80 + ncurses-5.2/doc/html/man/ncurses.3x.html | 899 + ncurses-5.2/doc/html/man/panel.3x.html | 194 + ncurses-5.2/doc/html/man/resizeterm.3x.html | 80 + ncurses-5.2/doc/html/man/term.5.html | 184 + ncurses-5.2/doc/html/man/term.7.html | 239 + ncurses-5.2/doc/html/man/terminfo.5.html | 2242 +++ ncurses-5.2/doc/html/man/tic.1m.html | 297 + ncurses-5.2/doc/html/man/toe.1m.html | 76 + ncurses-5.2/doc/html/man/tput.1.html | 246 + ncurses-5.2/doc/html/man/tset.1.html | 303 + ncurses-5.2/doc/html/man/wresize.3x.html | 80 + ncurses-5.2/doc/html/ncurses-intro.html | 2686 +++ ncurses-5.2/doc/ncurses-intro.doc | 2502 +++ ncurses-5.2/form/Makefile.in | 155 + ncurses-5.2/form/READ.ME | 15 + ncurses-5.2/form/fld_arg.c | 91 + ncurses-5.2/form/fld_attr.c | 111 + ncurses-5.2/form/fld_current.c | 124 + ncurses-5.2/form/fld_def.c | 346 + ncurses-5.2/form/fld_dup.c | 97 + ncurses-5.2/form/fld_ftchoice.c | 62 + ncurses-5.2/form/fld_ftlink.c | 83 + ncurses-5.2/form/fld_info.c | 91 + ncurses-5.2/form/fld_just.c | 81 + ncurses-5.2/form/fld_link.c | 90 + ncurses-5.2/form/fld_max.c | 74 + ncurses-5.2/form/fld_move.c | 62 + ncurses-5.2/form/fld_newftyp.c | 125 + ncurses-5.2/form/fld_opts.c | 124 + ncurses-5.2/form/fld_pad.c | 78 + ncurses-5.2/form/fld_page.c | 76 + ncurses-5.2/form/fld_stat.c | 73 + ncurses-5.2/form/fld_type.c | 92 + ncurses-5.2/form/fld_user.c | 67 + ncurses-5.2/form/form.h | 388 + ncurses-5.2/form/form.priv.h | 128 + ncurses-5.2/form/frm_cursor.c | 66 + ncurses-5.2/form/frm_data.c | 181 + ncurses-5.2/form/frm_def.c | 376 + ncurses-5.2/form/frm_driver.c | 3843 ++++ ncurses-5.2/form/frm_hook.c | 140 + ncurses-5.2/form/frm_opts.c | 116 + ncurses-5.2/form/frm_page.c | 100 + ncurses-5.2/form/frm_post.c | 117 + ncurses-5.2/form/frm_req_name.c | 163 + ncurses-5.2/form/frm_scale.c | 63 + ncurses-5.2/form/frm_sub.c | 69 + ncurses-5.2/form/frm_user.c | 67 + ncurses-5.2/form/frm_win.c | 70 + ncurses-5.2/form/fty_alnum.c | 137 + ncurses-5.2/form/fty_alpha.c | 138 + ncurses-5.2/form/fty_enum.c | 295 + ncurses-5.2/form/fty_int.c | 160 + ncurses-5.2/form/fty_ipv4.c | 81 + ncurses-5.2/form/fty_num.c | 195 + ncurses-5.2/form/fty_regex.c | 257 + ncurses-5.2/form/headers | 31 + ncurses-5.2/form/llib-lform | 694 + ncurses-5.2/form/modules | 73 + ncurses-5.2/include/Caps | 1314 ++ ncurses-5.2/include/MKhashsize.sh | 14 + ncurses-5.2/include/MKncurses_def.sh | 80 + ncurses-5.2/include/MKparametrized.sh | 35 + ncurses-5.2/include/MKterm.h.awk.in | 315 + ncurses-5.2/include/Makefile.in | 111 + ncurses-5.2/include/capdefaults.c | 84 + ncurses-5.2/include/curses.h.in | 1370 ++ ncurses-5.2/include/edit_cfg.sh | 65 + ncurses-5.2/include/headers | 34 + ncurses-5.2/include/nc_alloc.h | 83 + ncurses-5.2/include/nc_panel.h | 66 + ncurses-5.2/include/ncurses_cfg.hin | 62 + ncurses-5.2/include/ncurses_defs | 151 + ncurses-5.2/include/term_entry.h | 161 + ncurses-5.2/include/termcap.h.in | 70 + ncurses-5.2/include/tic.h | 299 + ncurses-5.2/include/unctrl.h.in | 63 + ncurses-5.2/install-sh | 250 + ncurses-5.2/man/MKterminfo.sh | 105 + ncurses-5.2/man/Makefile.in | 75 + ncurses-5.2/man/captoinfo.1m | 189 + ncurses-5.2/man/clear.1 | 48 + ncurses-5.2/man/curs_addch.3x | 163 + ncurses-5.2/man/curs_addchstr.3x | 83 + ncurses-5.2/man/curs_addstr.3x | 82 + ncurses-5.2/man/curs_attr.3x | 221 + ncurses-5.2/man/curs_beep.3x | 63 + ncurses-5.2/man/curs_bkgd.3x | 102 + ncurses-5.2/man/curs_border.3x | 110 + ncurses-5.2/man/curs_clear.3x | 94 + ncurses-5.2/man/curs_color.3x | 216 + ncurses-5.2/man/curs_delch.3x | 70 + ncurses-5.2/man/curs_deleteln.3x | 87 + ncurses-5.2/man/curs_extend.3x | 89 + ncurses-5.2/man/curs_getch.3x | 277 + ncurses-5.2/man/curs_getstr.3x | 107 + ncurses-5.2/man/curs_getyx.3x | 72 + ncurses-5.2/man/curs_inch.3x | 73 + ncurses-5.2/man/curs_inchstr.3x | 88 + ncurses-5.2/man/curs_initscr.3x | 124 + ncurses-5.2/man/curs_inopts.3x | 214 + ncurses-5.2/man/curs_insch.3x | 70 + ncurses-5.2/man/curs_insstr.3x | 95 + ncurses-5.2/man/curs_instr.3x | 89 + ncurses-5.2/man/curs_kernel.3x | 159 + ncurses-5.2/man/curs_mouse.3x | 217 + ncurses-5.2/man/curs_move.3x | 63 + ncurses-5.2/man/curs_outopts.3x | 169 + ncurses-5.2/man/curs_overlay.3x | 76 + ncurses-5.2/man/curs_pad.3x | 110 + ncurses-5.2/man/curs_print.3x | 74 + ncurses-5.2/man/curs_printw.3x | 80 + ncurses-5.2/man/curs_refresh.3x | 115 + ncurses-5.2/man/curs_scanw.3x | 81 + ncurses-5.2/man/curs_scr_dump.3x | 94 + ncurses-5.2/man/curs_scroll.3x | 79 + ncurses-5.2/man/curs_slk.3x | 149 + ncurses-5.2/man/curs_termattrs.3x | 107 + ncurses-5.2/man/curs_termcap.3x | 118 + ncurses-5.2/man/curs_terminfo.3x | 272 + ncurses-5.2/man/curs_touch.3x | 96 + ncurses-5.2/man/curs_trace.3x | 150 + ncurses-5.2/man/curs_util.3x | 114 + ncurses-5.2/man/curs_window.3x | 159 + ncurses-5.2/man/default_colors.3x | 133 + ncurses-5.2/man/define_key.3x | 70 + ncurses-5.2/man/form.3x | 200 + ncurses-5.2/man/form_cursor.3x | 74 + ncurses-5.2/man/form_data.3x | 63 + ncurses-5.2/man/form_driver.3x | 272 + ncurses-5.2/man/form_field.3x | 97 + ncurses-5.2/man/form_field_attributes.3x | 91 + ncurses-5.2/man/form_field_buffer.3x | 99 + ncurses-5.2/man/form_field_info.3x | 84 + ncurses-5.2/man/form_field_just.3x | 78 + ncurses-5.2/man/form_field_new.3x | 96 + ncurses-5.2/man/form_field_opts.3x | 120 + ncurses-5.2/man/form_field_userptr.3x | 73 + ncurses-5.2/man/form_field_validation.3x | 127 + ncurses-5.2/man/form_fieldtype.3x | 126 + ncurses-5.2/man/form_hook.3x | 100 + ncurses-5.2/man/form_new.3x | 79 + ncurses-5.2/man/form_new_page.3x | 77 + ncurses-5.2/man/form_opts.3x | 90 + ncurses-5.2/man/form_page.3x | 95 + ncurses-5.2/man/form_post.3x | 90 + ncurses-5.2/man/form_requestname.3x | 69 + ncurses-5.2/man/form_userptr.3x | 73 + ncurses-5.2/man/form_win.3x | 95 + ncurses-5.2/man/infocmp.1m | 378 + ncurses-5.2/man/infotocap.1m | 74 + ncurses-5.2/man/keybound.3x | 67 + ncurses-5.2/man/keyok.3x | 69 + ncurses-5.2/man/make_sed.sh | 83 + ncurses-5.2/man/man_db.renames | 117 + ncurses-5.2/man/manlinks.sed | 68 + ncurses-5.2/man/menu.3x | 190 + ncurses-5.2/man/menu_attributes.3x | 100 + ncurses-5.2/man/menu_cursor.3x | 73 + ncurses-5.2/man/menu_driver.3x | 170 + ncurses-5.2/man/menu_format.3x | 84 + ncurses-5.2/man/menu_hook.3x | 101 + ncurses-5.2/man/menu_items.3x | 91 + ncurses-5.2/man/menu_mark.3x | 84 + ncurses-5.2/man/menu_new.3x | 79 + ncurses-5.2/man/menu_opts.3x | 104 + ncurses-5.2/man/menu_pattern.3x | 82 + ncurses-5.2/man/menu_post.3x | 91 + ncurses-5.2/man/menu_requestname.3x | 69 + ncurses-5.2/man/menu_spacing.3x | 84 + ncurses-5.2/man/menu_userptr.3x | 73 + ncurses-5.2/man/menu_win.3x | 95 + ncurses-5.2/man/mitem_current.3x | 101 + ncurses-5.2/man/mitem_name.3x | 64 + ncurses-5.2/man/mitem_new.3x | 83 + ncurses-5.2/man/mitem_opts.3x | 84 + ncurses-5.2/man/mitem_userptr.3x | 72 + ncurses-5.2/man/mitem_value.3x | 76 + ncurses-5.2/man/mitem_visible.3x | 59 + ncurses-5.2/man/ncurses.3x | 927 + ncurses-5.2/man/panel.3x | 182 + ncurses-5.2/man/resizeterm.3x | 87 + ncurses-5.2/man/term.5 | 208 + ncurses-5.2/man/term.7 | 204 + ncurses-5.2/man/terminfo.head | 95 + ncurses-5.2/man/terminfo.tail | 1499 ++ ncurses-5.2/man/tic.1m | 301 + ncurses-5.2/man/toe.1m | 81 + ncurses-5.2/man/tput.1 | 256 + ncurses-5.2/man/tset.1 | 250 + ncurses-5.2/man/wresize.3x | 70 + ncurses-5.2/menu/Makefile.in | 157 + ncurses-5.2/menu/READ.ME | 14 + ncurses-5.2/menu/eti.h | 52 + ncurses-5.2/menu/headers | 32 + ncurses-5.2/menu/llib-lmenu | 508 + ncurses-5.2/menu/m_attribs.c | 141 + ncurses-5.2/menu/m_cursor.c | 110 + ncurses-5.2/menu/m_driver.c | 540 + ncurses-5.2/menu/m_format.c | 125 + ncurses-5.2/menu/m_global.c | 483 + ncurses-5.2/menu/m_hook.c | 149 + ncurses-5.2/menu/m_item_cur.c | 106 + ncurses-5.2/menu/m_item_nam.c | 68 + ncurses-5.2/menu/m_item_new.c | 227 + ncurses-5.2/menu/m_item_opt.c | 146 + ncurses-5.2/menu/m_item_top.c | 102 + ncurses-5.2/menu/m_item_use.c | 72 + ncurses-5.2/menu/m_item_val.c | 100 + ncurses-5.2/menu/m_item_vis.c | 66 + ncurses-5.2/menu/m_items.c | 103 + ncurses-5.2/menu/m_new.c | 108 + ncurses-5.2/menu/m_opts.c | 170 + ncurses-5.2/menu/m_pad.c | 90 + ncurses-5.2/menu/m_pattern.c | 117 + ncurses-5.2/menu/m_post.c | 366 + ncurses-5.2/menu/m_req_name.c | 119 + ncurses-5.2/menu/m_scale.c | 71 + ncurses-5.2/menu/m_spacing.c | 98 + ncurses-5.2/menu/m_sub.c | 80 + ncurses-5.2/menu/m_userptr.c | 72 + ncurses-5.2/menu/m_win.c | 80 + ncurses-5.2/menu/menu.h | 254 + ncurses-5.2/menu/menu.priv.h | 114 + ncurses-5.2/menu/mf_common.h | 93 + ncurses-5.2/menu/modules | 60 + ncurses-5.2/misc/Makefile.in | 121 + ncurses-5.2/misc/chkdef.cmd | 86 + ncurses-5.2/misc/cleantic.cmd | 16 + ncurses-5.2/misc/cmpdef.cmd | 106 + ncurses-5.2/misc/emx.src | 825 + ncurses-5.2/misc/form.def | 101 + ncurses-5.2/misc/form.ref | 106 + ncurses-5.2/misc/indent.pro | 35 + ncurses-5.2/misc/makedef.cmd | 151 + ncurses-5.2/misc/makellib | 162 + ncurses-5.2/misc/menu.def | 81 + ncurses-5.2/misc/menu.ref | 73 + ncurses-5.2/misc/ncurses.def | 447 + ncurses-5.2/misc/ncurses.ref | 572 + ncurses-5.2/misc/panel.def | 20 + ncurses-5.2/misc/panel.ref | 18 + ncurses-5.2/misc/run_tic.in | 146 + ncurses-5.2/misc/shlib | 87 + ncurses-5.2/misc/tabset/std | 1 + ncurses-5.2/misc/tabset/stdcrt | 1 + ncurses-5.2/misc/tabset/vt100 | 3 + ncurses-5.2/misc/tabset/vt300 | 3 + ncurses-5.2/misc/tdlint | 111 + ncurses-5.2/misc/terminfo.src | 18609 +++++++++++++++++++ ncurses-5.2/mk-0th.awk | 91 + ncurses-5.2/mk-1st.awk | 311 + ncurses-5.2/mk-2nd.awk | 115 + ncurses-5.2/mkinstalldirs | 37 + ncurses-5.2/ncurses/Makefile.in | 253 + ncurses-5.2/ncurses/README | 2 + ncurses-5.2/ncurses/SigAction.h | 117 + ncurses-5.2/ncurses/base/MKkeyname.awk | 74 + ncurses-5.2/ncurses/base/MKlib_gen.sh | 259 + ncurses-5.2/ncurses/base/MKunctrl.awk | 69 + ncurses-5.2/ncurses/base/README | 7 + ncurses-5.2/ncurses/base/define_key.c | 59 + ncurses-5.2/ncurses/base/keybound.c | 45 + ncurses-5.2/ncurses/base/keyok.c | 72 + ncurses-5.2/ncurses/base/lib_addch.c | 298 + ncurses-5.2/ncurses/base/lib_addstr.c | 103 + ncurses-5.2/ncurses/base/lib_beep.c | 73 + ncurses-5.2/ncurses/base/lib_bkgd.c | 86 + ncurses-5.2/ncurses/base/lib_box.c | 119 + ncurses-5.2/ncurses/base/lib_chgat.c | 62 + ncurses-5.2/ncurses/base/lib_clear.c | 55 + ncurses-5.2/ncurses/base/lib_clearok.c | 56 + ncurses-5.2/ncurses/base/lib_clrbot.c | 76 + ncurses-5.2/ncurses/base/lib_clreol.c | 91 + ncurses-5.2/ncurses/base/lib_color.c | 482 + ncurses-5.2/ncurses/base/lib_colorset.c | 58 + ncurses-5.2/ncurses/base/lib_delch.c | 68 + ncurses-5.2/ncurses/base/lib_delwin.c | 72 + ncurses-5.2/ncurses/base/lib_dft_fgbg.c | 71 + ncurses-5.2/ncurses/base/lib_echo.c | 60 + ncurses-5.2/ncurses/base/lib_endwin.c | 61 + ncurses-5.2/ncurses/base/lib_erase.c | 73 + ncurses-5.2/ncurses/base/lib_flash.c | 73 + ncurses-5.2/ncurses/base/lib_freeall.c | 139 + ncurses-5.2/ncurses/base/lib_getch.c | 388 + ncurses-5.2/ncurses/base/lib_getstr.c | 192 + ncurses-5.2/ncurses/base/lib_hline.c | 77 + ncurses-5.2/ncurses/base/lib_immedok.c | 54 + ncurses-5.2/ncurses/base/lib_inchstr.c | 62 + ncurses-5.2/ncurses/base/lib_initscr.c | 78 + ncurses-5.2/ncurses/base/lib_insch.c | 67 + ncurses-5.2/ncurses/base/lib_insdel.c | 62 + ncurses-5.2/ncurses/base/lib_insstr.c | 81 + ncurses-5.2/ncurses/base/lib_instr.c | 73 + ncurses-5.2/ncurses/base/lib_isendwin.c | 51 + ncurses-5.2/ncurses/base/lib_leaveok.c | 56 + ncurses-5.2/ncurses/base/lib_mouse.c | 1004 + ncurses-5.2/ncurses/base/lib_move.c | 61 + ncurses-5.2/ncurses/base/lib_mvwin.c | 109 + ncurses-5.2/ncurses/base/lib_newterm.c | 227 + ncurses-5.2/ncurses/base/lib_newwin.c | 286 + ncurses-5.2/ncurses/base/lib_nl.c | 79 + ncurses-5.2/ncurses/base/lib_overlay.c | 161 + ncurses-5.2/ncurses/base/lib_pad.c | 292 + ncurses-5.2/ncurses/base/lib_printw.c | 110 + ncurses-5.2/ncurses/base/lib_redrawln.c | 69 + ncurses-5.2/ncurses/base/lib_refresh.c | 183 + ncurses-5.2/ncurses/base/lib_restart.c | 91 + ncurses-5.2/ncurses/base/lib_scanw.c | 111 + ncurses-5.2/ncurses/base/lib_screen.c | 198 + ncurses-5.2/ncurses/base/lib_scroll.c | 120 + ncurses-5.2/ncurses/base/lib_scrollok.c | 56 + ncurses-5.2/ncurses/base/lib_scrreg.c | 60 + ncurses-5.2/ncurses/base/lib_set_term.c | 419 + ncurses-5.2/ncurses/base/lib_slk.c | 214 + ncurses-5.2/ncurses/base/lib_slkatr_set.c | 56 + ncurses-5.2/ncurses/base/lib_slkatrof.c | 55 + ncurses-5.2/ncurses/base/lib_slkatron.c | 55 + ncurses-5.2/ncurses/base/lib_slkatrset.c | 55 + ncurses-5.2/ncurses/base/lib_slkattr.c | 54 + ncurses-5.2/ncurses/base/lib_slkclear.c | 62 + ncurses-5.2/ncurses/base/lib_slkcolor.c | 54 + ncurses-5.2/ncurses/base/lib_slkinit.c | 51 + ncurses-5.2/ncurses/base/lib_slklab.c | 51 + ncurses-5.2/ncurses/base/lib_slkrefr.c | 126 + ncurses-5.2/ncurses/base/lib_slkset.c | 95 + ncurses-5.2/ncurses/base/lib_slktouch.c | 53 + ncurses-5.2/ncurses/base/lib_touch.c | 87 + ncurses-5.2/ncurses/base/lib_ungetch.c | 74 + ncurses-5.2/ncurses/base/lib_vline.c | 76 + ncurses-5.2/ncurses/base/lib_wattroff.c | 55 + ncurses-5.2/ncurses/base/lib_wattron.c | 55 + ncurses-5.2/ncurses/base/lib_winch.c | 53 + ncurses-5.2/ncurses/base/lib_window.c | 221 + ncurses-5.2/ncurses/base/memmove.c | 63 + ncurses-5.2/ncurses/base/nc_panel.c | 41 + ncurses-5.2/ncurses/base/resizeterm.c | 121 + ncurses-5.2/ncurses/base/safe_sprintf.c | 239 + ncurses-5.2/ncurses/base/sigaction.c | 106 + ncurses-5.2/ncurses/base/tries.c | 138 + ncurses-5.2/ncurses/base/version.c | 47 + ncurses-5.2/ncurses/base/vsscanf.c | 47 + ncurses-5.2/ncurses/base/wresize.c | 179 + ncurses-5.2/ncurses/curses.priv.h | 838 + ncurses-5.2/ncurses/fifo_defs.h | 59 + ncurses-5.2/ncurses/llib-lncurses | 3021 +++ ncurses-5.2/ncurses/modules | 189 + ncurses-5.2/ncurses/tinfo/MKcaptab.awk | 70 + ncurses-5.2/ncurses/tinfo/MKfallback.sh | 75 + ncurses-5.2/ncurses/tinfo/MKnames.awk | 98 + ncurses-5.2/ncurses/tinfo/README | 8 + ncurses-5.2/ncurses/tinfo/access.c | 94 + ncurses-5.2/ncurses/tinfo/add_tries.c | 125 + ncurses-5.2/ncurses/tinfo/alloc_entry.c | 225 + ncurses-5.2/ncurses/tinfo/alloc_ttype.c | 489 + ncurses-5.2/ncurses/tinfo/captoinfo.c | 831 + ncurses-5.2/ncurses/tinfo/comp_error.c | 132 + ncurses-5.2/ncurses/tinfo/comp_expand.c | 189 + ncurses-5.2/ncurses/tinfo/comp_hash.c | 325 + ncurses-5.2/ncurses/tinfo/comp_parse.c | 484 + ncurses-5.2/ncurses/tinfo/comp_scan.c | 797 + ncurses-5.2/ncurses/tinfo/doalloc.c | 74 + ncurses-5.2/ncurses/tinfo/free_ttype.c | 72 + ncurses-5.2/ncurses/tinfo/getenv_num.c | 56 + ncurses-5.2/ncurses/tinfo/home_terminfo.c | 65 + ncurses-5.2/ncurses/tinfo/init_keytry.c | 78 + ncurses-5.2/ncurses/tinfo/keys.list | 158 + ncurses-5.2/ncurses/tinfo/lib_acs.c | 139 + ncurses-5.2/ncurses/tinfo/lib_baudrate.c | 178 + ncurses-5.2/ncurses/tinfo/lib_cur_term.c | 70 + ncurses-5.2/ncurses/tinfo/lib_data.c | 84 + ncurses-5.2/ncurses/tinfo/lib_has_cap.c | 63 + ncurses-5.2/ncurses/tinfo/lib_kernel.c | 130 + ncurses-5.2/ncurses/tinfo/lib_longname.c | 58 + ncurses-5.2/ncurses/tinfo/lib_napms.c | 89 + ncurses-5.2/ncurses/tinfo/lib_options.c | 255 + ncurses-5.2/ncurses/tinfo/lib_print.c | 96 + ncurses-5.2/ncurses/tinfo/lib_raw.c | 236 + ncurses-5.2/ncurses/tinfo/lib_setup.c | 414 + ncurses-5.2/ncurses/tinfo/lib_termcap.c | 192 + ncurses-5.2/ncurses/tinfo/lib_termname.c | 46 + ncurses-5.2/ncurses/tinfo/lib_tgoto.c | 197 + ncurses-5.2/ncurses/tinfo/lib_ti.c | 103 + ncurses-5.2/ncurses/tinfo/lib_tparm.c | 740 + ncurses-5.2/ncurses/tinfo/lib_tputs.c | 324 + ncurses-5.2/ncurses/tinfo/lib_ttyflags.c | 163 + ncurses-5.2/ncurses/tinfo/make_keys.c | 134 + ncurses-5.2/ncurses/tinfo/name_match.c | 96 + ncurses-5.2/ncurses/tinfo/parse_entry.c | 952 + ncurses-5.2/ncurses/tinfo/read_entry.c | 501 + ncurses-5.2/ncurses/tinfo/read_termcap.c | 1111 ++ ncurses-5.2/ncurses/tinfo/setbuf.c | 144 + ncurses-5.2/ncurses/tinfo/strings.c | 139 + ncurses-5.2/ncurses/tinfo/write_entry.c | 581 + ncurses-5.2/ncurses/trace/README | 5 + ncurses-5.2/ncurses/trace/lib_trace.c | 216 + ncurses-5.2/ncurses/trace/lib_traceatr.c | 240 + ncurses-5.2/ncurses/trace/lib_tracebits.c | 247 + ncurses-5.2/ncurses/trace/lib_tracechr.c | 51 + ncurses-5.2/ncurses/trace/lib_tracedmp.c | 128 + ncurses-5.2/ncurses/trace/lib_tracemse.c | 95 + ncurses-5.2/ncurses/trace/trace_buf.c | 80 + ncurses-5.2/ncurses/trace/trace_tries.c | 74 + ncurses-5.2/ncurses/trace/trace_xnames.c | 74 + ncurses-5.2/ncurses/tty/MKexpanded.sh | 99 + ncurses-5.2/ncurses/tty/hardscroll.c | 328 + ncurses-5.2/ncurses/tty/hashmap.c | 569 + ncurses-5.2/ncurses/tty/lib_mvcur.c | 1182 ++ ncurses-5.2/ncurses/tty/lib_tstp.c | 366 + ncurses-5.2/ncurses/tty/lib_twait.c | 265 + ncurses-5.2/ncurses/tty/lib_vidattr.c | 296 + ncurses-5.2/ncurses/tty/tty_display.h | 137 + ncurses-5.2/ncurses/tty/tty_input.h | 61 + ncurses-5.2/ncurses/tty/tty_update.c | 1801 ++ ncurses-5.2/panel/Makefile.in | 149 + ncurses-5.2/panel/headers | 31 + ncurses-5.2/panel/llib-lpanel | 143 + ncurses-5.2/panel/modules | 49 + ncurses-5.2/panel/p_above.c | 51 + ncurses-5.2/panel/p_below.c | 53 + ncurses-5.2/panel/p_bottom.c | 70 + ncurses-5.2/panel/p_delete.c | 54 + ncurses-5.2/panel/p_hidden.c | 47 + ncurses-5.2/panel/p_hide.c | 57 + ncurses-5.2/panel/p_move.c | 54 + ncurses-5.2/panel/p_new.c | 104 + ncurses-5.2/panel/p_replace.c | 53 + ncurses-5.2/panel/p_show.c | 67 + ncurses-5.2/panel/p_top.c | 45 + ncurses-5.2/panel/p_update.c | 60 + ncurses-5.2/panel/p_user.c | 55 + ncurses-5.2/panel/p_win.c | 49 + ncurses-5.2/panel/panel.c | 136 + ncurses-5.2/panel/panel.h | 75 + ncurses-5.2/panel/panel.priv.h | 203 + ncurses-5.2/progs/MKtermsort.sh | 127 + ncurses-5.2/progs/Makefile.in | 269 + ncurses-5.2/progs/capconvert | 229 + ncurses-5.2/progs/clear.c | 58 + ncurses-5.2/progs/clear.sh | 1 + ncurses-5.2/progs/dump_entry.c | 972 + ncurses-5.2/progs/dump_entry.h | 67 + ncurses-5.2/progs/infocmp.c | 1441 ++ ncurses-5.2/progs/modules | 41 + ncurses-5.2/progs/progs.priv.h | 174 + ncurses-5.2/progs/tic.c | 1068 ++ ncurses-5.2/progs/toe.c | 291 + ncurses-5.2/progs/tput.c | 391 + ncurses-5.2/progs/tset.c | 1205 ++ ncurses-5.2/sysdeps/unix/sysv/linux/Makefile | 10 + .../sysdeps/unix/sysv/linux/alpha/configure | 2 + ncurses-5.2/sysdeps/unix/sysv/linux/configure | 407 + ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sed | 100 + ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sh | 37 + ncurses-5.2/sysdeps/unix/sysv/linux/run_tic.sh | 143 + ncurses-5.2/tack/COPYING | 340 + ncurses-5.2/tack/HISTORY | 44 + ncurses-5.2/tack/Makefile.in | 170 + ncurses-5.2/tack/README | 14 + ncurses-5.2/tack/ansi.c | 853 + ncurses-5.2/tack/charset.c | 709 + ncurses-5.2/tack/color.c | 767 + ncurses-5.2/tack/control.c | 657 + ncurses-5.2/tack/crum.c | 426 + ncurses-5.2/tack/edit.c | 977 + ncurses-5.2/tack/fun.c | 912 + ncurses-5.2/tack/init.c | 300 + ncurses-5.2/tack/menu.c | 421 + ncurses-5.2/tack/modes.c | 913 + ncurses-5.2/tack/modules | 18 + ncurses-5.2/tack/output.c | 818 + ncurses-5.2/tack/pad.c | 1957 ++ ncurses-5.2/tack/scan.c | 261 + ncurses-5.2/tack/sync.c | 424 + ncurses-5.2/tack/sysdep.c | 498 + ncurses-5.2/tack/tack.1 | 311 + ncurses-5.2/tack/tack.c | 620 + ncurses-5.2/tack/tack.h | 403 + ncurses-5.2/tar-copy.sh | 70 + ncurses-5.2/test/Makefile.in | 221 + ncurses-5.2/test/README | 22 + ncurses-5.2/test/blue.c | 440 + ncurses-5.2/test/bs.6 | 42 + ncurses-5.2/test/bs.c | 1268 ++ ncurses-5.2/test/cardfile.c | 420 + ncurses-5.2/test/cardfile.dat | 13 + ncurses-5.2/test/configure | 1998 ++ ncurses-5.2/test/configure.in | 199 + ncurses-5.2/test/ditto.c | 148 + ncurses-5.2/test/dots.c | 143 + ncurses-5.2/test/filter.c | 109 + ncurses-5.2/test/firework.c | 174 + ncurses-5.2/test/firstlast.c | 89 + ncurses-5.2/test/gdc.6 | 22 + ncurses-5.2/test/gdc.c | 316 + ncurses-5.2/test/hanoi.c | 303 + ncurses-5.2/test/hashtest.c | 220 + ncurses-5.2/test/keynames.c | 14 + ncurses-5.2/test/knight.c | 591 + ncurses-5.2/test/lrtest.c | 132 + ncurses-5.2/test/modules | 59 + ncurses-5.2/test/ncurses.c | 3616 ++++ ncurses-5.2/test/ncurses_tst.hin | 56 + ncurses-5.2/test/newdemo.c | 348 + ncurses-5.2/test/railroad.c | 241 + ncurses-5.2/test/rain.c | 133 + ncurses-5.2/test/tclock.c | 226 + ncurses-5.2/test/test.priv.h | 116 + ncurses-5.2/test/testaddch.c | 60 + ncurses-5.2/test/testcurs.c | 657 + ncurses-5.2/test/testscanw.c | 38 + ncurses-5.2/test/tracemunch | 98 + ncurses-5.2/test/view.c | 447 + ncurses-5.2/test/worm.c | 428 + ncurses-5.2/test/xmas.c | 1160 ++ ncurses-5.3/misc/run_tic.sh | 2 +- readline-4.3.orig/CHANGELOG | 699 + readline-4.3.orig/CHANGES | 612 + readline-4.3.orig/COPYING | 339 + readline-4.3.orig/INSTALL | 273 + readline-4.3.orig/MANIFEST | 126 + readline-4.3.orig/Makefile.in | 520 + readline-4.3.orig/README | 172 + readline-4.3.orig/USAGE | 37 + readline-4.3.orig/aclocal.m4 | 1792 ++ readline-4.3.orig/ansi_stdlib.h | 54 + readline-4.3.orig/bind.c | 2150 +++ readline-4.3.orig/callback.c | 156 + readline-4.3.orig/chardefs.h | 159 + readline-4.3.orig/compat.c | 113 + readline-4.3.orig/complete.c | 2004 ++ readline-4.3.orig/config.h.in | 200 + readline-4.3.orig/configure | 5865 ++++++ readline-4.3.orig/configure.in | 206 + readline-4.3.orig/display.c | 2196 +++ readline-4.3.orig/doc/Makefile.in | 234 + readline-4.3.orig/doc/hist.texinfo | 110 + readline-4.3.orig/doc/history.0 | 660 + readline-4.3.orig/doc/history.3 | 640 + readline-4.3.orig/doc/history.dvi | Bin 0 -> 48868 bytes readline-4.3.orig/doc/history.html | 1639 ++ readline-4.3.orig/doc/history.info | 840 + readline-4.3.orig/doc/history.ps | 1658 ++ readline-4.3.orig/doc/history_3.ps | 800 + readline-4.3.orig/doc/hstech.texinfo | 550 + readline-4.3.orig/doc/hsuser.texinfo | 437 + readline-4.3.orig/doc/manvers.texinfo | 10 + readline-4.3.orig/doc/readline.0 | 997 + readline-4.3.orig/doc/readline.3 | 1272 ++ readline-4.3.orig/doc/readline.dvi | Bin 0 -> 235920 bytes readline-4.3.orig/doc/readline.html | 5908 ++++++ readline-4.3.orig/doc/readline.info | 3638 ++++ readline-4.3.orig/doc/readline.ps | 5200 ++++++ readline-4.3.orig/doc/readline_3.ps | 1294 ++ readline-4.3.orig/doc/rlman.texinfo | 108 + readline-4.3.orig/doc/rltech.texinfo | 2165 +++ readline-4.3.orig/doc/rluser.texinfo | 1796 ++ readline-4.3.orig/doc/rluserman.dvi | Bin 0 -> 62592 bytes readline-4.3.orig/doc/rluserman.html | 2184 +++ readline-4.3.orig/doc/rluserman.info | 1260 ++ readline-4.3.orig/doc/rluserman.ps | 2001 ++ readline-4.3.orig/doc/rluserman.texinfo | 94 + readline-4.3.orig/doc/texi2dvi | 568 + readline-4.3.orig/doc/texi2html | 5429 ++++++ readline-4.3.orig/doc/texinfo.tex | 5992 ++++++ readline-4.3.orig/emacs_keymap.c | 873 + readline-4.3.orig/examples/Inputrc | 81 + readline-4.3.orig/examples/Makefile.in | 104 + readline-4.3.orig/examples/excallback.c | 188 + readline-4.3.orig/examples/fileman.c | 485 + readline-4.3.orig/examples/histexamp.c | 112 + readline-4.3.orig/examples/manexamp.c | 112 + readline-4.3.orig/examples/readlinebuf.h | 139 + readline-4.3.orig/examples/rl.c | 151 + readline-4.3.orig/examples/rlcat.c | 174 + readline-4.3.orig/examples/rlfe.c | 1042 ++ readline-4.3.orig/examples/rltest.c | 87 + readline-4.3.orig/examples/rlversion.c | 43 + readline-4.3.orig/funmap.c | 253 + readline-4.3.orig/histexpand.c | 1491 ++ readline-4.3.orig/histfile.c | 479 + readline-4.3.orig/histlib.h | 82 + readline-4.3.orig/history.c | 381 + readline-4.3.orig/history.h | 246 + readline-4.3.orig/histsearch.c | 195 + readline-4.3.orig/input.c | 540 + readline-4.3.orig/isearch.c | 560 + readline-4.3.orig/keymaps.c | 150 + readline-4.3.orig/keymaps.h | 103 + readline-4.3.orig/kill.c | 652 + readline-4.3.orig/macro.c | 262 + readline-4.3.orig/mbutil.c | 337 + readline-4.3.orig/misc.c | 496 + readline-4.3.orig/nls.c | 225 + readline-4.3.orig/parens.c | 179 + readline-4.3.orig/posixdir.h | 57 + readline-4.3.orig/posixjmp.h | 40 + readline-4.3.orig/posixstat.h | 142 + readline-4.3.orig/readline.c | 973 + readline-4.3.orig/readline.h | 799 + readline-4.3.orig/rlconf.h | 60 + readline-4.3.orig/rldefs.h | 156 + readline-4.3.orig/rlmbutil.h | 108 + readline-4.3.orig/rlprivate.h | 284 + readline-4.3.orig/rlshell.h | 34 + readline-4.3.orig/rlstdc.h | 45 + readline-4.3.orig/rltty.c | 911 + readline-4.3.orig/rltty.h | 82 + readline-4.3.orig/rltypedefs.h | 88 + readline-4.3.orig/rlwinsize.h | 57 + readline-4.3.orig/savestring.c | 36 + readline-4.3.orig/search.c | 465 + readline-4.3.orig/shell.c | 196 + readline-4.3.orig/shlib/Makefile.in | 437 + readline-4.3.orig/signals.c | 398 + readline-4.3.orig/support/config.guess | 1393 ++ readline-4.3.orig/support/config.sub | 1497 ++ readline-4.3.orig/support/install.sh | 247 + readline-4.3.orig/support/mkdirs | 48 + readline-4.3.orig/support/mkdist | 120 + readline-4.3.orig/support/shlib-install | 156 + readline-4.3.orig/support/shobj-conf | 458 + readline-4.3.orig/support/wcwidth.c | 236 + readline-4.3.orig/tcap.h | 60 + readline-4.3.orig/terminal.c | 662 + readline-4.3.orig/text.c | 1540 ++ readline-4.3.orig/tilde.c | 458 + readline-4.3.orig/tilde.h | 78 + readline-4.3.orig/undo.c | 263 + readline-4.3.orig/util.c | 338 + readline-4.3.orig/vi_keymap.c | 877 + readline-4.3.orig/vi_mode.c | 1485 ++ readline-4.3.orig/xmalloc.c | 88 + readline-4.3.orig/xmalloc.h | 46 + readline-4.3/CHANGELOG-ReadLine | 699 + readline-4.3/CHANGES | 612 + readline-4.3/COPYING | 339 + readline-4.3/INSTALL | 273 + readline-4.3/MANIFEST | 126 + readline-4.3/Makefile.in | 520 + readline-4.3/README | 172 + readline-4.3/USAGE | 37 + readline-4.3/aclocal.m4 | 1792 ++ readline-4.3/ansi_stdlib.h | 54 + readline-4.3/bind.c | 2150 +++ readline-4.3/callback.c | 156 + readline-4.3/chardefs.h | 159 + readline-4.3/compat.c | 113 + readline-4.3/complete.c | 2004 ++ readline-4.3/config.h.in | 200 + readline-4.3/configure | 5865 ++++++ readline-4.3/configure.in | 206 + readline-4.3/display.c | 2196 +++ readline-4.3/doc/Makefile.in | 234 + readline-4.3/doc/hist.texinfo | 110 + readline-4.3/doc/history.3 | 640 + readline-4.3/doc/hstech.texinfo | 550 + readline-4.3/doc/hsuser.texinfo | 437 + readline-4.3/doc/manvers.texinfo | 10 + readline-4.3/doc/readline.3 | 1272 ++ readline-4.3/doc/rlman.texinfo | 108 + readline-4.3/doc/rltech.texinfo | 2165 +++ readline-4.3/doc/rluser.texinfo | 1796 ++ readline-4.3/doc/rluserman.texinfo | 94 + readline-4.3/doc/texi2dvi | 568 + readline-4.3/doc/texi2html | 5429 ++++++ readline-4.3/doc/texinfo.tex | 5992 ++++++ readline-4.3/emacs_keymap.c | 873 + readline-4.3/examples/Inputrc | 81 + readline-4.3/examples/Makefile.in | 104 + readline-4.3/examples/excallback.c | 188 + readline-4.3/examples/fileman.c | 485 + readline-4.3/examples/histexamp.c | 112 + readline-4.3/examples/manexamp.c | 112 + readline-4.3/examples/readlinebuf.h | 139 + readline-4.3/examples/rl.c | 151 + readline-4.3/examples/rlcat.c | 174 + readline-4.3/examples/rlfe.c | 1042 ++ readline-4.3/examples/rltest.c | 87 + readline-4.3/examples/rlversion.c | 43 + readline-4.3/funmap.c | 253 + readline-4.3/histexpand.c | 1491 ++ readline-4.3/histfile.c | 479 + readline-4.3/histlib.h | 82 + readline-4.3/history.c | 381 + readline-4.3/history.h | 246 + readline-4.3/histsearch.c | 195 + readline-4.3/input.c | 540 + readline-4.3/isearch.c | 560 + readline-4.3/keymaps.c | 150 + readline-4.3/keymaps.h | 103 + readline-4.3/kill.c | 652 + readline-4.3/macro.c | 262 + readline-4.3/mbutil.c | 337 + readline-4.3/misc.c | 496 + readline-4.3/nls.c | 225 + readline-4.3/parens.c | 179 + readline-4.3/posixdir.h | 57 + readline-4.3/posixjmp.h | 40 + readline-4.3/posixstat.h | 142 + readline-4.3/readline.c | 973 + readline-4.3/readline.h | 799 + readline-4.3/rlconf.h | 60 + readline-4.3/rldefs.h | 156 + readline-4.3/rlmbutil.h | 108 + readline-4.3/rlprivate.h | 284 + readline-4.3/rlshell.h | 34 + readline-4.3/rlstdc.h | 45 + readline-4.3/rltty.c | 911 + readline-4.3/rltty.h | 82 + readline-4.3/rltypedefs.h | 88 + readline-4.3/rlwinsize.h | 57 + readline-4.3/savestring.c | 36 + readline-4.3/search.c | 465 + readline-4.3/shell.c | 196 + readline-4.3/shlib/Makefile.in | 437 + readline-4.3/signals.c | 400 + readline-4.3/support/config.guess | 1393 ++ readline-4.3/support/config.sub | 1497 ++ readline-4.3/support/install.sh | 247 + readline-4.3/support/mkdirs | 48 + readline-4.3/support/mkdist | 120 + readline-4.3/support/shlib-install | 156 + readline-4.3/support/shobj-conf | 458 + readline-4.3/support/wcwidth.c | 236 + readline-4.3/tcap.h | 60 + readline-4.3/terminal.c | 662 + readline-4.3/text.c | 1540 ++ readline-4.3/tilde.c | 458 + readline-4.3/tilde.h | 78 + readline-4.3/undo.c | 263 + readline-4.3/util.c | 338 + readline-4.3/vi_keymap.c | 877 + readline-4.3/vi_mode.c | 1485 ++ readline-4.3/xmalloc.c | 88 + readline-4.3/xmalloc.h | 46 + readline-doc-4.3/MANIFEST.doc | 21 + readline-doc-4.3/doc/history.0 | 660 + readline-doc-4.3/doc/history.dvi | Bin 0 -> 48868 bytes readline-doc-4.3/doc/history.html | 1639 ++ readline-doc-4.3/doc/history.info | 840 + readline-doc-4.3/doc/history.ps | 1658 ++ readline-doc-4.3/doc/history_3.ps | 800 + readline-doc-4.3/doc/readline.0 | 997 + readline-doc-4.3/doc/readline.dvi | Bin 0 -> 235920 bytes readline-doc-4.3/doc/readline.html | 5908 ++++++ readline-doc-4.3/doc/readline.info | 3638 ++++ readline-doc-4.3/doc/readline.ps | 5200 ++++++ readline-doc-4.3/doc/readline_3.ps | 1294 ++ readline-doc-4.3/doc/rluserman.dvi | Bin 0 -> 62592 bytes readline-doc-4.3/doc/rluserman.html | 2184 +++ readline-doc-4.3/doc/rluserman.info | 1260 ++ readline-doc-4.3/doc/rluserman.ps | 2001 ++ rtemsNfs/ChangeLog | 37 + rtemsNfs/LICENSE | 115 + rtemsNfs/Makefile | 16 + rtemsNfs/README | 491 + rtemsNfs/proto/Makefile | 75 + rtemsNfs/proto/mount_prot.h | 144 + rtemsNfs/proto/mount_prot.x | 161 + rtemsNfs/proto/mount_prot_xdr.c | 124 + rtemsNfs/proto/nfs_prot.h | 453 + rtemsNfs/proto/nfs_prot.x | 1268 ++ rtemsNfs/proto/nfs_prot_xdr.c | 671 + rtemsNfs/rtems-filesystem-patch | 860 + rtemsNfs/src/Makefile | 104 + rtemsNfs/src/cexphelp.c | 16 + rtemsNfs/src/dirutils.c | 323 + rtemsNfs/src/librtemsNfs.h | 158 + rtemsNfs/src/nfs.c | 3317 ++++ rtemsNfs/src/nfs.modini.c | 27 + rtemsNfs/src/rpcio.c | 1717 ++ rtemsNfs/src/rpcio.h | 205 + rtemsNfs/src/rpcio.modini.c | 15 + rtemsNfs/src/sock_mbuf.c | 279 + rtemsNfs/src/xdr_mbuf.c | 534 + zlib-1.1.4/ChangeLog | 481 + zlib-1.1.4/FAQ | 100 + zlib-1.1.4/INDEX | 86 + zlib-1.1.4/Make_vms.com | 115 + zlib-1.1.4/Makefile | 175 + zlib-1.1.4/Makefile.in | 175 + zlib-1.1.4/Makefile.riscos | 151 + zlib-1.1.4/README | 147 + zlib-1.1.4/adler32.c | 48 + zlib-1.1.4/algorithm.txt | 213 + zlib-1.1.4/amiga/Makefile.pup | 66 + zlib-1.1.4/amiga/Makefile.sas | 64 + zlib-1.1.4/compress.c | 68 + zlib-1.1.4/configure | 212 + zlib-1.1.4/contrib/README.contrib | 34 + zlib-1.1.4/contrib/asm386/gvmat32.asm | 559 + zlib-1.1.4/contrib/asm386/gvmat32c.c | 200 + zlib-1.1.4/contrib/asm386/mkgvmt32.bat | 1 + zlib-1.1.4/contrib/asm386/zlibvc.def | 74 + zlib-1.1.4/contrib/asm386/zlibvc.dsp | 651 + zlib-1.1.4/contrib/asm386/zlibvc.dsw | 41 + zlib-1.1.4/contrib/asm586/README.586 | 43 + zlib-1.1.4/contrib/asm586/match.S | 354 + zlib-1.1.4/contrib/asm686/README.686 | 34 + zlib-1.1.4/contrib/asm686/match.S | 327 + zlib-1.1.4/contrib/delphi/zlib.mak | 36 + zlib-1.1.4/contrib/delphi/zlibdef.pas | 169 + zlib-1.1.4/contrib/delphi2/d_zlib.bpr | 224 + zlib-1.1.4/contrib/delphi2/d_zlib.cpp | 17 + zlib-1.1.4/contrib/delphi2/readme.txt | 17 + zlib-1.1.4/contrib/delphi2/zlib.bpg | 26 + zlib-1.1.4/contrib/delphi2/zlib.bpr | 225 + zlib-1.1.4/contrib/delphi2/zlib.cpp | 22 + zlib-1.1.4/contrib/delphi2/zlib.pas | 534 + zlib-1.1.4/contrib/delphi2/zlib32.bpr | 174 + zlib-1.1.4/contrib/delphi2/zlib32.cpp | 42 + zlib-1.1.4/contrib/iostream/test.cpp | 24 + zlib-1.1.4/contrib/iostream/zfstream.cpp | 329 + zlib-1.1.4/contrib/iostream/zfstream.h | 142 + zlib-1.1.4/contrib/iostream2/zstream.h | 307 + zlib-1.1.4/contrib/iostream2/zstream_test.cpp | 25 + zlib-1.1.4/contrib/minizip/ChangeLogUnzip | 38 + zlib-1.1.4/contrib/minizip/Makefile | 25 + zlib-1.1.4/contrib/minizip/miniunz.c | 508 + zlib-1.1.4/contrib/minizip/minizip.c | 302 + zlib-1.1.4/contrib/minizip/readme.txt | 37 + zlib-1.1.4/contrib/minizip/unzip.c | 1294 ++ zlib-1.1.4/contrib/minizip/unzip.def | 15 + zlib-1.1.4/contrib/minizip/unzip.h | 275 + zlib-1.1.4/contrib/minizip/zip.c | 718 + zlib-1.1.4/contrib/minizip/zip.def | 5 + zlib-1.1.4/contrib/minizip/zip.h | 150 + zlib-1.1.4/contrib/minizip/zlibvc.def | 74 + zlib-1.1.4/contrib/minizip/zlibvc.dsp | 651 + zlib-1.1.4/contrib/minizip/zlibvc.dsw | 41 + zlib-1.1.4/contrib/untgz/Makefile | 14 + zlib-1.1.4/contrib/untgz/makefile.w32 | 63 + zlib-1.1.4/contrib/untgz/untgz.c | 522 + zlib-1.1.4/contrib/visual-basic.txt | 69 + zlib-1.1.4/crc32.c | 162 + zlib-1.1.4/deflate.c | 1350 ++ zlib-1.1.4/deflate.h | 318 + zlib-1.1.4/descrip.mms | 48 + zlib-1.1.4/example.c | 556 + zlib-1.1.4/gzio.c | 875 + zlib-1.1.4/infblock.c | 403 + zlib-1.1.4/infblock.h | 39 + zlib-1.1.4/infcodes.c | 251 + zlib-1.1.4/infcodes.h | 27 + zlib-1.1.4/inffast.c | 183 + zlib-1.1.4/inffast.h | 17 + zlib-1.1.4/inffixed.h | 151 + zlib-1.1.4/inflate.c | 366 + zlib-1.1.4/inftrees.c | 454 + zlib-1.1.4/inftrees.h | 58 + zlib-1.1.4/infutil.c | 87 + zlib-1.1.4/infutil.h | 98 + zlib-1.1.4/maketree.c | 85 + zlib-1.1.4/minigzip.c | 320 + zlib-1.1.4/msdos/Makefile.b32 | 104 + zlib-1.1.4/msdos/Makefile.bor | 125 + zlib-1.1.4/msdos/Makefile.dj2 | 100 + zlib-1.1.4/msdos/Makefile.emx | 69 + zlib-1.1.4/msdos/Makefile.msc | 121 + zlib-1.1.4/msdos/Makefile.tc | 108 + zlib-1.1.4/msdos/Makefile.w32 | 97 + zlib-1.1.4/msdos/Makefile.wat | 103 + zlib-1.1.4/msdos/zlib.def | 60 + zlib-1.1.4/msdos/zlib.rc | 32 + zlib-1.1.4/nt/Makefile.emx | 138 + zlib-1.1.4/nt/Makefile.gcc | 87 + zlib-1.1.4/nt/Makefile.nt | 88 + zlib-1.1.4/nt/zlib.dnt | 47 + zlib-1.1.4/os2/Makefile.os2 | 136 + zlib-1.1.4/os2/zlib.def | 51 + zlib-1.1.4/trees.c | 1214 ++ zlib-1.1.4/trees.h | 128 + zlib-1.1.4/uncompr.c | 58 + zlib-1.1.4/zconf.h | 279 + zlib-1.1.4/zlib.3 | 107 + zlib-1.1.4/zlib.h | 893 + zlib-1.1.4/zlib.html | 971 + zlib-1.1.4/zutil.c | 225 + zlib-1.1.4/zutil.h | 220 + 1402 files changed, 489629 insertions(+), 1 deletion(-) create mode 100644 ChangeLog create mode 100644 README create mode 100644 RTEMS_Makefiles/Makefile.avl create mode 100644 RTEMS_Makefiles/Makefile.bfd create mode 100644 RTEMS_Makefiles/Makefile.common create mode 100644 RTEMS_Makefiles/Makefile.libtecla create mode 100644 RTEMS_Makefiles/Makefile.ncurses create mode 100644 RTEMS_Makefiles/Makefile.ncurses-5.3 create mode 100644 RTEMS_Makefiles/Makefile.readline-4.3 create mode 100644 RTEMS_Makefiles/Makefile.site create mode 100644 RTEMS_Makefiles/Makefile.zlib create mode 100644 SUPPORT create mode 100644 VERSION create mode 100644 avl-1.4.0/AUTHORS create mode 100644 avl-1.4.0/COPYING create mode 100644 avl-1.4.0/ChangeLog create mode 100644 avl-1.4.0/INSTALL create mode 100644 avl-1.4.0/Makefile.am create mode 100644 avl-1.4.0/Makefile.in create mode 100644 avl-1.4.0/NEWS create mode 100644 avl-1.4.0/README create mode 100644 avl-1.4.0/THANKS create mode 100644 avl-1.4.0/TODO create mode 100644 avl-1.4.0/aclocal.m4 create mode 100644 avl-1.4.0/avl.c create mode 100644 avl-1.4.0/avl.h create mode 100644 avl-1.4.0/avl.html create mode 100644 avl-1.4.0/avl.info create mode 100644 avl-1.4.0/avl.texinfo create mode 100644 avl-1.4.0/avl.text create mode 100644 avl-1.4.0/avlt.c create mode 100644 avl-1.4.0/avlt.h create mode 100644 avl-1.4.0/avltr.c create mode 100644 avl-1.4.0/avltr.h create mode 100755 avl-1.4.0/configure create mode 100644 avl-1.4.0/configure.in create mode 100755 avl-1.4.0/install-sh create mode 100755 avl-1.4.0/missing create mode 100755 avl-1.4.0/mkinstalldirs create mode 100644 avl-1.4.0/rb.c create mode 100644 avl-1.4.0/rb.h create mode 100644 avl-1.4.0/texinfo.tex create mode 100644 avl-1.4.0/thread-test.c create mode 100755 bit create mode 100644 bit_bfd create mode 100644 examples/avl/BuildTests.sh create mode 100644 examples/avl/Makefile create mode 100644 examples/avl/README create mode 100644 examples/avl/init.c create mode 100644 examples/ncurses/BuildTests.sh create mode 100644 examples/ncurses/Makefile create mode 100644 examples/ncurses/README create mode 100644 examples/ncurses/init.c create mode 100644 examples/readline/.gdbinit create mode 100644 examples/readline/Makefile create mode 100644 examples/readline/init.c create mode 100644 examples/readline/rlgeneric.c create mode 100644 libtecla-1.4.1/CHANGES create mode 100644 libtecla-1.4.1/INSTALL create mode 100644 libtecla-1.4.1/LICENSE.TERMS create mode 100644 libtecla-1.4.1/Makefile create mode 100644 libtecla-1.4.1/Makefile.in create mode 100644 libtecla-1.4.1/Makefile.rules create mode 100644 libtecla-1.4.1/Makefile.stub create mode 100644 libtecla-1.4.1/PORTING create mode 100644 libtecla-1.4.1/README create mode 100644 libtecla-1.4.1/RELEASE.NOTES create mode 100644 libtecla-1.4.1/config.guess create mode 100644 libtecla-1.4.1/config.sub create mode 100755 libtecla-1.4.1/configure create mode 100644 libtecla-1.4.1/configure.in create mode 100644 libtecla-1.4.1/cplfile.c create mode 100644 libtecla-1.4.1/cplfile.h create mode 100644 libtecla-1.4.1/cplmatch.c create mode 100644 libtecla-1.4.1/demo.c create mode 100644 libtecla-1.4.1/demo2.c create mode 100644 libtecla-1.4.1/direader.c create mode 100644 libtecla-1.4.1/direader.h create mode 100644 libtecla-1.4.1/enhance.c create mode 100644 libtecla-1.4.1/expand.c create mode 100644 libtecla-1.4.1/freelist.c create mode 100644 libtecla-1.4.1/freelist.h create mode 100644 libtecla-1.4.1/getline.c create mode 100644 libtecla-1.4.1/getline.h create mode 100644 libtecla-1.4.1/hash.c create mode 100644 libtecla-1.4.1/hash.h create mode 100644 libtecla-1.4.1/history.c create mode 100644 libtecla-1.4.1/history.h create mode 100644 libtecla-1.4.1/homedir.c create mode 100644 libtecla-1.4.1/homedir.h create mode 100644 libtecla-1.4.1/html/changes.html create mode 100644 libtecla-1.4.1/html/cpl_complete_word.html create mode 100644 libtecla-1.4.1/html/ef_expand_file.html create mode 100644 libtecla-1.4.1/html/enhance.html create mode 100644 libtecla-1.4.1/html/gl_get_line.html create mode 100644 libtecla-1.4.1/html/index.html create mode 100644 libtecla-1.4.1/html/libtecla.html create mode 100644 libtecla-1.4.1/html/pca_lookup_file.html create mode 100644 libtecla-1.4.1/html/release.html create mode 100755 libtecla-1.4.1/install-sh create mode 100644 libtecla-1.4.1/keytab.c create mode 100644 libtecla-1.4.1/keytab.h create mode 100644 libtecla-1.4.1/libtecla.h create mode 100644 libtecla-1.4.1/libtecla.map create mode 100644 libtecla-1.4.1/man3/cfc_file_start.3 create mode 100644 libtecla-1.4.1/man3/cfc_literal_escapes.3 create mode 100644 libtecla-1.4.1/man3/cfc_set_check_fn.3 create mode 100644 libtecla-1.4.1/man3/cpl_add_completion.3 create mode 100644 libtecla-1.4.1/man3/cpl_complete_word.3 create mode 100644 libtecla-1.4.1/man3/cpl_file_completions.3 create mode 100644 libtecla-1.4.1/man3/cpl_last_error.3 create mode 100644 libtecla-1.4.1/man3/cpl_list_completions.3 create mode 100644 libtecla-1.4.1/man3/cpl_record_error.3 create mode 100644 libtecla-1.4.1/man3/del_CplFileConf.3 create mode 100644 libtecla-1.4.1/man3/del_ExpandFile.3 create mode 100644 libtecla-1.4.1/man3/del_GetLine.3 create mode 100644 libtecla-1.4.1/man3/del_PathCache.3 create mode 100644 libtecla-1.4.1/man3/del_PcaPathConf.3 create mode 100644 libtecla-1.4.1/man3/del_WordCompletion.3 create mode 100644 libtecla-1.4.1/man3/ef_expand_file.3 create mode 100644 libtecla-1.4.1/man3/ef_last_error.3 create mode 100644 libtecla-1.4.1/man3/ef_list_expansions.3 create mode 100644 libtecla-1.4.1/man3/enhance.3 create mode 100644 libtecla-1.4.1/man3/gl_change_terminal.3 create mode 100644 libtecla-1.4.1/man3/gl_clear_history.3 create mode 100644 libtecla-1.4.1/man3/gl_configure_getline.3 create mode 100644 libtecla-1.4.1/man3/gl_customize_completion.3 create mode 100644 libtecla-1.4.1/man3/gl_echo_mode.3 create mode 100644 libtecla-1.4.1/man3/gl_get_line.3 create mode 100644 libtecla-1.4.1/man3/gl_group_history.3 create mode 100644 libtecla-1.4.1/man3/gl_ignore_signal.3 create mode 100644 libtecla-1.4.1/man3/gl_last_signal.3 create mode 100644 libtecla-1.4.1/man3/gl_limit_history.3 create mode 100644 libtecla-1.4.1/man3/gl_load_history.3 create mode 100644 libtecla-1.4.1/man3/gl_lookup_history.3 create mode 100644 libtecla-1.4.1/man3/gl_prompt_style.3 create mode 100644 libtecla-1.4.1/man3/gl_range_of_history.3 create mode 100644 libtecla-1.4.1/man3/gl_resize_history.3 create mode 100644 libtecla-1.4.1/man3/gl_save_history.3 create mode 100644 libtecla-1.4.1/man3/gl_show_history.3 create mode 100644 libtecla-1.4.1/man3/gl_size_of_history.3 create mode 100644 libtecla-1.4.1/man3/gl_state_of_history.3 create mode 100644 libtecla-1.4.1/man3/gl_terminal_size.3 create mode 100644 libtecla-1.4.1/man3/gl_toggle_history.3 create mode 100644 libtecla-1.4.1/man3/gl_trap_signal.3 create mode 100644 libtecla-1.4.1/man3/gl_watch_fd.3 create mode 100644 libtecla-1.4.1/man3/libtecla.3 create mode 100644 libtecla-1.4.1/man3/libtecla_version.3 create mode 100644 libtecla-1.4.1/man3/new_CplFileConf.3 create mode 100644 libtecla-1.4.1/man3/new_ExpandFile.3 create mode 100644 libtecla-1.4.1/man3/new_GetLine.3 create mode 100644 libtecla-1.4.1/man3/new_PathCache.3 create mode 100644 libtecla-1.4.1/man3/new_PcaPathConf.3 create mode 100644 libtecla-1.4.1/man3/new_WordCompletion.3 create mode 100644 libtecla-1.4.1/man3/pca_last_error.3 create mode 100644 libtecla-1.4.1/man3/pca_lookup_file.3 create mode 100644 libtecla-1.4.1/man3/pca_path_completions.3 create mode 100644 libtecla-1.4.1/man3/pca_scan_path.3 create mode 100644 libtecla-1.4.1/man3/pca_set_check_fn.3 create mode 100644 libtecla-1.4.1/man3/ppc_file_start.3 create mode 100644 libtecla-1.4.1/man3/ppc_literal_escapes.3 create mode 100644 libtecla-1.4.1/pathutil.c create mode 100644 libtecla-1.4.1/pathutil.h create mode 100644 libtecla-1.4.1/pcache.c create mode 100644 libtecla-1.4.1/stringrp.c create mode 100644 libtecla-1.4.1/stringrp.h create mode 100644 libtecla-1.4.1/strngmem.c create mode 100644 libtecla-1.4.1/strngmem.h create mode 100755 libtecla-1.4.1/update_html create mode 100755 libtecla-1.4.1/update_version create mode 100644 libtecla-1.4.1/version.c create mode 100644 ncurses-5.2/ANNOUNCE create mode 100644 ncurses-5.2/Ada95/Makefile.in create mode 100644 ncurses-5.2/Ada95/README create mode 100644 ncurses-5.2/Ada95/TODO create mode 100644 ncurses-5.2/Ada95/gen/Makefile.in create mode 100644 ncurses-5.2/Ada95/gen/gen.c create mode 100644 ncurses-5.2/Ada95/gen/html.m4 create mode 100644 ncurses-5.2/Ada95/gen/normal.m4 create mode 100644 ncurses-5.2/Ada95/gen/table.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-aux.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-forms.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-menus.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-mouse.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses-panels.ads.m4 create mode 100644 ncurses-5.2/Ada95/gen/terminal_interface-curses.ads.m4 create mode 100644 ncurses-5.2/Ada95/samples/Makefile.in create mode 100644 ncurses-5.2/Ada95/samples/README create mode 100644 ncurses-5.2/Ada95/samples/explain.txt create mode 100644 ncurses-5.2/Ada95/samples/rain.adb create mode 100644 ncurses-5.2/Ada95/samples/rain.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-curses_demo.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-explanation.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-explanation.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo-handler.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo-handler.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-form_demo.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-function_key_setting.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-function_key_setting.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-header_handler.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-header_handler.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-helpers.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-helpers.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-keyboard_handler.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-keyboard_handler.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-manifest.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo-handler.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo-handler.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-menu_demo.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-my_field_type.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-my_field_type.ads create mode 100644 ncurses-5.2/Ada95/samples/sample-text_io_demo.adb create mode 100644 ncurses-5.2/Ada95/samples/sample-text_io_demo.ads create mode 100644 ncurses-5.2/Ada95/samples/sample.adb create mode 100644 ncurses-5.2/Ada95/samples/sample.ads create mode 100644 ncurses-5.2/Ada95/samples/status.adb create mode 100644 ncurses-5.2/Ada95/samples/status.ads create mode 100644 ncurses-5.2/Ada95/samples/tour.adb create mode 100644 ncurses-5.2/Ada95/samples/tour.ads create mode 100644 ncurses-5.2/Ada95/src/Makefile.in create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-aux.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_user_data.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms-form_user_data.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-forms.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-menus-item_user_data.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-menus-menu_user_data.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-menus.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-mouse.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-panels-user_data.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-panels.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.ads create mode 100644 ncurses-5.2/Ada95/src/terminal_interface-curses.adb create mode 100644 ncurses-5.2/Ada95/src/terminal_interface.ads create mode 100644 ncurses-5.2/INSTALL create mode 100644 ncurses-5.2/MANIFEST create mode 100644 ncurses-5.2/Makefile.glibc create mode 100644 ncurses-5.2/Makefile.in create mode 100644 ncurses-5.2/Makefile.os2 create mode 100644 ncurses-5.2/NEWS create mode 100644 ncurses-5.2/README create mode 100644 ncurses-5.2/README.emx create mode 100644 ncurses-5.2/README.glibc create mode 100644 ncurses-5.2/TO-DO create mode 100644 ncurses-5.2/aclocal.m4 create mode 100644 ncurses-5.2/announce.html.in create mode 100644 ncurses-5.2/c++/Makefile.in create mode 100644 ncurses-5.2/c++/NEWS create mode 100644 ncurses-5.2/c++/PROBLEMS create mode 100644 ncurses-5.2/c++/README-first create mode 100644 ncurses-5.2/c++/cursesapp.cc create mode 100644 ncurses-5.2/c++/cursesapp.h create mode 100644 ncurses-5.2/c++/cursesf.cc create mode 100644 ncurses-5.2/c++/cursesf.h create mode 100644 ncurses-5.2/c++/cursesm.cc create mode 100644 ncurses-5.2/c++/cursesm.h create mode 100644 ncurses-5.2/c++/cursesmain.cc create mode 100644 ncurses-5.2/c++/cursesp.cc create mode 100644 ncurses-5.2/c++/cursesp.h create mode 100644 ncurses-5.2/c++/cursespad.cc create mode 100644 ncurses-5.2/c++/cursesw.cc create mode 100644 ncurses-5.2/c++/cursesw.h create mode 100644 ncurses-5.2/c++/cursslk.cc create mode 100644 ncurses-5.2/c++/cursslk.h create mode 100644 ncurses-5.2/c++/demo.cc create mode 100755 ncurses-5.2/c++/edit_cfg.sh create mode 100644 ncurses-5.2/c++/etip.h.in create mode 100644 ncurses-5.2/c++/headers create mode 100644 ncurses-5.2/c++/internal.h create mode 100644 ncurses-5.2/c++/modules create mode 100755 ncurses-5.2/config.guess create mode 100755 ncurses-5.2/config.sub create mode 100755 ncurses-5.2/configure create mode 100644 ncurses-5.2/configure.in create mode 100644 ncurses-5.2/convert_configure.pl create mode 100644 ncurses-5.2/dist.mk create mode 100644 ncurses-5.2/doc/hackguide.doc create mode 100644 ncurses-5.2/doc/html/Ada95.html create mode 100644 ncurses-5.2/doc/html/ada/files.htm create mode 100644 ncurses-5.2/doc/html/ada/files/T.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/A.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/B.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/C.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/D.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/E.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/F.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/G.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/H.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/I.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/K.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/L.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/M.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/N.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/O.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/P.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/Q.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/R.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/S.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/T.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/U.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/V.htm create mode 100644 ncurses-5.2/doc/html/ada/funcs/W.htm create mode 100644 ncurses-5.2/doc/html/ada/index.htm create mode 100644 ncurses-5.2/doc/html/ada/main.htm create mode 100644 ncurses-5.2/doc/html/ada/table.html create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-aux__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-aux__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alpha__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alpha__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-intfield__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-intfield__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-numeric__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-numeric__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-regexp__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-regexp__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types-user__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_types__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_user_data__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-field_user_data__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-form_user_data__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms-form_user_data__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-forms__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-item_user_data__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-item_user_data__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-menu_user_data__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus-menu_user_data__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-menus__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-mouse__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-mouse__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-panels-user_data__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-panels-user_data__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-panels__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-panels__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-aux__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-aux__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-complex_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-complex_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-decimal_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-decimal_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-enumeration_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-enumeration_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-fixed_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-fixed_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-float_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-float_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-integer_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-integer_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-modular_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io-modular_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses-text_io__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses__adb.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface-curses__ads.htm create mode 100644 ncurses-5.2/doc/html/ada/terminal_interface__ads.htm create mode 100644 ncurses-5.2/doc/html/announce.html create mode 100644 ncurses-5.2/doc/html/hackguide.html create mode 100644 ncurses-5.2/doc/html/index.html create mode 100644 ncurses-5.2/doc/html/man/captoinfo.1m.html create mode 100644 ncurses-5.2/doc/html/man/clear.1.html create mode 100644 ncurses-5.2/doc/html/man/curs_addch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_addchstr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_addstr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_attr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_beep.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_bkgd.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_border.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_clear.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_color.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_delch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_deleteln.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_extend.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_getch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_getstr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_getyx.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_inch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_inchstr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_initscr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_inopts.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_insch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_insstr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_instr.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_kernel.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_mouse.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_move.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_outopts.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_overlay.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_pad.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_print.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_printw.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_refresh.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_scanw.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_scr_dump.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_scroll.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_slk.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_termattrs.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_termcap.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_terminfo.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_touch.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_trace.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_util.3x.html create mode 100644 ncurses-5.2/doc/html/man/curs_window.3x.html create mode 100644 ncurses-5.2/doc/html/man/default_colors.3x.html create mode 100644 ncurses-5.2/doc/html/man/define_key.3x.html create mode 100644 ncurses-5.2/doc/html/man/form.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_cursor.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_data.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_driver.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_attributes.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_buffer.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_info.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_just.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_new.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_opts.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_userptr.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_field_validation.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_fieldtype.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_hook.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_new.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_new_page.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_opts.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_page.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_post.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_requestname.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_userptr.3x.html create mode 100644 ncurses-5.2/doc/html/man/form_win.3x.html create mode 100644 ncurses-5.2/doc/html/man/infocmp.1m.html create mode 100644 ncurses-5.2/doc/html/man/infotocap.1m.html create mode 100644 ncurses-5.2/doc/html/man/keybound.3x.html create mode 100644 ncurses-5.2/doc/html/man/keyok.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_attributes.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_cursor.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_driver.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_format.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_hook.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_items.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_mark.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_new.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_opts.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_pattern.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_post.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_requestname.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_spacing.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_userptr.3x.html create mode 100644 ncurses-5.2/doc/html/man/menu_win.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_current.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_name.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_new.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_opts.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_userptr.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_value.3x.html create mode 100644 ncurses-5.2/doc/html/man/mitem_visible.3x.html create mode 100644 ncurses-5.2/doc/html/man/ncurses.3x.html create mode 100644 ncurses-5.2/doc/html/man/panel.3x.html create mode 100644 ncurses-5.2/doc/html/man/resizeterm.3x.html create mode 100644 ncurses-5.2/doc/html/man/term.5.html create mode 100644 ncurses-5.2/doc/html/man/term.7.html create mode 100644 ncurses-5.2/doc/html/man/terminfo.5.html create mode 100644 ncurses-5.2/doc/html/man/tic.1m.html create mode 100644 ncurses-5.2/doc/html/man/toe.1m.html create mode 100644 ncurses-5.2/doc/html/man/tput.1.html create mode 100644 ncurses-5.2/doc/html/man/tset.1.html create mode 100644 ncurses-5.2/doc/html/man/wresize.3x.html create mode 100644 ncurses-5.2/doc/html/ncurses-intro.html create mode 100644 ncurses-5.2/doc/ncurses-intro.doc create mode 100644 ncurses-5.2/form/Makefile.in create mode 100644 ncurses-5.2/form/READ.ME create mode 100644 ncurses-5.2/form/fld_arg.c create mode 100644 ncurses-5.2/form/fld_attr.c create mode 100644 ncurses-5.2/form/fld_current.c create mode 100644 ncurses-5.2/form/fld_def.c create mode 100644 ncurses-5.2/form/fld_dup.c create mode 100644 ncurses-5.2/form/fld_ftchoice.c create mode 100644 ncurses-5.2/form/fld_ftlink.c create mode 100644 ncurses-5.2/form/fld_info.c create mode 100644 ncurses-5.2/form/fld_just.c create mode 100644 ncurses-5.2/form/fld_link.c create mode 100644 ncurses-5.2/form/fld_max.c create mode 100644 ncurses-5.2/form/fld_move.c create mode 100644 ncurses-5.2/form/fld_newftyp.c create mode 100644 ncurses-5.2/form/fld_opts.c create mode 100644 ncurses-5.2/form/fld_pad.c create mode 100644 ncurses-5.2/form/fld_page.c create mode 100644 ncurses-5.2/form/fld_stat.c create mode 100644 ncurses-5.2/form/fld_type.c create mode 100644 ncurses-5.2/form/fld_user.c create mode 100644 ncurses-5.2/form/form.h create mode 100644 ncurses-5.2/form/form.priv.h create mode 100644 ncurses-5.2/form/frm_cursor.c create mode 100644 ncurses-5.2/form/frm_data.c create mode 100644 ncurses-5.2/form/frm_def.c create mode 100644 ncurses-5.2/form/frm_driver.c create mode 100644 ncurses-5.2/form/frm_hook.c create mode 100644 ncurses-5.2/form/frm_opts.c create mode 100644 ncurses-5.2/form/frm_page.c create mode 100644 ncurses-5.2/form/frm_post.c create mode 100644 ncurses-5.2/form/frm_req_name.c create mode 100644 ncurses-5.2/form/frm_scale.c create mode 100644 ncurses-5.2/form/frm_sub.c create mode 100644 ncurses-5.2/form/frm_user.c create mode 100644 ncurses-5.2/form/frm_win.c create mode 100644 ncurses-5.2/form/fty_alnum.c create mode 100644 ncurses-5.2/form/fty_alpha.c create mode 100644 ncurses-5.2/form/fty_enum.c create mode 100644 ncurses-5.2/form/fty_int.c create mode 100644 ncurses-5.2/form/fty_ipv4.c create mode 100644 ncurses-5.2/form/fty_num.c create mode 100644 ncurses-5.2/form/fty_regex.c create mode 100644 ncurses-5.2/form/headers create mode 100644 ncurses-5.2/form/llib-lform create mode 100644 ncurses-5.2/form/modules create mode 100644 ncurses-5.2/include/Caps create mode 100755 ncurses-5.2/include/MKhashsize.sh create mode 100755 ncurses-5.2/include/MKncurses_def.sh create mode 100755 ncurses-5.2/include/MKparametrized.sh create mode 100644 ncurses-5.2/include/MKterm.h.awk.in create mode 100644 ncurses-5.2/include/Makefile.in create mode 100644 ncurses-5.2/include/capdefaults.c create mode 100644 ncurses-5.2/include/curses.h.in create mode 100755 ncurses-5.2/include/edit_cfg.sh create mode 100644 ncurses-5.2/include/headers create mode 100644 ncurses-5.2/include/nc_alloc.h create mode 100644 ncurses-5.2/include/nc_panel.h create mode 100644 ncurses-5.2/include/ncurses_cfg.hin create mode 100644 ncurses-5.2/include/ncurses_defs create mode 100644 ncurses-5.2/include/term_entry.h create mode 100644 ncurses-5.2/include/termcap.h.in create mode 100644 ncurses-5.2/include/tic.h create mode 100644 ncurses-5.2/include/unctrl.h.in create mode 100755 ncurses-5.2/install-sh create mode 100755 ncurses-5.2/man/MKterminfo.sh create mode 100644 ncurses-5.2/man/Makefile.in create mode 100644 ncurses-5.2/man/captoinfo.1m create mode 100644 ncurses-5.2/man/clear.1 create mode 100644 ncurses-5.2/man/curs_addch.3x create mode 100644 ncurses-5.2/man/curs_addchstr.3x create mode 100644 ncurses-5.2/man/curs_addstr.3x create mode 100644 ncurses-5.2/man/curs_attr.3x create mode 100644 ncurses-5.2/man/curs_beep.3x create mode 100644 ncurses-5.2/man/curs_bkgd.3x create mode 100644 ncurses-5.2/man/curs_border.3x create mode 100644 ncurses-5.2/man/curs_clear.3x create mode 100644 ncurses-5.2/man/curs_color.3x create mode 100644 ncurses-5.2/man/curs_delch.3x create mode 100644 ncurses-5.2/man/curs_deleteln.3x create mode 100644 ncurses-5.2/man/curs_extend.3x create mode 100644 ncurses-5.2/man/curs_getch.3x create mode 100644 ncurses-5.2/man/curs_getstr.3x create mode 100644 ncurses-5.2/man/curs_getyx.3x create mode 100644 ncurses-5.2/man/curs_inch.3x create mode 100644 ncurses-5.2/man/curs_inchstr.3x create mode 100644 ncurses-5.2/man/curs_initscr.3x create mode 100644 ncurses-5.2/man/curs_inopts.3x create mode 100644 ncurses-5.2/man/curs_insch.3x create mode 100644 ncurses-5.2/man/curs_insstr.3x create mode 100644 ncurses-5.2/man/curs_instr.3x create mode 100644 ncurses-5.2/man/curs_kernel.3x create mode 100644 ncurses-5.2/man/curs_mouse.3x create mode 100644 ncurses-5.2/man/curs_move.3x create mode 100644 ncurses-5.2/man/curs_outopts.3x create mode 100644 ncurses-5.2/man/curs_overlay.3x create mode 100644 ncurses-5.2/man/curs_pad.3x create mode 100644 ncurses-5.2/man/curs_print.3x create mode 100644 ncurses-5.2/man/curs_printw.3x create mode 100644 ncurses-5.2/man/curs_refresh.3x create mode 100644 ncurses-5.2/man/curs_scanw.3x create mode 100644 ncurses-5.2/man/curs_scr_dump.3x create mode 100644 ncurses-5.2/man/curs_scroll.3x create mode 100644 ncurses-5.2/man/curs_slk.3x create mode 100644 ncurses-5.2/man/curs_termattrs.3x create mode 100644 ncurses-5.2/man/curs_termcap.3x create mode 100644 ncurses-5.2/man/curs_terminfo.3x create mode 100644 ncurses-5.2/man/curs_touch.3x create mode 100644 ncurses-5.2/man/curs_trace.3x create mode 100644 ncurses-5.2/man/curs_util.3x create mode 100644 ncurses-5.2/man/curs_window.3x create mode 100644 ncurses-5.2/man/default_colors.3x create mode 100644 ncurses-5.2/man/define_key.3x create mode 100644 ncurses-5.2/man/form.3x create mode 100644 ncurses-5.2/man/form_cursor.3x create mode 100644 ncurses-5.2/man/form_data.3x create mode 100644 ncurses-5.2/man/form_driver.3x create mode 100644 ncurses-5.2/man/form_field.3x create mode 100644 ncurses-5.2/man/form_field_attributes.3x create mode 100644 ncurses-5.2/man/form_field_buffer.3x create mode 100644 ncurses-5.2/man/form_field_info.3x create mode 100644 ncurses-5.2/man/form_field_just.3x create mode 100644 ncurses-5.2/man/form_field_new.3x create mode 100644 ncurses-5.2/man/form_field_opts.3x create mode 100644 ncurses-5.2/man/form_field_userptr.3x create mode 100644 ncurses-5.2/man/form_field_validation.3x create mode 100644 ncurses-5.2/man/form_fieldtype.3x create mode 100644 ncurses-5.2/man/form_hook.3x create mode 100644 ncurses-5.2/man/form_new.3x create mode 100644 ncurses-5.2/man/form_new_page.3x create mode 100644 ncurses-5.2/man/form_opts.3x create mode 100644 ncurses-5.2/man/form_page.3x create mode 100644 ncurses-5.2/man/form_post.3x create mode 100644 ncurses-5.2/man/form_requestname.3x create mode 100644 ncurses-5.2/man/form_userptr.3x create mode 100644 ncurses-5.2/man/form_win.3x create mode 100644 ncurses-5.2/man/infocmp.1m create mode 100644 ncurses-5.2/man/infotocap.1m create mode 100644 ncurses-5.2/man/keybound.3x create mode 100644 ncurses-5.2/man/keyok.3x create mode 100755 ncurses-5.2/man/make_sed.sh create mode 100644 ncurses-5.2/man/man_db.renames create mode 100644 ncurses-5.2/man/manlinks.sed create mode 100644 ncurses-5.2/man/menu.3x create mode 100644 ncurses-5.2/man/menu_attributes.3x create mode 100644 ncurses-5.2/man/menu_cursor.3x create mode 100644 ncurses-5.2/man/menu_driver.3x create mode 100644 ncurses-5.2/man/menu_format.3x create mode 100644 ncurses-5.2/man/menu_hook.3x create mode 100644 ncurses-5.2/man/menu_items.3x create mode 100644 ncurses-5.2/man/menu_mark.3x create mode 100644 ncurses-5.2/man/menu_new.3x create mode 100644 ncurses-5.2/man/menu_opts.3x create mode 100644 ncurses-5.2/man/menu_pattern.3x create mode 100644 ncurses-5.2/man/menu_post.3x create mode 100644 ncurses-5.2/man/menu_requestname.3x create mode 100644 ncurses-5.2/man/menu_spacing.3x create mode 100644 ncurses-5.2/man/menu_userptr.3x create mode 100644 ncurses-5.2/man/menu_win.3x create mode 100644 ncurses-5.2/man/mitem_current.3x create mode 100644 ncurses-5.2/man/mitem_name.3x create mode 100644 ncurses-5.2/man/mitem_new.3x create mode 100644 ncurses-5.2/man/mitem_opts.3x create mode 100644 ncurses-5.2/man/mitem_userptr.3x create mode 100644 ncurses-5.2/man/mitem_value.3x create mode 100644 ncurses-5.2/man/mitem_visible.3x create mode 100644 ncurses-5.2/man/ncurses.3x create mode 100644 ncurses-5.2/man/panel.3x create mode 100644 ncurses-5.2/man/resizeterm.3x create mode 100644 ncurses-5.2/man/term.5 create mode 100644 ncurses-5.2/man/term.7 create mode 100644 ncurses-5.2/man/terminfo.head create mode 100644 ncurses-5.2/man/terminfo.tail create mode 100644 ncurses-5.2/man/tic.1m create mode 100644 ncurses-5.2/man/toe.1m create mode 100644 ncurses-5.2/man/tput.1 create mode 100644 ncurses-5.2/man/tset.1 create mode 100644 ncurses-5.2/man/wresize.3x create mode 100644 ncurses-5.2/menu/Makefile.in create mode 100644 ncurses-5.2/menu/READ.ME create mode 100644 ncurses-5.2/menu/eti.h create mode 100644 ncurses-5.2/menu/headers create mode 100644 ncurses-5.2/menu/llib-lmenu create mode 100644 ncurses-5.2/menu/m_attribs.c create mode 100644 ncurses-5.2/menu/m_cursor.c create mode 100644 ncurses-5.2/menu/m_driver.c create mode 100644 ncurses-5.2/menu/m_format.c create mode 100644 ncurses-5.2/menu/m_global.c create mode 100644 ncurses-5.2/menu/m_hook.c create mode 100644 ncurses-5.2/menu/m_item_cur.c create mode 100644 ncurses-5.2/menu/m_item_nam.c create mode 100644 ncurses-5.2/menu/m_item_new.c create mode 100644 ncurses-5.2/menu/m_item_opt.c create mode 100644 ncurses-5.2/menu/m_item_top.c create mode 100644 ncurses-5.2/menu/m_item_use.c create mode 100644 ncurses-5.2/menu/m_item_val.c create mode 100644 ncurses-5.2/menu/m_item_vis.c create mode 100644 ncurses-5.2/menu/m_items.c create mode 100644 ncurses-5.2/menu/m_new.c create mode 100644 ncurses-5.2/menu/m_opts.c create mode 100644 ncurses-5.2/menu/m_pad.c create mode 100644 ncurses-5.2/menu/m_pattern.c create mode 100644 ncurses-5.2/menu/m_post.c create mode 100644 ncurses-5.2/menu/m_req_name.c create mode 100644 ncurses-5.2/menu/m_scale.c create mode 100644 ncurses-5.2/menu/m_spacing.c create mode 100644 ncurses-5.2/menu/m_sub.c create mode 100644 ncurses-5.2/menu/m_userptr.c create mode 100644 ncurses-5.2/menu/m_win.c create mode 100644 ncurses-5.2/menu/menu.h create mode 100644 ncurses-5.2/menu/menu.priv.h create mode 100644 ncurses-5.2/menu/mf_common.h create mode 100644 ncurses-5.2/menu/modules create mode 100644 ncurses-5.2/misc/Makefile.in create mode 100644 ncurses-5.2/misc/chkdef.cmd create mode 100644 ncurses-5.2/misc/cleantic.cmd create mode 100644 ncurses-5.2/misc/cmpdef.cmd create mode 100644 ncurses-5.2/misc/emx.src create mode 100644 ncurses-5.2/misc/form.def create mode 100644 ncurses-5.2/misc/form.ref create mode 100644 ncurses-5.2/misc/indent.pro create mode 100644 ncurses-5.2/misc/makedef.cmd create mode 100755 ncurses-5.2/misc/makellib create mode 100644 ncurses-5.2/misc/menu.def create mode 100644 ncurses-5.2/misc/menu.ref create mode 100644 ncurses-5.2/misc/ncurses.def create mode 100644 ncurses-5.2/misc/ncurses.ref create mode 100644 ncurses-5.2/misc/panel.def create mode 100644 ncurses-5.2/misc/panel.ref create mode 100644 ncurses-5.2/misc/run_tic.in create mode 100755 ncurses-5.2/misc/shlib create mode 100644 ncurses-5.2/misc/tabset/std create mode 100644 ncurses-5.2/misc/tabset/stdcrt create mode 100644 ncurses-5.2/misc/tabset/vt100 create mode 100644 ncurses-5.2/misc/tabset/vt300 create mode 100755 ncurses-5.2/misc/tdlint create mode 100644 ncurses-5.2/misc/terminfo.src create mode 100644 ncurses-5.2/mk-0th.awk create mode 100644 ncurses-5.2/mk-1st.awk create mode 100644 ncurses-5.2/mk-2nd.awk create mode 100755 ncurses-5.2/mkinstalldirs create mode 100644 ncurses-5.2/ncurses/Makefile.in create mode 100644 ncurses-5.2/ncurses/README create mode 100644 ncurses-5.2/ncurses/SigAction.h create mode 100644 ncurses-5.2/ncurses/base/MKkeyname.awk create mode 100755 ncurses-5.2/ncurses/base/MKlib_gen.sh create mode 100644 ncurses-5.2/ncurses/base/MKunctrl.awk create mode 100644 ncurses-5.2/ncurses/base/README create mode 100644 ncurses-5.2/ncurses/base/define_key.c create mode 100644 ncurses-5.2/ncurses/base/keybound.c create mode 100644 ncurses-5.2/ncurses/base/keyok.c create mode 100644 ncurses-5.2/ncurses/base/lib_addch.c create mode 100644 ncurses-5.2/ncurses/base/lib_addstr.c create mode 100644 ncurses-5.2/ncurses/base/lib_beep.c create mode 100644 ncurses-5.2/ncurses/base/lib_bkgd.c create mode 100644 ncurses-5.2/ncurses/base/lib_box.c create mode 100644 ncurses-5.2/ncurses/base/lib_chgat.c create mode 100644 ncurses-5.2/ncurses/base/lib_clear.c create mode 100644 ncurses-5.2/ncurses/base/lib_clearok.c create mode 100644 ncurses-5.2/ncurses/base/lib_clrbot.c create mode 100644 ncurses-5.2/ncurses/base/lib_clreol.c create mode 100644 ncurses-5.2/ncurses/base/lib_color.c create mode 100644 ncurses-5.2/ncurses/base/lib_colorset.c create mode 100644 ncurses-5.2/ncurses/base/lib_delch.c create mode 100644 ncurses-5.2/ncurses/base/lib_delwin.c create mode 100644 ncurses-5.2/ncurses/base/lib_dft_fgbg.c create mode 100644 ncurses-5.2/ncurses/base/lib_echo.c create mode 100644 ncurses-5.2/ncurses/base/lib_endwin.c create mode 100644 ncurses-5.2/ncurses/base/lib_erase.c create mode 100644 ncurses-5.2/ncurses/base/lib_flash.c create mode 100644 ncurses-5.2/ncurses/base/lib_freeall.c create mode 100644 ncurses-5.2/ncurses/base/lib_getch.c create mode 100644 ncurses-5.2/ncurses/base/lib_getstr.c create mode 100644 ncurses-5.2/ncurses/base/lib_hline.c create mode 100644 ncurses-5.2/ncurses/base/lib_immedok.c create mode 100644 ncurses-5.2/ncurses/base/lib_inchstr.c create mode 100644 ncurses-5.2/ncurses/base/lib_initscr.c create mode 100644 ncurses-5.2/ncurses/base/lib_insch.c create mode 100644 ncurses-5.2/ncurses/base/lib_insdel.c create mode 100644 ncurses-5.2/ncurses/base/lib_insstr.c create mode 100644 ncurses-5.2/ncurses/base/lib_instr.c create mode 100644 ncurses-5.2/ncurses/base/lib_isendwin.c create mode 100644 ncurses-5.2/ncurses/base/lib_leaveok.c create mode 100644 ncurses-5.2/ncurses/base/lib_mouse.c create mode 100644 ncurses-5.2/ncurses/base/lib_move.c create mode 100644 ncurses-5.2/ncurses/base/lib_mvwin.c create mode 100644 ncurses-5.2/ncurses/base/lib_newterm.c create mode 100644 ncurses-5.2/ncurses/base/lib_newwin.c create mode 100644 ncurses-5.2/ncurses/base/lib_nl.c create mode 100644 ncurses-5.2/ncurses/base/lib_overlay.c create mode 100644 ncurses-5.2/ncurses/base/lib_pad.c create mode 100644 ncurses-5.2/ncurses/base/lib_printw.c create mode 100644 ncurses-5.2/ncurses/base/lib_redrawln.c create mode 100644 ncurses-5.2/ncurses/base/lib_refresh.c create mode 100644 ncurses-5.2/ncurses/base/lib_restart.c create mode 100644 ncurses-5.2/ncurses/base/lib_scanw.c create mode 100644 ncurses-5.2/ncurses/base/lib_screen.c create mode 100644 ncurses-5.2/ncurses/base/lib_scroll.c create mode 100644 ncurses-5.2/ncurses/base/lib_scrollok.c create mode 100644 ncurses-5.2/ncurses/base/lib_scrreg.c create mode 100644 ncurses-5.2/ncurses/base/lib_set_term.c create mode 100644 ncurses-5.2/ncurses/base/lib_slk.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkatr_set.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkatrof.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkatron.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkatrset.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkattr.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkclear.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkcolor.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkinit.c create mode 100644 ncurses-5.2/ncurses/base/lib_slklab.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkrefr.c create mode 100644 ncurses-5.2/ncurses/base/lib_slkset.c create mode 100644 ncurses-5.2/ncurses/base/lib_slktouch.c create mode 100644 ncurses-5.2/ncurses/base/lib_touch.c create mode 100644 ncurses-5.2/ncurses/base/lib_ungetch.c create mode 100644 ncurses-5.2/ncurses/base/lib_vline.c create mode 100644 ncurses-5.2/ncurses/base/lib_wattroff.c create mode 100644 ncurses-5.2/ncurses/base/lib_wattron.c create mode 100644 ncurses-5.2/ncurses/base/lib_winch.c create mode 100644 ncurses-5.2/ncurses/base/lib_window.c create mode 100644 ncurses-5.2/ncurses/base/memmove.c create mode 100644 ncurses-5.2/ncurses/base/nc_panel.c create mode 100644 ncurses-5.2/ncurses/base/resizeterm.c create mode 100644 ncurses-5.2/ncurses/base/safe_sprintf.c create mode 100644 ncurses-5.2/ncurses/base/sigaction.c create mode 100644 ncurses-5.2/ncurses/base/tries.c create mode 100644 ncurses-5.2/ncurses/base/version.c create mode 100644 ncurses-5.2/ncurses/base/vsscanf.c create mode 100644 ncurses-5.2/ncurses/base/wresize.c create mode 100644 ncurses-5.2/ncurses/curses.priv.h create mode 100644 ncurses-5.2/ncurses/fifo_defs.h create mode 100644 ncurses-5.2/ncurses/llib-lncurses create mode 100644 ncurses-5.2/ncurses/modules create mode 100644 ncurses-5.2/ncurses/tinfo/MKcaptab.awk create mode 100755 ncurses-5.2/ncurses/tinfo/MKfallback.sh create mode 100644 ncurses-5.2/ncurses/tinfo/MKnames.awk create mode 100644 ncurses-5.2/ncurses/tinfo/README create mode 100644 ncurses-5.2/ncurses/tinfo/access.c create mode 100644 ncurses-5.2/ncurses/tinfo/add_tries.c create mode 100644 ncurses-5.2/ncurses/tinfo/alloc_entry.c create mode 100644 ncurses-5.2/ncurses/tinfo/alloc_ttype.c create mode 100644 ncurses-5.2/ncurses/tinfo/captoinfo.c create mode 100644 ncurses-5.2/ncurses/tinfo/comp_error.c create mode 100644 ncurses-5.2/ncurses/tinfo/comp_expand.c create mode 100644 ncurses-5.2/ncurses/tinfo/comp_hash.c create mode 100644 ncurses-5.2/ncurses/tinfo/comp_parse.c create mode 100644 ncurses-5.2/ncurses/tinfo/comp_scan.c create mode 100644 ncurses-5.2/ncurses/tinfo/doalloc.c create mode 100644 ncurses-5.2/ncurses/tinfo/free_ttype.c create mode 100644 ncurses-5.2/ncurses/tinfo/getenv_num.c create mode 100644 ncurses-5.2/ncurses/tinfo/home_terminfo.c create mode 100644 ncurses-5.2/ncurses/tinfo/init_keytry.c create mode 100644 ncurses-5.2/ncurses/tinfo/keys.list create mode 100644 ncurses-5.2/ncurses/tinfo/lib_acs.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_baudrate.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_cur_term.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_data.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_has_cap.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_kernel.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_longname.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_napms.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_options.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_print.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_raw.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_setup.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_termcap.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_termname.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_tgoto.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_ti.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_tparm.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_tputs.c create mode 100644 ncurses-5.2/ncurses/tinfo/lib_ttyflags.c create mode 100644 ncurses-5.2/ncurses/tinfo/make_keys.c create mode 100644 ncurses-5.2/ncurses/tinfo/name_match.c create mode 100644 ncurses-5.2/ncurses/tinfo/parse_entry.c create mode 100644 ncurses-5.2/ncurses/tinfo/read_entry.c create mode 100644 ncurses-5.2/ncurses/tinfo/read_termcap.c create mode 100644 ncurses-5.2/ncurses/tinfo/setbuf.c create mode 100644 ncurses-5.2/ncurses/tinfo/strings.c create mode 100644 ncurses-5.2/ncurses/tinfo/write_entry.c create mode 100644 ncurses-5.2/ncurses/trace/README create mode 100644 ncurses-5.2/ncurses/trace/lib_trace.c create mode 100644 ncurses-5.2/ncurses/trace/lib_traceatr.c create mode 100644 ncurses-5.2/ncurses/trace/lib_tracebits.c create mode 100644 ncurses-5.2/ncurses/trace/lib_tracechr.c create mode 100644 ncurses-5.2/ncurses/trace/lib_tracedmp.c create mode 100644 ncurses-5.2/ncurses/trace/lib_tracemse.c create mode 100644 ncurses-5.2/ncurses/trace/trace_buf.c create mode 100644 ncurses-5.2/ncurses/trace/trace_tries.c create mode 100644 ncurses-5.2/ncurses/trace/trace_xnames.c create mode 100755 ncurses-5.2/ncurses/tty/MKexpanded.sh create mode 100644 ncurses-5.2/ncurses/tty/hardscroll.c create mode 100644 ncurses-5.2/ncurses/tty/hashmap.c create mode 100644 ncurses-5.2/ncurses/tty/lib_mvcur.c create mode 100644 ncurses-5.2/ncurses/tty/lib_tstp.c create mode 100644 ncurses-5.2/ncurses/tty/lib_twait.c create mode 100644 ncurses-5.2/ncurses/tty/lib_vidattr.c create mode 100644 ncurses-5.2/ncurses/tty/tty_display.h create mode 100644 ncurses-5.2/ncurses/tty/tty_input.h create mode 100644 ncurses-5.2/ncurses/tty/tty_update.c create mode 100644 ncurses-5.2/panel/Makefile.in create mode 100644 ncurses-5.2/panel/headers create mode 100644 ncurses-5.2/panel/llib-lpanel create mode 100644 ncurses-5.2/panel/modules create mode 100644 ncurses-5.2/panel/p_above.c create mode 100644 ncurses-5.2/panel/p_below.c create mode 100644 ncurses-5.2/panel/p_bottom.c create mode 100644 ncurses-5.2/panel/p_delete.c create mode 100644 ncurses-5.2/panel/p_hidden.c create mode 100644 ncurses-5.2/panel/p_hide.c create mode 100644 ncurses-5.2/panel/p_move.c create mode 100644 ncurses-5.2/panel/p_new.c create mode 100644 ncurses-5.2/panel/p_replace.c create mode 100644 ncurses-5.2/panel/p_show.c create mode 100644 ncurses-5.2/panel/p_top.c create mode 100644 ncurses-5.2/panel/p_update.c create mode 100644 ncurses-5.2/panel/p_user.c create mode 100644 ncurses-5.2/panel/p_win.c create mode 100644 ncurses-5.2/panel/panel.c create mode 100644 ncurses-5.2/panel/panel.h create mode 100644 ncurses-5.2/panel/panel.priv.h create mode 100755 ncurses-5.2/progs/MKtermsort.sh create mode 100644 ncurses-5.2/progs/Makefile.in create mode 100755 ncurses-5.2/progs/capconvert create mode 100644 ncurses-5.2/progs/clear.c create mode 100755 ncurses-5.2/progs/clear.sh create mode 100644 ncurses-5.2/progs/dump_entry.c create mode 100644 ncurses-5.2/progs/dump_entry.h create mode 100644 ncurses-5.2/progs/infocmp.c create mode 100644 ncurses-5.2/progs/modules create mode 100644 ncurses-5.2/progs/progs.priv.h create mode 100644 ncurses-5.2/progs/tic.c create mode 100644 ncurses-5.2/progs/toe.c create mode 100644 ncurses-5.2/progs/tput.c create mode 100644 ncurses-5.2/progs/tset.c create mode 100644 ncurses-5.2/sysdeps/unix/sysv/linux/Makefile create mode 100755 ncurses-5.2/sysdeps/unix/sysv/linux/alpha/configure create mode 100755 ncurses-5.2/sysdeps/unix/sysv/linux/configure create mode 100644 ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sed create mode 100755 ncurses-5.2/sysdeps/unix/sysv/linux/edit_man.sh create mode 100755 ncurses-5.2/sysdeps/unix/sysv/linux/run_tic.sh create mode 100644 ncurses-5.2/tack/COPYING create mode 100644 ncurses-5.2/tack/HISTORY create mode 100644 ncurses-5.2/tack/Makefile.in create mode 100644 ncurses-5.2/tack/README create mode 100644 ncurses-5.2/tack/ansi.c create mode 100644 ncurses-5.2/tack/charset.c create mode 100644 ncurses-5.2/tack/color.c create mode 100644 ncurses-5.2/tack/control.c create mode 100644 ncurses-5.2/tack/crum.c create mode 100644 ncurses-5.2/tack/edit.c create mode 100644 ncurses-5.2/tack/fun.c create mode 100644 ncurses-5.2/tack/init.c create mode 100644 ncurses-5.2/tack/menu.c create mode 100644 ncurses-5.2/tack/modes.c create mode 100644 ncurses-5.2/tack/modules create mode 100644 ncurses-5.2/tack/output.c create mode 100644 ncurses-5.2/tack/pad.c create mode 100644 ncurses-5.2/tack/scan.c create mode 100644 ncurses-5.2/tack/sync.c create mode 100644 ncurses-5.2/tack/sysdep.c create mode 100644 ncurses-5.2/tack/tack.1 create mode 100644 ncurses-5.2/tack/tack.c create mode 100644 ncurses-5.2/tack/tack.h create mode 100755 ncurses-5.2/tar-copy.sh create mode 100644 ncurses-5.2/test/Makefile.in create mode 100644 ncurses-5.2/test/README create mode 100644 ncurses-5.2/test/blue.c create mode 100644 ncurses-5.2/test/bs.6 create mode 100644 ncurses-5.2/test/bs.c create mode 100644 ncurses-5.2/test/cardfile.c create mode 100644 ncurses-5.2/test/cardfile.dat create mode 100755 ncurses-5.2/test/configure create mode 100644 ncurses-5.2/test/configure.in create mode 100644 ncurses-5.2/test/ditto.c create mode 100644 ncurses-5.2/test/dots.c create mode 100644 ncurses-5.2/test/filter.c create mode 100644 ncurses-5.2/test/firework.c create mode 100644 ncurses-5.2/test/firstlast.c create mode 100644 ncurses-5.2/test/gdc.6 create mode 100644 ncurses-5.2/test/gdc.c create mode 100644 ncurses-5.2/test/hanoi.c create mode 100644 ncurses-5.2/test/hashtest.c create mode 100644 ncurses-5.2/test/keynames.c create mode 100644 ncurses-5.2/test/knight.c create mode 100644 ncurses-5.2/test/lrtest.c create mode 100644 ncurses-5.2/test/modules create mode 100644 ncurses-5.2/test/ncurses.c create mode 100644 ncurses-5.2/test/ncurses_tst.hin create mode 100644 ncurses-5.2/test/newdemo.c create mode 100644 ncurses-5.2/test/railroad.c create mode 100644 ncurses-5.2/test/rain.c create mode 100644 ncurses-5.2/test/tclock.c create mode 100644 ncurses-5.2/test/test.priv.h create mode 100644 ncurses-5.2/test/testaddch.c create mode 100644 ncurses-5.2/test/testcurs.c create mode 100644 ncurses-5.2/test/testscanw.c create mode 100755 ncurses-5.2/test/tracemunch create mode 100644 ncurses-5.2/test/view.c create mode 100644 ncurses-5.2/test/worm.c create mode 100644 ncurses-5.2/test/xmas.c create mode 100644 readline-4.3.orig/CHANGELOG create mode 100644 readline-4.3.orig/CHANGES create mode 100644 readline-4.3.orig/COPYING create mode 100644 readline-4.3.orig/INSTALL create mode 100644 readline-4.3.orig/MANIFEST create mode 100644 readline-4.3.orig/Makefile.in create mode 100644 readline-4.3.orig/README create mode 100644 readline-4.3.orig/USAGE create mode 100644 readline-4.3.orig/aclocal.m4 create mode 100644 readline-4.3.orig/ansi_stdlib.h create mode 100644 readline-4.3.orig/bind.c create mode 100644 readline-4.3.orig/callback.c create mode 100644 readline-4.3.orig/chardefs.h create mode 100644 readline-4.3.orig/compat.c create mode 100644 readline-4.3.orig/complete.c create mode 100644 readline-4.3.orig/config.h.in create mode 100755 readline-4.3.orig/configure create mode 100644 readline-4.3.orig/configure.in create mode 100644 readline-4.3.orig/display.c create mode 100644 readline-4.3.orig/doc/Makefile.in create mode 100644 readline-4.3.orig/doc/hist.texinfo create mode 100644 readline-4.3.orig/doc/history.0 create mode 100644 readline-4.3.orig/doc/history.3 create mode 100644 readline-4.3.orig/doc/history.dvi create mode 100644 readline-4.3.orig/doc/history.html create mode 100644 readline-4.3.orig/doc/history.info create mode 100644 readline-4.3.orig/doc/history.ps create mode 100644 readline-4.3.orig/doc/history_3.ps create mode 100644 readline-4.3.orig/doc/hstech.texinfo create mode 100644 readline-4.3.orig/doc/hsuser.texinfo create mode 100644 readline-4.3.orig/doc/manvers.texinfo create mode 100644 readline-4.3.orig/doc/readline.0 create mode 100644 readline-4.3.orig/doc/readline.3 create mode 100644 readline-4.3.orig/doc/readline.dvi create mode 100644 readline-4.3.orig/doc/readline.html create mode 100644 readline-4.3.orig/doc/readline.info create mode 100644 readline-4.3.orig/doc/readline.ps create mode 100644 readline-4.3.orig/doc/readline_3.ps create mode 100644 readline-4.3.orig/doc/rlman.texinfo create mode 100644 readline-4.3.orig/doc/rltech.texinfo create mode 100644 readline-4.3.orig/doc/rluser.texinfo create mode 100644 readline-4.3.orig/doc/rluserman.dvi create mode 100644 readline-4.3.orig/doc/rluserman.html create mode 100644 readline-4.3.orig/doc/rluserman.info create mode 100644 readline-4.3.orig/doc/rluserman.ps create mode 100644 readline-4.3.orig/doc/rluserman.texinfo create mode 100755 readline-4.3.orig/doc/texi2dvi create mode 100755 readline-4.3.orig/doc/texi2html create mode 100644 readline-4.3.orig/doc/texinfo.tex create mode 100644 readline-4.3.orig/emacs_keymap.c create mode 100644 readline-4.3.orig/examples/Inputrc create mode 100644 readline-4.3.orig/examples/Makefile.in create mode 100644 readline-4.3.orig/examples/excallback.c create mode 100644 readline-4.3.orig/examples/fileman.c create mode 100644 readline-4.3.orig/examples/histexamp.c create mode 100644 readline-4.3.orig/examples/manexamp.c create mode 100644 readline-4.3.orig/examples/readlinebuf.h create mode 100644 readline-4.3.orig/examples/rl.c create mode 100644 readline-4.3.orig/examples/rlcat.c create mode 100644 readline-4.3.orig/examples/rlfe.c create mode 100644 readline-4.3.orig/examples/rltest.c create mode 100644 readline-4.3.orig/examples/rlversion.c create mode 100644 readline-4.3.orig/funmap.c create mode 100644 readline-4.3.orig/histexpand.c create mode 100644 readline-4.3.orig/histfile.c create mode 100644 readline-4.3.orig/histlib.h create mode 100644 readline-4.3.orig/history.c create mode 100644 readline-4.3.orig/history.h create mode 100644 readline-4.3.orig/histsearch.c create mode 100644 readline-4.3.orig/input.c create mode 100644 readline-4.3.orig/isearch.c create mode 100644 readline-4.3.orig/keymaps.c create mode 100644 readline-4.3.orig/keymaps.h create mode 100644 readline-4.3.orig/kill.c create mode 100644 readline-4.3.orig/macro.c create mode 100644 readline-4.3.orig/mbutil.c create mode 100644 readline-4.3.orig/misc.c create mode 100644 readline-4.3.orig/nls.c create mode 100644 readline-4.3.orig/parens.c create mode 100644 readline-4.3.orig/posixdir.h create mode 100644 readline-4.3.orig/posixjmp.h create mode 100644 readline-4.3.orig/posixstat.h create mode 100644 readline-4.3.orig/readline.c create mode 100644 readline-4.3.orig/readline.h create mode 100644 readline-4.3.orig/rlconf.h create mode 100644 readline-4.3.orig/rldefs.h create mode 100644 readline-4.3.orig/rlmbutil.h create mode 100644 readline-4.3.orig/rlprivate.h create mode 100644 readline-4.3.orig/rlshell.h create mode 100644 readline-4.3.orig/rlstdc.h create mode 100644 readline-4.3.orig/rltty.c create mode 100644 readline-4.3.orig/rltty.h create mode 100644 readline-4.3.orig/rltypedefs.h create mode 100644 readline-4.3.orig/rlwinsize.h create mode 100644 readline-4.3.orig/savestring.c create mode 100644 readline-4.3.orig/search.c create mode 100644 readline-4.3.orig/shell.c create mode 100644 readline-4.3.orig/shlib/Makefile.in create mode 100644 readline-4.3.orig/signals.c create mode 100755 readline-4.3.orig/support/config.guess create mode 100644 readline-4.3.orig/support/config.sub create mode 100755 readline-4.3.orig/support/install.sh create mode 100755 readline-4.3.orig/support/mkdirs create mode 100755 readline-4.3.orig/support/mkdist create mode 100755 readline-4.3.orig/support/shlib-install create mode 100755 readline-4.3.orig/support/shobj-conf create mode 100644 readline-4.3.orig/support/wcwidth.c create mode 100644 readline-4.3.orig/tcap.h create mode 100644 readline-4.3.orig/terminal.c create mode 100644 readline-4.3.orig/text.c create mode 100644 readline-4.3.orig/tilde.c create mode 100644 readline-4.3.orig/tilde.h create mode 100644 readline-4.3.orig/undo.c create mode 100644 readline-4.3.orig/util.c create mode 100644 readline-4.3.orig/vi_keymap.c create mode 100644 readline-4.3.orig/vi_mode.c create mode 100644 readline-4.3.orig/xmalloc.c create mode 100644 readline-4.3.orig/xmalloc.h create mode 100644 readline-4.3/CHANGELOG-ReadLine create mode 100644 readline-4.3/CHANGES create mode 100644 readline-4.3/COPYING create mode 100644 readline-4.3/INSTALL create mode 100644 readline-4.3/MANIFEST create mode 100644 readline-4.3/Makefile.in create mode 100644 readline-4.3/README create mode 100644 readline-4.3/USAGE create mode 100644 readline-4.3/aclocal.m4 create mode 100644 readline-4.3/ansi_stdlib.h create mode 100644 readline-4.3/bind.c create mode 100644 readline-4.3/callback.c create mode 100644 readline-4.3/chardefs.h create mode 100644 readline-4.3/compat.c create mode 100644 readline-4.3/complete.c create mode 100644 readline-4.3/config.h.in create mode 100755 readline-4.3/configure create mode 100644 readline-4.3/configure.in create mode 100644 readline-4.3/display.c create mode 100644 readline-4.3/doc/Makefile.in create mode 100644 readline-4.3/doc/hist.texinfo create mode 100644 readline-4.3/doc/history.3 create mode 100644 readline-4.3/doc/hstech.texinfo create mode 100644 readline-4.3/doc/hsuser.texinfo create mode 100644 readline-4.3/doc/manvers.texinfo create mode 100644 readline-4.3/doc/readline.3 create mode 100644 readline-4.3/doc/rlman.texinfo create mode 100644 readline-4.3/doc/rltech.texinfo create mode 100644 readline-4.3/doc/rluser.texinfo create mode 100644 readline-4.3/doc/rluserman.texinfo create mode 100755 readline-4.3/doc/texi2dvi create mode 100755 readline-4.3/doc/texi2html create mode 100644 readline-4.3/doc/texinfo.tex create mode 100644 readline-4.3/emacs_keymap.c create mode 100644 readline-4.3/examples/Inputrc create mode 100644 readline-4.3/examples/Makefile.in create mode 100644 readline-4.3/examples/excallback.c create mode 100644 readline-4.3/examples/fileman.c create mode 100644 readline-4.3/examples/histexamp.c create mode 100644 readline-4.3/examples/manexamp.c create mode 100644 readline-4.3/examples/readlinebuf.h create mode 100644 readline-4.3/examples/rl.c create mode 100644 readline-4.3/examples/rlcat.c create mode 100644 readline-4.3/examples/rlfe.c create mode 100644 readline-4.3/examples/rltest.c create mode 100644 readline-4.3/examples/rlversion.c create mode 100644 readline-4.3/funmap.c create mode 100644 readline-4.3/histexpand.c create mode 100644 readline-4.3/histfile.c create mode 100644 readline-4.3/histlib.h create mode 100644 readline-4.3/history.c create mode 100644 readline-4.3/history.h create mode 100644 readline-4.3/histsearch.c create mode 100644 readline-4.3/input.c create mode 100644 readline-4.3/isearch.c create mode 100644 readline-4.3/keymaps.c create mode 100644 readline-4.3/keymaps.h create mode 100644 readline-4.3/kill.c create mode 100644 readline-4.3/macro.c create mode 100644 readline-4.3/mbutil.c create mode 100644 readline-4.3/misc.c create mode 100644 readline-4.3/nls.c create mode 100644 readline-4.3/parens.c create mode 100644 readline-4.3/posixdir.h create mode 100644 readline-4.3/posixjmp.h create mode 100644 readline-4.3/posixstat.h create mode 100644 readline-4.3/readline.c create mode 100644 readline-4.3/readline.h create mode 100644 readline-4.3/rlconf.h create mode 100644 readline-4.3/rldefs.h create mode 100644 readline-4.3/rlmbutil.h create mode 100644 readline-4.3/rlprivate.h create mode 100644 readline-4.3/rlshell.h create mode 100644 readline-4.3/rlstdc.h create mode 100644 readline-4.3/rltty.c create mode 100644 readline-4.3/rltty.h create mode 100644 readline-4.3/rltypedefs.h create mode 100644 readline-4.3/rlwinsize.h create mode 100644 readline-4.3/savestring.c create mode 100644 readline-4.3/search.c create mode 100644 readline-4.3/shell.c create mode 100644 readline-4.3/shlib/Makefile.in create mode 100644 readline-4.3/signals.c create mode 100755 readline-4.3/support/config.guess create mode 100644 readline-4.3/support/config.sub create mode 100755 readline-4.3/support/install.sh create mode 100755 readline-4.3/support/mkdirs create mode 100755 readline-4.3/support/mkdist create mode 100755 readline-4.3/support/shlib-install create mode 100755 readline-4.3/support/shobj-conf create mode 100644 readline-4.3/support/wcwidth.c create mode 100644 readline-4.3/tcap.h create mode 100644 readline-4.3/terminal.c create mode 100644 readline-4.3/text.c create mode 100644 readline-4.3/tilde.c create mode 100644 readline-4.3/tilde.h create mode 100644 readline-4.3/undo.c create mode 100644 readline-4.3/util.c create mode 100644 readline-4.3/vi_keymap.c create mode 100644 readline-4.3/vi_mode.c create mode 100644 readline-4.3/xmalloc.c create mode 100644 readline-4.3/xmalloc.h create mode 100644 readline-doc-4.3/MANIFEST.doc create mode 100644 readline-doc-4.3/doc/history.0 create mode 100644 readline-doc-4.3/doc/history.dvi create mode 100644 readline-doc-4.3/doc/history.html create mode 100644 readline-doc-4.3/doc/history.info create mode 100644 readline-doc-4.3/doc/history.ps create mode 100644 readline-doc-4.3/doc/history_3.ps create mode 100644 readline-doc-4.3/doc/readline.0 create mode 100644 readline-doc-4.3/doc/readline.dvi create mode 100644 readline-doc-4.3/doc/readline.html create mode 100644 readline-doc-4.3/doc/readline.info create mode 100644 readline-doc-4.3/doc/readline.ps create mode 100644 readline-doc-4.3/doc/readline_3.ps create mode 100644 readline-doc-4.3/doc/rluserman.dvi create mode 100644 readline-doc-4.3/doc/rluserman.html create mode 100644 readline-doc-4.3/doc/rluserman.info create mode 100644 readline-doc-4.3/doc/rluserman.ps create mode 100644 rtemsNfs/ChangeLog create mode 100644 rtemsNfs/LICENSE create mode 100644 rtemsNfs/Makefile create mode 100644 rtemsNfs/README create mode 100644 rtemsNfs/proto/Makefile create mode 100644 rtemsNfs/proto/mount_prot.h create mode 100644 rtemsNfs/proto/mount_prot.x create mode 100644 rtemsNfs/proto/mount_prot_xdr.c create mode 100644 rtemsNfs/proto/nfs_prot.h create mode 100644 rtemsNfs/proto/nfs_prot.x create mode 100644 rtemsNfs/proto/nfs_prot_xdr.c create mode 100644 rtemsNfs/rtems-filesystem-patch create mode 100644 rtemsNfs/src/Makefile create mode 100644 rtemsNfs/src/cexphelp.c create mode 100644 rtemsNfs/src/dirutils.c create mode 100644 rtemsNfs/src/librtemsNfs.h create mode 100644 rtemsNfs/src/nfs.c create mode 100644 rtemsNfs/src/nfs.modini.c create mode 100644 rtemsNfs/src/rpcio.c create mode 100644 rtemsNfs/src/rpcio.h create mode 100644 rtemsNfs/src/rpcio.modini.c create mode 100644 rtemsNfs/src/sock_mbuf.c create mode 100644 rtemsNfs/src/xdr_mbuf.c create mode 100644 zlib-1.1.4/ChangeLog create mode 100644 zlib-1.1.4/FAQ create mode 100644 zlib-1.1.4/INDEX create mode 100644 zlib-1.1.4/Make_vms.com create mode 100644 zlib-1.1.4/Makefile create mode 100644 zlib-1.1.4/Makefile.in create mode 100644 zlib-1.1.4/Makefile.riscos create mode 100644 zlib-1.1.4/README create mode 100644 zlib-1.1.4/adler32.c create mode 100644 zlib-1.1.4/algorithm.txt create mode 100644 zlib-1.1.4/amiga/Makefile.pup create mode 100644 zlib-1.1.4/amiga/Makefile.sas create mode 100644 zlib-1.1.4/compress.c create mode 100755 zlib-1.1.4/configure create mode 100644 zlib-1.1.4/contrib/README.contrib create mode 100644 zlib-1.1.4/contrib/asm386/gvmat32.asm create mode 100644 zlib-1.1.4/contrib/asm386/gvmat32c.c create mode 100644 zlib-1.1.4/contrib/asm386/mkgvmt32.bat create mode 100644 zlib-1.1.4/contrib/asm386/zlibvc.def create mode 100644 zlib-1.1.4/contrib/asm386/zlibvc.dsp create mode 100644 zlib-1.1.4/contrib/asm386/zlibvc.dsw create mode 100644 zlib-1.1.4/contrib/asm586/README.586 create mode 100644 zlib-1.1.4/contrib/asm586/match.S create mode 100644 zlib-1.1.4/contrib/asm686/README.686 create mode 100644 zlib-1.1.4/contrib/asm686/match.S create mode 100644 zlib-1.1.4/contrib/delphi/zlib.mak create mode 100644 zlib-1.1.4/contrib/delphi/zlibdef.pas create mode 100644 zlib-1.1.4/contrib/delphi2/d_zlib.bpr create mode 100644 zlib-1.1.4/contrib/delphi2/d_zlib.cpp create mode 100644 zlib-1.1.4/contrib/delphi2/readme.txt create mode 100644 zlib-1.1.4/contrib/delphi2/zlib.bpg create mode 100644 zlib-1.1.4/contrib/delphi2/zlib.bpr create mode 100644 zlib-1.1.4/contrib/delphi2/zlib.cpp create mode 100644 zlib-1.1.4/contrib/delphi2/zlib.pas create mode 100644 zlib-1.1.4/contrib/delphi2/zlib32.bpr create mode 100644 zlib-1.1.4/contrib/delphi2/zlib32.cpp create mode 100644 zlib-1.1.4/contrib/iostream/test.cpp create mode 100644 zlib-1.1.4/contrib/iostream/zfstream.cpp create mode 100644 zlib-1.1.4/contrib/iostream/zfstream.h create mode 100644 zlib-1.1.4/contrib/iostream2/zstream.h create mode 100644 zlib-1.1.4/contrib/iostream2/zstream_test.cpp create mode 100644 zlib-1.1.4/contrib/minizip/ChangeLogUnzip create mode 100644 zlib-1.1.4/contrib/minizip/Makefile create mode 100644 zlib-1.1.4/contrib/minizip/miniunz.c create mode 100644 zlib-1.1.4/contrib/minizip/minizip.c create mode 100644 zlib-1.1.4/contrib/minizip/readme.txt create mode 100644 zlib-1.1.4/contrib/minizip/unzip.c create mode 100644 zlib-1.1.4/contrib/minizip/unzip.def create mode 100644 zlib-1.1.4/contrib/minizip/unzip.h create mode 100644 zlib-1.1.4/contrib/minizip/zip.c create mode 100644 zlib-1.1.4/contrib/minizip/zip.def create mode 100644 zlib-1.1.4/contrib/minizip/zip.h create mode 100644 zlib-1.1.4/contrib/minizip/zlibvc.def create mode 100644 zlib-1.1.4/contrib/minizip/zlibvc.dsp create mode 100644 zlib-1.1.4/contrib/minizip/zlibvc.dsw create mode 100644 zlib-1.1.4/contrib/untgz/Makefile create mode 100644 zlib-1.1.4/contrib/untgz/makefile.w32 create mode 100644 zlib-1.1.4/contrib/untgz/untgz.c create mode 100644 zlib-1.1.4/contrib/visual-basic.txt create mode 100644 zlib-1.1.4/crc32.c create mode 100644 zlib-1.1.4/deflate.c create mode 100644 zlib-1.1.4/deflate.h create mode 100644 zlib-1.1.4/descrip.mms create mode 100644 zlib-1.1.4/example.c create mode 100644 zlib-1.1.4/gzio.c create mode 100644 zlib-1.1.4/infblock.c create mode 100644 zlib-1.1.4/infblock.h create mode 100644 zlib-1.1.4/infcodes.c create mode 100644 zlib-1.1.4/infcodes.h create mode 100644 zlib-1.1.4/inffast.c create mode 100644 zlib-1.1.4/inffast.h create mode 100644 zlib-1.1.4/inffixed.h create mode 100644 zlib-1.1.4/inflate.c create mode 100644 zlib-1.1.4/inftrees.c create mode 100644 zlib-1.1.4/inftrees.h create mode 100644 zlib-1.1.4/infutil.c create mode 100644 zlib-1.1.4/infutil.h create mode 100644 zlib-1.1.4/maketree.c create mode 100644 zlib-1.1.4/minigzip.c create mode 100644 zlib-1.1.4/msdos/Makefile.b32 create mode 100644 zlib-1.1.4/msdos/Makefile.bor create mode 100644 zlib-1.1.4/msdos/Makefile.dj2 create mode 100644 zlib-1.1.4/msdos/Makefile.emx create mode 100644 zlib-1.1.4/msdos/Makefile.msc create mode 100644 zlib-1.1.4/msdos/Makefile.tc create mode 100644 zlib-1.1.4/msdos/Makefile.w32 create mode 100644 zlib-1.1.4/msdos/Makefile.wat create mode 100644 zlib-1.1.4/msdos/zlib.def create mode 100644 zlib-1.1.4/msdos/zlib.rc create mode 100644 zlib-1.1.4/nt/Makefile.emx create mode 100644 zlib-1.1.4/nt/Makefile.gcc create mode 100644 zlib-1.1.4/nt/Makefile.nt create mode 100644 zlib-1.1.4/nt/zlib.dnt create mode 100644 zlib-1.1.4/os2/Makefile.os2 create mode 100644 zlib-1.1.4/os2/zlib.def create mode 100644 zlib-1.1.4/trees.c create mode 100644 zlib-1.1.4/trees.h create mode 100644 zlib-1.1.4/uncompr.c create mode 100644 zlib-1.1.4/zconf.h create mode 100644 zlib-1.1.4/zlib.3 create mode 100644 zlib-1.1.4/zlib.h create mode 100644 zlib-1.1.4/zlib.html create mode 100644 zlib-1.1.4/zutil.c create mode 100644 zlib-1.1.4/zutil.h diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a8c7638 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,97 @@ +2006-04-19 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-4.6.99.3. + +2005-09-02 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-4.6.99.2. + +2005-09-02 Joel Sherrill + + * bit, ncurses-5.3/misc/run_tic.sh: Added rtemsNfs 1.2 + * rtemsNfs/ChangeLog, rtemsNfs/LICENSE, rtemsNfs/Makefile, + rtemsNfs/README, rtemsNfs/rtems-filesystem-patch, + rtemsNfs/proto/Makefile, rtemsNfs/proto/mount_prot.h, + rtemsNfs/proto/mount_prot.x, rtemsNfs/proto/mount_prot_xdr.c, + rtemsNfs/proto/nfs_prot.h, rtemsNfs/proto/nfs_prot.x, + rtemsNfs/proto/nfs_prot_xdr.c, rtemsNfs/src/Makefile, + rtemsNfs/src/cexphelp.c, rtemsNfs/src/dirutils.c, + rtemsNfs/src/librtemsNfs.h, rtemsNfs/src/nfs.c, + rtemsNfs/src/nfs.modini.c, rtemsNfs/src/rpcio.c, + rtemsNfs/src/rpcio.h, rtemsNfs/src/rpcio.modini.c, + rtemsNfs/src/sock_mbuf.c, rtemsNfs/src/xdr_mbuf.c: New files. + * rtemsNfs-1.1/ChangeLog, rtemsNfs-1.1/LICENSE, rtemsNfs-1.1/Makefile, + rtemsNfs-1.1/README, rtemsNfs-1.1/rtems-filesystem-patch, + rtemsNfs-1.1/proto/Makefile, rtemsNfs-1.1/proto/mount_prot.x, + rtemsNfs-1.1/proto/nfs_prot.x, rtemsNfs-1.1/src/Makefile, + rtemsNfs-1.1/src/cexphelp.c, rtemsNfs-1.1/src/dirutils.c, + rtemsNfs-1.1/src/librtemsNfs.h, rtemsNfs-1.1/src/nfs.c, + rtemsNfs-1.1/src/nfs.modini.c, rtemsNfs-1.1/src/rpcio.c, + rtemsNfs-1.1/src/rpcio.h, rtemsNfs-1.1/src/rpcio.modini.c, + rtemsNfs-1.1/src/sock_mbuf.c, rtemsNfs-1.1/src/xdr_mbuf.c: Removed. + +2004-10-18 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-4.6.2. + +2004-10-18 Joel Sherrill + + * aclocal/version.m4: Updated to rtems-addon-packages-4.6.2. + +2003-01-28 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-20030128. + +2003-01-28 Joel Sherrill + + * aclocal/version.m4: Updated to rtems-addon-packages-20030128. + +2003-01-20 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-20030120. + +2003-01-20 Joel Sherrill + + * aclocal/version.m4: Updated to rtems-addon-packages-20030120. + +2002-12-19 Eric Norum + + * ncurses-5.3 bit: Update ncurses add-on package. + +2002-11-28 Eric Norum + + * RTEMS_Makefiles/Makefile.bfd: New file + +2002-11-21 Eric Norum + + * bit, bit_bfd: Add support for additional add-ons (libtecla, BFD) + +2002-11-19 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-20021119. + +2002-11-19 Joel Sherrill + + * aclocal/version.m4: Updated to rtems-addon-packages-20021119. + +2002-11-08 Eric Norum + + * RTEMS_Makefiles/Makefile.libtecla, bit, libtecla-1.4.1/: + Add TECLA command-line editing library. + +2002-09-12 Eric Norum + + * RTEMS_Makefiles/Makefile.ncurses: Added ansi terminal type. + +2002-07-30 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-20020730a. + +2002-07-30 Joel Sherrill + + * VERSION: Updated to rtems-addon-packages-20020730. + +2002-07-30 Joel Sherrill + + * ChangeLog, VERSION, SUPPORT: New files. + diff --git a/README b/README new file mode 100644 index 0000000..504f048 --- /dev/null +++ b/README @@ -0,0 +1,24 @@ +Assorted add-on packages for RTEMS. + +The bit script builds and installs all the packages. + +To build a package: + cd <> + make -f ../RTEMS_Makefiles/Makefile.<> + +Notes +===== +1) You must build and install the host version of infocmp before trying to +build ncurses. +2) You must build and install ncurses before trying to build readline. +3) To add ncurses support for other terminals, change the declaration + of TERMINALS. + +Cautions +======== +The readline and ncurses `configure' scripts check for the presence of +select(). Because the RTEMS dummy.rel file does not include network +configuration information the scripts decide that select() does not +exist. This is correct since although RTEMS does have a select() call +it is not supported on tty devices. The fact that one shortcoming is +covering up another is not really satisfactory, though. diff --git a/RTEMS_Makefiles/Makefile.avl b/RTEMS_Makefiles/Makefile.avl new file mode 100644 index 0000000..b801392 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.avl @@ -0,0 +1,12 @@ +# +# Configure/build/install the AVL library +# +include ../RTEMS_Makefiles/Makefile.common + +all: + ./configure \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include + make + make install diff --git a/RTEMS_Makefiles/Makefile.bfd b/RTEMS_Makefiles/Makefile.bfd new file mode 100644 index 0000000..b6b9586 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.bfd @@ -0,0 +1,14 @@ +# +# Configure/build/install the libtecla library +# +include ../RTEMS_Makefiles/Makefile.common + +all: + $(BINUTILS_SRC_DIR)/bfd/configure \ + --host=$(RTEMS_CPU)-rtems \ + --disable-nls \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include + make + make install diff --git a/RTEMS_Makefiles/Makefile.common b/RTEMS_Makefiles/Makefile.common new file mode 100644 index 0000000..7e0ddbe --- /dev/null +++ b/RTEMS_Makefiles/Makefile.common @@ -0,0 +1,23 @@ +########################################################### +# Meta-Makefile for compiling packages to work with RTEMS # +########################################################### + +# +# Pick up RTEMS configuration +# +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg +CC += $(CPU_CFLAGS) + +# +# For some reason RTEMS Makefiles don't export this +# +export RANLIB + +.PHONY: all + +# +# Include site-specific options +# +include ../RTEMS_Makefiles/Makefile.site diff --git a/RTEMS_Makefiles/Makefile.libtecla b/RTEMS_Makefiles/Makefile.libtecla new file mode 100644 index 0000000..2405adb --- /dev/null +++ b/RTEMS_Makefiles/Makefile.libtecla @@ -0,0 +1,15 @@ +# +# Configure/build/install the libtecla library +# +include ../RTEMS_Makefiles/Makefile.common + +all: + ./configure \ + --host=$(RTEMS_CPU)-rtems \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include + make + make reentrant + make install + make distclean diff --git a/RTEMS_Makefiles/Makefile.ncurses b/RTEMS_Makefiles/Makefile.ncurses new file mode 100644 index 0000000..3df6d38 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.ncurses @@ -0,0 +1,28 @@ +# +# Declare supported terminal types. +# This value can be augmented/overridden by the site-configuration file +# +TERMINALS=xterm,vt100,linux,ansi + +include ../RTEMS_Makefiles/Makefile.common + +# +# The following will work only if you have the latest ncurses version +# of infocmp installed before trying to build for an RTEMS target. +# The cf_cv_type_of_bool hack works around a bug when configuring +# for a cross-target. +# +all: + cf_cv_type_of_bool=char CXX="$(CC)" TERM=xterm ./configure \ + --host=$(RTEMS_CPU)-rtems \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include \ + --without-ada \ + --without-progs \ + --without-cxx-binding \ + --disable-sigwinch \ + --disable-database \ + --with-fallbacks="$(TERMINALS)" + make "TERM=xterm" "HOSTCC=gcc" "HOSTCCFLAGS=-I. -I../include" HOSTLDFLAGS="" + make install diff --git a/RTEMS_Makefiles/Makefile.ncurses-5.3 b/RTEMS_Makefiles/Makefile.ncurses-5.3 new file mode 100644 index 0000000..24c5428 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.ncurses-5.3 @@ -0,0 +1,30 @@ +# +# Declare supported terminal types. +# This value can be augmented/overridden by the site-configuration file +# +TERMINALS=xterm,vt100,linux,ansi + +include ../RTEMS_Makefiles/Makefile.common + +# +# The following will work only if you have the latest ncurses version +# of infocmp installed before trying to build for an RTEMS target. +# The cf_cv_type_of_bool hack works around a bug when configuring +# for a cross-target. + #cf_cv_type_of_bool=char CXX="$(CC)" ./configure \ +# +all: + CXX="$(CC)" TERM=xterm ./configure \ + --host=$(RTEMS_CPU)-rtems \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include \ + --without-ada \ + --without-progs \ + --without-cxx-binding \ + --with-bool="unsigned char" \ + --disable-sigwinch \ + --disable-database \ + --with-fallbacks="$(TERMINALS)" + make "TERM=xterm" "HOSTCC=gcc" "HOSTCCFLAGS=-I. -I../include" HOSTLDFLAGS="" + make install diff --git a/RTEMS_Makefiles/Makefile.readline-4.3 b/RTEMS_Makefiles/Makefile.readline-4.3 new file mode 100644 index 0000000..36644d2 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.readline-4.3 @@ -0,0 +1,18 @@ +include ../RTEMS_Makefiles/Makefile.common + +# +# Running make distclean cleans up documentation files that require +# special tools to regenerate. Work around this problem by just +# copying the documentation files from another directory. +# +all: + bash_cv_have_mbstate_t=yes ./configure \ + --host=$(RTEMS_CPU)-rtems \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include \ + --disable-shared + cp ../readline-doc-4.3/doc/????* doc + make + cd doc ; make + make install diff --git a/RTEMS_Makefiles/Makefile.site b/RTEMS_Makefiles/Makefile.site new file mode 100644 index 0000000..2c9f3a4 --- /dev/null +++ b/RTEMS_Makefiles/Makefile.site @@ -0,0 +1,3 @@ +# +# Site-specific options/configuration goes here +# diff --git a/RTEMS_Makefiles/Makefile.zlib b/RTEMS_Makefiles/Makefile.zlib new file mode 100644 index 0000000..a6a54ca --- /dev/null +++ b/RTEMS_Makefiles/Makefile.zlib @@ -0,0 +1,13 @@ +# +# Configure/build/install the AVL library +# +include ../RTEMS_Makefiles/Makefile.common + +AR = $(AR_FOR_TARGET) cr +all: + ./configure \ + --prefix=$(exec_prefix) \ + --libdir=$(exec_prefix)/$(RTEMS_BSP)/lib \ + --includedir=$(exec_prefix)/$(RTEMS_BSP)/lib/include + make + make install diff --git a/SUPPORT b/SUPPORT new file mode 100644 index 0000000..083c1cb --- /dev/null +++ b/SUPPORT @@ -0,0 +1,22 @@ +# +# $Id$ +# + +On-Line Applications Research Corporation (OAR) offers support, +customization, and training for RTEMS. Custom RTEMS development services +includes porting RTEMS to new processors and the development of custom board +support packages and device drivers. In addition, OAR is available +to assist in the development of your real-time embedded application. + +For more information, email Mark Johannes at mark@OARcorp.com +or contact OAR at: + +On-Line Applications Research Corporation +4910-L Corporate Drive +Huntsville AL 35805 +Voice: (205) 722-9985 +Fax: (205 722-0985 + +RTEMS maintenance and development is funded solely by RTEMS users. +The future of RTEMS depends on its user base. + diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..0e8ae52 --- /dev/null +++ b/VERSION @@ -0,0 +1,7 @@ +# +# This file is automatically generated -- DO NOT EDIT!!! +# +# $Id$ +# + +Version 4.6.99.3 diff --git a/avl-1.4.0/AUTHORS b/avl-1.4.0/AUTHORS new file mode 100644 index 0000000..bcd66cd --- /dev/null +++ b/avl-1.4.0/AUTHORS @@ -0,0 +1 @@ +Ben Pfaff diff --git a/avl-1.4.0/COPYING b/avl-1.4.0/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/avl-1.4.0/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/avl-1.4.0/ChangeLog b/avl-1.4.0/ChangeLog new file mode 100644 index 0000000..e31a7c2 --- /dev/null +++ b/avl-1.4.0/ChangeLog @@ -0,0 +1,181 @@ +Sat Aug 7 18:32:43 1999 Ben Pfaff + + Implemented red-black tree library. + * Makefile.am: Add rb.c, rb.h in appropriate places. + * README: Update. + * rb.c: New file. + * rb.h: Ditto. + * avl.texinfo: Revised. + + * THANKS: Update. + * TODO: Update. + + * avl.c: In several places, replaced usage of comma operator with + a proper statement block. + * avlt.c: Ditto. + * avltr.c: Ditto. + + * avl.h: (AVL_TRAVERSER_INIT) New macro. + (avl_init_traverser) New function-like macro. + * avlt.h: (AVLT_TRAVERSER_INIT) New macro. + (avlt_init_traverser) New function-like macro. + * avltr.h: (AVLTR_TRAVERSER_INIT) New macro. + (avltr_init_traverser) New function-like macro. + * thread-test.c: (main) Use AVL_TRAVERSER_INIT. + + * Made version 1.4.0. + +Sat Jul 31 12:39:54 1999 Ben Pfaff + + * avl.texinfo: Update suggested by Jonathan Roy . + +Tue May 25 12:20:43 1999 Ben Pfaff + + * avl.c: (avl_delete) Make work properly for empty tree. Furrfu! + I should have noticed this before. + +Mon May 17 11:32:56 1999 Ben Pfaff + + * Makefile.am: Don't require texi2html. Use $(MAKEINFO) + variable. Thanks to Alexandre Oliva . + +Sat May 15 23:47:14 1999 Ben Pfaff + + * Updated copyright dates in several files. + + * Made version 1.3.0. + +Sat May 15 21:44:54 1999 Ben Pfaff + + * avl.c, avlt.c, avltr.c: In many places replaced assert (p) by + assert (p != NULL). Believe it or not, the former is not valid + ANSI C. + + Thanks to "Ficarra, David W, NNAD" for pointing + out the following two sets of bugs. + * avl.c: (avl_probe) Fix order of assignment and assertion. + * avlt.c: (avlt_walk, avlt_probe, avlt_find) Ditto. + * avltr.c: (avltr_probe, avltr_find) Ditto. + + * avlt.c: (avlt_find, avlt_delete) Check for empty tree. + * avltr.c: (avltr_probe) Ditto. + + * avl.c, avlt.c, avltr.c, thread-test.c: Change test code to only + perform a limited number of iterations to facilitate automated + testing. + + * avl.c: (avl_find_close) New function contributed by Thomas + Binder . + * avlt.c: (avlt_find_close) Ditto. + * avltr.c: (avltr_find_close) Ditto. + + * avl.texinfo: Update. + + libavl is now automake/autoconfiscated. Contributed by Alexandre + Oliva . + * AUTHORS: New file. + * Makefile: Now automake-generated. + * INSTALL: New file. + * Makefile.am: New file. + * Makefile.in: New file. + * THANKS: New file. + * config.h.in: New file. + * configure.in: New file. + * configure: New file. + * install-sh: New file. + * missing: New file. + * mkinstalldirs: New file. + * texinfo.tex: New file. + +Tue May 11 13:33:20 1999 Ben Pfaff + + * avl.texinfo: Fix typos. Thanks to onTy Toom + for pointing these out. + + * Made version 1.2.9. + +Sun Mar 14 13:39:16 1999 Ben Pfaff + + * avl.c: Fixed two occurrences of = that should have been == in + assertions. Thanks to Girish Zambre for + pointing out this problem. + + * avl.c, avlt.c, avltr.c: __attribute__ must follow declarations + for gcc 2.7.x. + + * Made version 1.2.8. + +Sun Mar 14 13:38:29 1999 Ben Pfaff + + * TODO: Add some comments from David Kastrup + . + + * Made version 1.2.7. + +Tue Jan 12 10:16:05 1999 Ben Pfaff + + * avl.texinfo: Add skip lists as alternative to AVL trees. Thanks + to Ron Pfeifle . + + * Made version 1.2.6. + +Sun Jan 10 15:37:57 1999 Ben Pfaff + + * avl.texinfo: Elaborated description of distinction between + threaded and unthreaded trees at request of several. + + * Made version 1.2.5. + +Sun Nov 22 13:36:58 1998 Ben Pfaff + + * avl.texinfo: Updates suggested by Jason Eisner + . + + * Made version 1.2.4. + +Sun Oct 18 10:26:08 1998 Ben Pfaff + + * TODO: New file. + + * avl.c: (xmalloc) Don't declare xmalloc if HAVE_XMALLOC is + defined. By default on error, print a message to stderr and exit, + rather than calling abort() as before. + * avlt.c: (xmalloc) Same. + * avltr.c: (xmalloc) Same. + + * Made version 1.2.3. + +Thu Sep 3 13:58:55 1998 Ben Pfaff + + * README: Update. + + * avl.c: (avl_delete) Minor efficiency fixes; removed redundant + comparison. + + * avlt.c: (avl_delete) Minor efficiency fix. + * avltr.c: (avl_delete) Same change. + + * avl.texi: Update. + + * Made version 1.2.2. + +Thu Jun 11 15:13:02 1998 Ben Pfaff + + * avl.c: Don't #define unused when PSPP is defined. + (force_avl_delete) Rename avl_force_delete. + + * avlt.c: (force_avlt_delete) Rename avlt_force_delete. + + * avltr.c: (force_avltr_delete) Rename avltr_force_delete. + + * Made version 1.2.1. + +Thu Jun 11 14:43:30 1998 Ben Pfaff + + * Version 1.2.0: First GNU release. + +---------------------------------------------------------------------- +Local Variables: +mode: change-log +version-control: never +End: diff --git a/avl-1.4.0/INSTALL b/avl-1.4.0/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/avl-1.4.0/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/avl-1.4.0/Makefile.am b/avl-1.4.0/Makefile.am new file mode 100644 index 0000000..aa4754d --- /dev/null +++ b/avl-1.4.0/Makefile.am @@ -0,0 +1,28 @@ +AUTOMAKE_OPTIONS = gnits + +include_HEADERS = avl.h avlt.h avltr.h rb.h + +lib_LIBRARIES = libavl.a +libavl_a_SOURCES = avl.c avlt.c avltr.c rb.c + +info_TEXINFOS = avl.texinfo +noinst_DATA = avl.html avl.text + +avl.text : avl.texinfo + $(MAKEINFO) $(srcdir)/avl.texinfo -o avl.text --no-headers + +avl.html: avl.texinfo + -texi2html -monolithic $(srcdir)/avl.texinfo + +EXTRA_PROGRAMS = avl-test avlt-test avltr-test thread-test rb-test +DISTCLEANFILES = $(EXTRA_PROGRAMS) $(BUILT_SOURCES) + +BUILT_SOURCES = avl-test.c avlt-test.c avltr-test.c rb-test.c + +TESTS = avl-test avlt-test avltr-test thread-test rb-test +avl-test.c avlt-test.c avltr-test.c rb-test.c: + rm -f $@ + echo '#define SELF_TEST 1' > $@ + echo '#include "'`echo $@ | sed s/-test//`'"' >> $@ + +thread_test_LDADD = libavl.a diff --git a/avl-1.4.0/Makefile.in b/avl-1.4.0/Makefile.in new file mode 100644 index 0000000..2d041aa --- /dev/null +++ b/avl-1.4.0/Makefile.in @@ -0,0 +1,572 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ + +AUTOMAKE_OPTIONS = gnits + +include_HEADERS = avl.h avlt.h avltr.h rb.h + +lib_LIBRARIES = libavl.a +libavl_a_SOURCES = avl.c avlt.c avltr.c rb.c + +info_TEXINFOS = avl.texinfo +noinst_DATA = avl.html avl.text + +EXTRA_PROGRAMS = avl-test avlt-test avltr-test thread-test rb-test +DISTCLEANFILES = $(EXTRA_PROGRAMS) $(BUILT_SOURCES) + +BUILT_SOURCES = avl-test.c avlt-test.c avltr-test.c rb-test.c + +TESTS = avl-test avlt-test avltr-test thread-test rb-test + +thread_test_LDADD = libavl.a +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(lib_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libavl_a_LIBADD = +libavl_a_OBJECTS = avl.o avlt.o avltr.o rb.o +AR = ar +avl_test_SOURCES = avl-test.c +avl_test_OBJECTS = avl-test.o +avl_test_LDADD = $(LDADD) +avl_test_DEPENDENCIES = +avl_test_LDFLAGS = +avlt_test_SOURCES = avlt-test.c +avlt_test_OBJECTS = avlt-test.o +avlt_test_LDADD = $(LDADD) +avlt_test_DEPENDENCIES = +avlt_test_LDFLAGS = +avltr_test_SOURCES = avltr-test.c +avltr_test_OBJECTS = avltr-test.o +avltr_test_LDADD = $(LDADD) +avltr_test_DEPENDENCIES = +avltr_test_LDFLAGS = +thread_test_SOURCES = thread-test.c +thread_test_OBJECTS = thread-test.o +thread_test_DEPENDENCIES = libavl.a +thread_test_LDFLAGS = +rb_test_SOURCES = rb-test.c +rb_test_OBJECTS = rb-test.o +rb_test_LDADD = $(LDADD) +rb_test_DEPENDENCIES = +rb_test_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +TEXI2DVI = texi2dvi +INFO_DEPS = avl.info +DVIS = avl.dvi +TEXINFOS = avl.texinfo +DATA = $(noinst_DATA) + +HEADERS = $(include_HEADERS) + +DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ +Makefile.in NEWS THANKS TODO aclocal.m4 configure configure.in \ +install-sh missing mkinstalldirs texinfo.tex + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +SOURCES = $(libavl_a_SOURCES) avl-test.c avlt-test.c avltr-test.c thread-test.c rb-test.c +OBJECTS = $(libavl_a_OBJECTS) avl-test.o avlt-test.o avltr-test.o thread-test.o rb-test.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .dvi .info .o .ps .s .texi .texinfo .txi +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnits --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-libLIBRARIES: + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +distclean-libLIBRARIES: + +maintainer-clean-libLIBRARIES: + +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LIBRARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +libavl.a: $(libavl_a_OBJECTS) $(libavl_a_DEPENDENCIES) + -rm -f libavl.a + $(AR) cru libavl.a $(libavl_a_OBJECTS) $(libavl_a_LIBADD) + $(RANLIB) libavl.a + +avl-test: $(avl_test_OBJECTS) $(avl_test_DEPENDENCIES) + @rm -f avl-test + $(LINK) $(avl_test_LDFLAGS) $(avl_test_OBJECTS) $(avl_test_LDADD) $(LIBS) + +avlt-test: $(avlt_test_OBJECTS) $(avlt_test_DEPENDENCIES) + @rm -f avlt-test + $(LINK) $(avlt_test_LDFLAGS) $(avlt_test_OBJECTS) $(avlt_test_LDADD) $(LIBS) + +avltr-test: $(avltr_test_OBJECTS) $(avltr_test_DEPENDENCIES) + @rm -f avltr-test + $(LINK) $(avltr_test_LDFLAGS) $(avltr_test_OBJECTS) $(avltr_test_LDADD) $(LIBS) + +thread-test: $(thread_test_OBJECTS) $(thread_test_DEPENDENCIES) + @rm -f thread-test + $(LINK) $(thread_test_LDFLAGS) $(thread_test_OBJECTS) $(thread_test_LDADD) $(LIBS) + +rb-test: $(rb_test_OBJECTS) $(rb_test_DEPENDENCIES) + @rm -f rb-test + $(LINK) $(rb_test_LDFLAGS) $(rb_test_OBJECTS) $(rb_test_LDADD) $(LIBS) + +avl.info: avl.texinfo +avl.dvi: avl.texinfo + + +DVIPS = dvips + +.texi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texi.dvi: + TEXINPUTS=.:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.texi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.texinfo.dvi: + TEXINPUTS=.:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi.info: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` + +.txi.dvi: + TEXINPUTS=.:$$TEXINPUTS \ + MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + +.txi: + @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] + cd $(srcdir) \ + && $(MAKEINFO) `echo $< | sed 's,.*/,,'` +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + d=$(srcdir); \ + for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ + if test -f $$d/$$ifile; then \ + echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \ + $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\ + done; \ + else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ + ii=yes; \ + else ii=; fi; \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + test -z "$ii" \ + || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \ + done + @$(NORMAL_UNINSTALL) + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ + done + +dist-info: $(INFO_DEPS) + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + d=$(srcdir); \ + for file in `cd $$d && eval echo $$base*`; do \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f avl.aux avl.cp avl.cps avl.dvi avl.fn avl.fns avl.ky avl.kys \ + avl.ps avl.log avl.pg avl.toc avl.tp avl.tps avl.vr avl.vrs \ + avl.op avl.tr avl.cv avl.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + cd $(srcdir) && for i in $(INFO_DEPS); do \ + rm -f $$i; \ + if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ + rm -f $$i-[0-9]*; \ + fi; \ + done + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + @if sed 15q $(srcdir)/NEWS | fgrep -e "$(VERSION)" > /dev/null; then :; else \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1; \ + fi + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info + +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info-am: $(INFO_DEPS) +info: info-am +dvi-am: $(DVIS) +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLIBRARIES +install-exec: install-exec-am + +install-data-am: install-info-am install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLIBRARIES uninstall-info \ + uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(INFO_DEPS) $(LIBRARIES) $(DATA) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(infodir) \ + $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-libLIBRARIES mostlyclean-compile \ + mostlyclean-aminfo mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLIBRARIES clean-compile clean-aminfo clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLIBRARIES distclean-compile distclean-aminfo \ + distclean-tags distclean-generic clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-libLIBRARIES \ + maintainer-clean-compile maintainer-clean-aminfo \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-libLIBRARIES distclean-libLIBRARIES \ +clean-libLIBRARIES maintainer-clean-libLIBRARIES uninstall-libLIBRARIES \ +install-libLIBRARIES mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile install-info-am uninstall-info \ +mostlyclean-aminfo distclean-aminfo clean-aminfo \ +maintainer-clean-aminfo uninstall-includeHEADERS install-includeHEADERS \ +tags mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \ +distdir check-TESTS info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +avl.text : avl.texinfo + $(MAKEINFO) $(srcdir)/avl.texinfo -o avl.text --no-headers + +avl.html: avl.texinfo + -texi2html -monolithic $(srcdir)/avl.texinfo +avl-test.c avlt-test.c avltr-test.c rb-test.c: + rm -f $@ + echo '#define SELF_TEST 1' > $@ + echo '#include "'`echo $@ | sed s/-test//`'"' >> $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/avl-1.4.0/NEWS b/avl-1.4.0/NEWS new file mode 100644 index 0000000..ecdc25d --- /dev/null +++ b/avl-1.4.0/NEWS @@ -0,0 +1,98 @@ +libavl NEWS -- history of user-visible changes. +Time-stamp: <1999-08-15 21:52:15 blp> +Copyright (C) 1998, 1999 Free Software Foundation, Inc. +See the end for copying conditions. + +Please send PSPP bug reports to bug-gnu-pspp@gnu.org. + +Changes for version 1.4.0: + + Implemented red-black trees. + + New functions, *_init_traverser(), to initialize a *_traverser + structure. New macros *_TRAVERSER_INIT for same purpose. + +Changes for version 1.3.0: + + Now uses Autoconf and Automake to configure. Thanks to Alexandre + Oliva . + + New: automated testing with `make check'. + + Fixes for strict ANSI C compliance. + + Fixed useless assertions. Fixed bug regarding empty trees for some + operations with threaded and right-threaded trees. Thanks to + "Ficarra, David W, NNAD" . + + New functions, avl*_find_close(), for finding a node in the tree + with a value close to a specified value. See documentation and + source code for more details. Thanks to Thomas Binder + . + +Changes for version 1.2.9: + + Fix typos in documentation. Thanks to onTy Toom . + +Changes for version 1.2.8: + + Fixed typos in assertions. Thanks to Girish Zambre + . + + Better support for gcc 2.7.x. + +Changes for versions 1.2.4, 1.2.5, 1.2.6, 1.2.7: + + Documentation updates. Thanks to Ron Pfeifle , + Jason Eisner , and others. + +Changes for version 1.2.3: + + The library's allocation function xmalloc() can easily be overridden + by the library's user. Thanks to Clayton Weaver + for the idea. + +Changes for version 1.2.2: + + Documentation fixes. Thanks to Akim Demaille + for pointing these out. + +Changes for version 1.2.1: + + Bug fixes. + +Changes for version 1.2.0: + + Implemented right-threaded trees. + + Added functions to convert among AVL tree types. + + First GNU release. + +Changes for version 1.1.0: + + Implemented threaded trees. + +Changes for version 1.0: + + First public release. + +---------------------------------------------------------------------- +Copyright information: + +Copyright (C) 1998, 1999 Free Software Foundation, Inc. + + Permission is granted to anyone to make or distribute verbatim + copies of this document as received, in any medium, provided that + the copyright notice and this permission notice are preserved, thus + giving the recipient permission to redistribute in turn. + + Permission is granted to distribute modified versions of this + document, or of portions of it, under the above conditions, + provided also that they carry prominent notices stating who last + changed them. + +Local variables: +version-control: never +mode: indented-text +end: diff --git a/avl-1.4.0/README b/avl-1.4.0/README new file mode 100644 index 0000000..46ed6e4 --- /dev/null +++ b/avl-1.4.0/README @@ -0,0 +1,37 @@ +This is version 1.4 of libavl, a library in ANSI C for manipulation of +balanced binary trees. Functions for use with three varieties of AVL +tree and one type of red-black tree are included. There is full +documentation, including an explanation of what AVL and red-black +trees are and why you'd use them, in Texinfo, Info, HTML, and plain +text formats. + +The library is divided into three parts, described in more detail +below. You need only include the files for the types of trees that +you are using. + + - avl.h, avl.c: Unthreaded AVL tree library. + - avlt.h, avlt.c: Threaded AVL tree library. + - avltr.h, avltr.c: Right-threaded AVL tree library. + - rb.h, rb.c: Unthreaded red-black tree library. + +Each .c file in the library has a self-test routine built in, which +can be invoked by compiling it with SELF_TEST set to 1. In addition, +there is a separate program thread-test.c that tests the functions +that convert among types of AVL trees. To automatically run these +tests, type `make check' after you have configured the library with +`configure'. For more information on how to configure and compile +libavl, see the file INSTALL included in this directory. + +libavl is licensed under the GNU General Public License (GPL), which +should be included in this directory in file COPYING. This is not the +same as GNU Library General Public License (LGPL). Please read the +license and become familiar with its terms. + +Please send bug reports and enhancement requests for libavl to Ben +Pfaff . + +Share and enjoy! + +Local variables: +mode: text +End: diff --git a/avl-1.4.0/THANKS b/avl-1.4.0/THANKS new file mode 100644 index 0000000..cd9319a --- /dev/null +++ b/avl-1.4.0/THANKS @@ -0,0 +1,15 @@ +Thanks to... + +* Donald Knuth for _The Art of Computer Programming_. + +* Thomas Cormen, Charles Leiserson, and Ron Rivest for _Introduction + to Algorithms_. + +* David MacKenzie for writing Autoconf, the automatic configuration + tool. + +* David MacKenzie and Tom Tromey for writing Automake, the tool for + generating `Makefile's. + +* All those who have contributed bug reports and enhancements. You + can find them listed individually in the NEWS and the ChangeLog. diff --git a/avl-1.4.0/TODO b/avl-1.4.0/TODO new file mode 100644 index 0000000..0231395 --- /dev/null +++ b/avl-1.4.0/TODO @@ -0,0 +1,92 @@ +TODO +---- + +* Write `bare' no-rebalancing version for comparison purposes. + +* In avl_delete's D9 it may be faster to move the data instead of + moving around all the pointers. Consider the situation carefully. + +* avl_traverse_{fwd,rev}; avl_find_traverse + +* Generalized testing framework; for instance, could compare with + kazlib and avllib implementations. + +* Merge algorithm paper into documentation. + +---------------------------------------------------------------------- +From: Akim Demaille +Subject: Re: libavl +To: pfaffben@pilot.msu.edu +Date: 25 Sep 1998 16:04:03 +0200 + + +Sorry for the delays... + +Ben Pfaff writes: + +> Akim Demaille writes: +> +> And finaly, for the application I want to make of libavl, I have +> sometimes to merge two avls, say the second into the first, while +> specifying, when conflict, whether it is always the first or the +> second that wins. +> +> I can easily make this using your api, nevertheless, I wanted to ask +> you whether you know none brute-force approaches, or even whether +> this kind of features might appear in the future. +> +> Knuth describes an elegant algorithm for merging two avls, but it only +> works if all the values in one of them is smaller than all the values +> in the other. +> +> If you do think of a clever algorithm for doing this, please let me +> know and I'll incorporate it into the API. + +I know none. but looking on the web, I found one in haskell :) +I didn't look whether it was smart or not. + +http://www.cs.chalmers.se/pub/haskell/library/avl-tree.lgs + +There is not much material. I think comp.compiler is a good place to +ask for an algorithm... + +Akim +---------------------------------------------------------------------- +From: David Kastrup +Subject: Re: Your AVL tree page +To: pfaffben@pilot.msu.edu +Date: Mon, 23 Nov 1998 18:38:55 +0100 + + From: Ben Pfaff + Date: 23 Nov 1998 12:12:31 -0500 + + David Kastrup writes: + + You might want to take a look at the texts at + http://www-lsi.upc.es/www/dept/techreps/1998.html + + In particular the paper + http://www-lsi.upc.es/dept/techreps/ps/R98-12.ps.gz + + might be interesting, as it gives an AVL-tree mechanism for + multi-threaded, distributed access. + + Thanks for the pointers. It seems that connectivity to that machine + is really slow from here, at least right now, so I'll try to take a + look at them a little later. Currently there is no multithread + support in libavl, but it might be nice to add it later. + +Well, the reference will probably not be what you think it is. It is +intended to not properly balance the tree during the access when that +would mean locking the entire tree. Instead, it does only local +corrections that eventually probagate to the top. One can also let a +"garbage collect" thread run that will optimize the data structures +at idle times, but will let them deteriorate a bit rather than fix +them up properly under stress. This is, of course, especially +interesting for internal data structures of an operating system, where +full balancing at the time of access will slow operations down, but +there will be idle times when balancing can occur without overhead. + +David Kastrup Phone: +49-234-700-5570 +Email: dak@neuroinformatik.ruhr-uni-bochum.de Fax: +49-234-709-4209 +Institut für Neuroinformatik, Universitätsstr. 150, 44780 Bochum, Germany diff --git a/avl-1.4.0/aclocal.m4 b/avl-1.4.0/aclocal.m4 new file mode 100644 index 0000000..9f8add8 --- /dev/null +++ b/avl-1.4.0/aclocal.m4 @@ -0,0 +1,104 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + diff --git a/avl-1.4.0/avl.c b/avl-1.4.0/avl.c new file mode 100644 index 0000000..82cdb6e --- /dev/null +++ b/avl-1.4.0/avl.c @@ -0,0 +1,1154 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avl.c in libavl. */ + +#if HAVE_CONFIG_H +#include +#endif +#if PSPP +#include "common.h" +#include "arena.h" +#define HAVE_XMALLOC 1 +#endif +#if SELF_TEST +#include +#include +#endif +#include +#include +#include +#include "avl.h" + +#if !PSPP && !__GCC__ +#define inline +#endif + +#if !PSPP +#if __GNUC__ >= 2 +#define unused __attribute__ ((unused)) +#else +#define unused +#endif +#endif + +#ifdef HAVE_XMALLOC +void *xmalloc (size_t); +#else /* !HAVE_XMALLOC */ +/* Allocates SIZE bytes of space using malloc(). Aborts if out of + memory. */ +static void * +xmalloc (size_t size) +{ + void *vp; + + if (size == 0) + return NULL; + vp = malloc (size); + + assert (vp != NULL); + if (vp == NULL) + { + fprintf (stderr, "virtual memory exhausted\n"); + exit (EXIT_FAILURE); + } + return vp; +} +#endif /* !HAVE_XMALLOC */ + +/* Creates an AVL tree in arena OWNER (which can be NULL). The arena + is owned by the caller, not by the AVL tree. CMP is a order + function for the data to be stored in the tree. PARAM is arbitrary + data that becomes an argument to the comparison function. */ +avl_tree * +avl_create (MAYBE_ARENA avl_comparison_func cmp, void *param) +{ + avl_tree *tree; + + assert (cmp != NULL); +#if PSPP + if (owner) + tree = arena_alloc (owner, sizeof (avl_tree)); + else +#endif + tree = xmalloc (sizeof (avl_tree)); + +#if PSPP + tree->owner = owner; +#endif + tree->root.link[0] = NULL; + tree->root.link[1] = NULL; + tree->cmp = cmp; + tree->count = 0; + tree->param = param; + + return tree; +} + +/* Destroy tree TREE. Function FREE_FUNC is called for every node in + the tree as it is destroyed. + + No effect if the tree has an arena owner and free_func is NULL. + The caller owns the arena and must destroy it itself. + + Do not attempt to reuse the tree after it has been freed. Create a + new one. */ +void +avl_destroy (avl_tree *tree, avl_node_func free_func) +{ + assert (tree != NULL); + +#if PSPP + if (free_func || tree->owner == NULL) +#endif + { + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal). */ + + /* T1. */ + avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + avl_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + while (p != NULL) + { + /* T3. */ + ab[ap] = 0; + an[ap++] = p; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if (ab[ap] == 0) + { + ab[ap++] = 1; + p = p->link[1]; + break; + } + + if (free_func) + free_func (p->data, tree->param); +#if PSPP + if (tree->owner == NULL) +#endif + free (p); + } + } + } + + done: +#if PSPP + if (tree->owner == NULL) +#endif + free (tree); +} + +/* avl_destroy() with FREE_FUNC hardcoded as free(). */ +void +avl_free (avl_tree *tree) +{ + avl_destroy (tree, (avl_node_func) free); +} + +/* Return the number of nodes in TREE. */ +int +avl_count (const avl_tree *tree) +{ + assert (tree != NULL); + return tree->count; +} + +/* Allocates room for a new avl_node in arena OWNER, or using + xmalloc() if OWNER is NULL. */ +#if PSPP +static inline avl_node * +new_node (arena **owner) +{ + if (owner != NULL) + return arena_alloc (owner, sizeof (avl_node)); + else + return xmalloc (sizeof (avl_node)); +} +#else +static inline avl_node * +new_node (void) +{ + return xmalloc (sizeof (avl_node)); +} + +#define new_node(owner) \ + new_node () +#endif + +/* Copy the contents of TREE to a new tree in arena OWNER. If COPY is + non-NULL, then each data item is passed to function COPY, and the + return values are inserted into the new tree; otherwise, the items + are copied verbatim from the old tree to the new tree. Returns the + new tree. */ +avl_tree * +avl_copy (MAYBE_ARENA const avl_tree *tree, avl_copy_func copy) +{ + /* This is a combination of Knuth's Algorithm 2.3.1C (copying a + binary tree) and Algorithm 2.3.1T as modified by exercise 12 + (preorder traversal). */ + + avl_tree *new_tree; + + /* PT1. */ + const avl_node *pa[AVL_MAX_HEIGHT]; /* Stack PA: nodes. */ + const avl_node **pp = pa; /* Stack PA: stack pointer. */ + const avl_node *p = &tree->root; + + /* QT1. */ + avl_node *qa[AVL_MAX_HEIGHT]; /* Stack QA: nodes. */ + avl_node **qp = qa; /* Stack QA: stack pointer. */ + avl_node *q; + + assert (tree != NULL); +#if PSPP + new_tree = avl_create (owner, tree->cmp, tree->param); +#else + new_tree = avl_create (tree->cmp, tree->param); +#endif + new_tree->count = tree->count; + q = &new_tree->root; + + for (;;) + { + /* C4. */ + if (p->link[0] != NULL) + { + avl_node *r = new_node (owner); + r->link[0] = r->link[1] = NULL; + q->link[0] = r; + } + + /* C5: Find preorder successors of P and Q. */ + goto start; + for (;;) + { + /* PT2. */ + while (p != NULL) + { + goto escape; + start: + /* PT3. */ + *pp++ = p; + *qp++ = q; + p = p->link[0]; + q = q->link[0]; + } + + /* PT4. */ + if (pp == pa) + { + assert (qp == qa); + return new_tree; + } + + p = *--pp; + q = *--qp; + + /* PT5. */ + p = p->link[1]; + q = q->link[1]; + } + escape: + + /* C2. */ + if (p->link[1]) + { + avl_node *r = new_node (owner); + r->link[0] = r->link[1] = NULL; + q->link[1] = r; + } + + /* C3. */ + q->bal = p->bal; + if (copy == NULL) + q->data = p->data; + else + q->data = copy (p->data, tree->param); + } +} + +/* Walk tree TREE in inorder, calling WALK_FUNC at each node. Passes + PARAM to WALK_FUNC. */ +void +avl_walk (const avl_tree *tree, avl_node_func walk_func, void *param) +{ + /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ + assert (tree && walk_func); + + { + /* T1. */ + const avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + const avl_node **ap = an; /* Stack A: stack pointer. */ + const avl_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + while (p != NULL) + { + /* T3. */ + *ap++ = p; + p = p->link[0]; + } + + /* T4. */ + if (ap == an) + return; + p = *--ap; + + /* T5. */ + walk_func (p->data, param); + p = p->link[1]; + } + } +} + +/* Each call to this function for a given TREE and TRAV return the + next item in the tree in inorder. Initialize the first element of + TRAV (init) to 0 before calling the first time. Returns NULL when + out of elements. */ +void * +avl_traverse (const avl_tree *tree, avl_traverser *trav) +{ + assert (tree && trav); + + /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ + if (trav->init == 0) + { + /* T1. */ + trav->init = 1; + trav->nstack = 0; + trav->p = tree->root.link[0]; + } + else + /* T5. */ + trav->p = trav->p->link[1]; + + for (;;) + { + /* T2. */ + while (trav->p != NULL) + { + /* T3. */ + trav->stack[trav->nstack++] = trav->p; + trav->p = trav->p->link[0]; + } + + /* T4. */ + if (trav->nstack == 0) + { + trav->init = 0; + return NULL; + } + trav->p = trav->stack[--trav->nstack]; + + /* T5. */ + return trav->p->data; + } +} + +/* Search TREE for an item matching ITEM. If found, returns a pointer + to the address of the item. If none is found, ITEM is inserted + into the tree, and a pointer to the address of ITEM is returned. + In either case, the pointer returned can be changed by the caller, + or the returned data item can be directly edited, but the key data + in the item must not be changed. */ +void ** +avl_probe (avl_tree *tree, void *item) +{ + /* Uses Knuth's Algorithm 6.2.3A (balanced tree search and + insertion), but caches results of comparisons. In empirical + tests this eliminates about 25% of the comparisons seen under + random insertions. */ + + /* A1. */ + avl_node *t; + avl_node *s, *p, *q, *r; + + assert (tree != NULL); + t = &tree->root; + s = p = t->link[0]; + + if (s == NULL) + { + tree->count++; + assert (tree->count == 1); + q = t->link[0] = new_node (tree->owner); + q->data = item; + q->link[0] = q->link[1] = NULL; + q->bal = 0; + return &q->data; + } + + for (;;) + { + /* A2. */ + int diff = tree->cmp (item, p->data, tree->param); + + /* A3. */ + if (diff < 0) + { + p->cache = 0; + q = p->link[0]; + if (q == NULL) + { + p->link[0] = q = new_node (tree->owner); + break; + } + } + /* A4. */ + else if (diff > 0) + { + p->cache = 1; + q = p->link[1]; + if (q == NULL) + { + p->link[1] = q = new_node (tree->owner); + break; + } + } + else + /* A2. */ + return &p->data; + + /* A3, A4. */ + if (q->bal != 0) + t = p, s = q; + p = q; + } + + /* A5. */ + tree->count++; + q->data = item; + q->link[0] = q->link[1] = NULL; + q->bal = 0; + + /* A6. */ + r = p = s->link[(int) s->cache]; + while (p != q) + { + p->bal = p->cache * 2 - 1; + p = p->link[(int) p->cache]; + } + + /* A7. */ + if (s->cache == 0) + { + /* a = -1. */ + if (s->bal == 0) + { + s->bal = -1; + return &q->data; + } + else if (s->bal == +1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == -1); + if (r->bal == -1) + { + /* A8. */ + p = r; + s->link[0] = r->link[1]; + r->link[1] = s; + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == +1); + p = r->link[1]; + r->link[1] = p->link[0]; + p->link[0] = r; + s->link[0] = p->link[1]; + p->link[1] = s; + if (p->bal == -1) + s->bal = 1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == +1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + } + } + else + { + /* a == +1. */ + if (s->bal == 0) + { + s->bal = 1; + return &q->data; + } + else if (s->bal == -1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == +1); + if (r->bal == +1) + { + /* A8. */ + p = r; + s->link[1] = r->link[0]; + r->link[0] = s; + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == -1); + p = r->link[0]; + r->link[0] = p->link[1]; + p->link[1] = r; + s->link[1] = p->link[0]; + p->link[0] = s; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = 1; + } + p->bal = 0; + } + } + + /* A10. */ + if (t != &tree->root && s == t->link[1]) + t->link[1] = p; + else + t->link[0] = p; + + return &q->data; +} + +/* Search TREE for an item matching ITEM, and return it if found. */ +void * +avl_find (const avl_tree *tree, const void *item) +{ + const avl_node *p; + + assert (tree != NULL); + for (p = tree->root.link[0]; p; ) + { + int diff = tree->cmp (item, p->data, tree->param); + + if (diff < 0) + p = p->link[0]; + else if (diff > 0) + p = p->link[1]; + else + return p->data; + } + + return NULL; +} + +/* Search TREE for an item close to the value of ITEM, and return it. + This function will return a null pointer only if TREE is empty. */ +void * +avl_find_close (const avl_tree *tree, const void *item) +{ + const avl_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p == NULL) + return NULL; + + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + int t; + + if (diff < 0) + t = 0; + else if (diff > 0) + t = 1; + else + return p->data; + + if (p->link[t]) + p = p->link[t]; + else + return p->data; + } +} + +/* Searches AVL tree TREE for an item matching ITEM. If found, the + item is removed from the tree and the actual item found is returned + to the caller. If no item matching ITEM exists in the tree, + returns NULL. */ +void * +avl_delete (avl_tree *tree, const void *item) +{ + /* Uses my Algorithm D, which can be found at + http://www.msu.edu/user/pfaffben/avl. Algorithm D is based on + Knuth's Algorithm 6.2.2D (Tree deletion) and 6.2.3A (Balanced + tree search and insertion), as well as the notes on pages 465-466 + of Vol. 3. */ + + /* D1. */ + avl_node *pa[AVL_MAX_HEIGHT]; /* Stack P: Nodes. */ + char a[AVL_MAX_HEIGHT]; /* Stack P: Bits. */ + int k = 1; /* Stack P: Pointer. */ + + avl_node **q; + avl_node *p; + + assert (tree != NULL); + + a[0] = 0; + pa[0] = &tree->root; + p = tree->root.link[0]; + for (;;) + { + /* D2. */ + int diff; + + if (p == NULL) + return NULL; + + diff = tree->cmp (item, p->data, tree->param); + if (diff == 0) + break; + + /* D3, D4. */ + pa[k] = p; + if (diff < 0) + { + p = p->link[0]; + a[k] = 0; + } + else if (diff > 0) + { + p = p->link[1]; + a[k] = 1; + } + k++; + } + tree->count--; + + item = p->data; + + /* D5. */ + q = &pa[k - 1]->link[(int) a[k - 1]]; + if (p->link[1] == NULL) + { + *q = p->link[0]; + if (*q) + (*q)->bal = 0; + } + else + { + /* D6. */ + avl_node *r = p->link[1]; + if (r->link[0] == NULL) + { + r->link[0] = p->link[0]; + *q = r; + r->bal = p->bal; + a[k] = 1; + pa[k++] = r; + } + else + { + /* D7. */ + avl_node *s = r->link[0]; + int l = k++; + + a[k] = 0; + pa[k++] = r; + + /* D8. */ + while (s->link[0] != NULL) + { + r = s; + s = r->link[0]; + a[k] = 0; + pa[k++] = r; + } + + /* D9. */ + a[l] = 1; + pa[l] = s; + s->link[0] = p->link[0]; + r->link[0] = s->link[1]; + s->link[1] = p->link[1]; + s->bal = p->bal; + *q = s; + } + } + +#if PSPP + if (tree->owner == NULL) +#endif + free (p); + + assert (k > 0); + /* D10. */ + while (--k) + { + avl_node *s = pa[k], *r; + + if (a[k] == 0) + { + /* D10. */ + if (s->bal == -1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = 1; + break; + } + + assert (s->bal == +1); + r = s->link[1]; + + assert (r != NULL); + if (r->bal == 0) + { + /* D11. */ + s->link[1] = r->link[0]; + r->link[0] = s; + r->bal = -1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == +1) + { + /* D12. */ + s->link[1] = r->link[0]; + r->link[0] = s; + s->bal = r->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = r; + } + else + { + /* D13. */ + assert (r->bal == -1); + p = r->link[0]; + r->link[0] = p->link[1]; + p->link[1] = r; + s->link[1] = p->link[0]; + p->link[0] = s; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = +1; + } + p->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = p; + } + } + else + { + assert (a[k] == 1); + + /* D10. */ + if (s->bal == +1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = -1; + break; + } + + assert (s->bal == -1); + r = s->link[0]; + + if (r == NULL || r->bal == 0) + { + /* D11. */ + s->link[0] = r->link[1]; + r->link[1] = s; + r->bal = 1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == -1) + { + /* D12. */ + s->link[0] = r->link[1]; + r->link[1] = s; + s->bal = r->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = r; + } + else if (r->bal == +1) + { + /* D13. */ + p = r->link[1]; + r->link[1] = p->link[0]; + p->link[0] = r; + s->link[0] = p->link[1]; + p->link[1] = s; + if (p->bal == -1) + s->bal = 1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == 1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = p; + } + } + } + + return (void *) item; +} + +/* Inserts ITEM into TREE. Returns NULL if the item was inserted, + otherwise a pointer to the duplicate item. */ +void * +avl_insert (avl_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avl_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +/* If ITEM does not exist in TREE, inserts it and returns NULL. If a + matching item does exist, it is replaced by ITEM and the item + replaced is returned. The caller is responsible for freeing the + item returned. */ +void * +avl_replace (avl_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avl_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} + +/* Delete ITEM from TREE when you know that ITEM must be in TREE. For + debugging purposes. */ +void * +(avl_force_delete) (avl_tree *tree, void *item) +{ + void *found = avl_delete (tree, item); + assert (found != NULL); + return found; +} + +#if SELF_TEST + +/* Used to flag delayed aborting. */ +int done = 0; + +/* Print the structure of node NODE of an avl tree, which is LEVEL + levels from the top of the tree. Uses different delimiters to + visually distinguish levels. */ +void +print_structure (avl_node *node, int level) +{ + char lc[] = "([{`/"; + char rc[] = ")]}'\\"; + + assert (level <= 10); + + if (node == NULL) + { + printf (" nil"); + return; + } + printf (" %c%d", lc[level % 5], (int) node->data); + if (node->link[0] || node->link[1]) + print_structure (node->link[0], level + 1); + if (node->link[1]) + print_structure (node->link[1], level + 1); + printf ("%c", rc[level % 5]); +} + +/* Compare two integers A and B and return a strcmp()-type result. */ +int +compare_ints (const void *a, const void *b, void *param unused) +{ + return ((int) a) - ((int) b); +} + +/* Print the value of integer A. */ +void +print_int (void *a, void *param unused) +{ + printf (" %d", (int) a); +} + +/* Linearly print contents of TREE. */ +void +print_contents (avl_tree *tree) +{ + avl_walk (tree, print_int, NULL); + printf ("\n"); +} + +/* Examine NODE in a avl tree. *COUNT is increased by the number of + nodes in the tree, including the current one. If the node is the + root of the tree, PARENT should be INT_MIN, otherwise it should be + the parent node value. DIR is the direction that the current node + is linked from the parent: -1 for left child, +1 for right child; + it is not used if PARENT is INT_MIN. Returns the height of the + tree rooted at NODE. */ +int +recurse_tree (avl_node *node, int *count, int parent, int dir) +{ + if (node) + { + int d = (int) node->data; + int nl = node->link[0] ? recurse_tree (node->link[0], count, d, -1) : 0; + int nr = node->link[1] ? recurse_tree (node->link[1], count, d, 1) : 0; + (*count)++; + + if (nr - nl != node->bal) + { + printf (" Node %d is unbalanced: right height=%d, left height=%d, " + "difference=%d, but balance factor=%d.\n", + d, nr, nl, nr - nl, node->bal); + done = 1; + } + + if (parent != INT_MIN) + { + assert (dir == -1 || dir == +1); + if (dir == -1 && d > parent) + { + printf (" Node %d is smaller than its left child %d.\n", + parent, d); + done = 1; + } + else if (dir == +1 && d < parent) + { + printf (" Node %d is larger than its right child %d.\n", + parent, d); + done = 1; + } + } + assert (node->bal >= -1 && node->bal <= 1); + return 1 + (nl > nr ? nl : nr); + } + else return 0; +} + +/* Check that everything about TREE is kosher. */ +void +verify_tree (avl_tree *tree) +{ + int count = 0; + recurse_tree (tree->root.link[0], &count, INT_MIN, 0); + if (count != tree->count) + { + printf (" Tree has %d nodes, but tree count is %d.\n", + count, tree->count); + done = 1; + } + if (done) + abort (); +} + +/* Arrange the N elements of ARRAY in random order. */ +void +shuffle (int *array, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + int j = i + rand () % (n - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Compares avl trees rooted at A and B, making sure that they are + identical. */ +void +compare_trees (avl_node *a, avl_node *b) +{ + if (a == NULL || b == NULL) + { + assert (a == NULL && b == NULL); + return; + } + if (a->data != b->data || a->bal != b->bal + || ((a->link[0] != NULL) ^ (b->link[0] != NULL)) + || ((a->link[1] != NULL) ^ (b->link[1] != NULL))) + { + printf (" Copied nodes differ: %d b=%d a->bal=%d b->bal=%d a:", + (int) a->data, (int) b->data, a->bal, b->bal); + if (a->link[0]) + printf ("l"); + if (a->link[1]) + printf ("r"); + printf (" b:"); + if (b->link[0]) + printf ("l"); + if (b->link[1]) + printf ("r"); + printf ("\n"); + abort (); + } + if (a->link[0] != NULL) + compare_trees (a->link[0], b->link[0]); + if (a->link[1] != NULL) + compare_trees (a->link[1], b->link[1]); +} + +/* Simple stress test procedure for the AVL tree routines. Does the + following: + + * Generate a random number seed. By default this is generated from + the current time. You can also pass a seed value on the command + line if you want to test the same case. The seed value is + displayed. + + * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 + into it, in random order. Verify the tree structure after each + insertion. + + * Remove each integer from the tree, in a different random order. + After each deletion, verify the tree structure; also, make a copy + of the tree into a new tree, verify the copy and compare it to the + original, then destroy the copy. + + * Destroy the tree, increment the random seed value, and start over. + + If you make any modifications to the avl tree routines, then you + might want to insert some calls to print_structure() at strategic + places in order to be able to see what's really going on. Also, + memory debuggers like Checker or Purify are very handy. */ +#define TREE_SIZE 1024 +#define N_ITERATIONS 16 +int +main (int argc, char **argv) +{ + int array[TREE_SIZE]; + int seed; + int iteration; + + if (argc == 2) + seed = atoi (argv[1]); + else + seed = time (0) * 257 % 32768; + + fputs ("Testing avl...\n", stdout); + + for (iteration = 1; iteration <= N_ITERATIONS; iteration++) + { + avl_tree *tree; + int i; + + printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); + fflush (stdout); + + srand (seed++); + + for (i = 0; i < TREE_SIZE; i++) + array[i] = i; + shuffle (array, TREE_SIZE); + + tree = avl_create (compare_ints, NULL); + for (i = 0; i < TREE_SIZE; i++) + avl_force_insert (tree, (void *) (array[i])); + verify_tree (tree); + + shuffle (array, TREE_SIZE); + for (i = 0; i < TREE_SIZE; i++) + { + avl_tree *copy; + + avl_delete (tree, (void *) (array[i])); + verify_tree (tree); + + copy = avl_copy (tree, NULL); + verify_tree (copy); + compare_trees (tree->root.link[0], copy->root.link[0]); + avl_destroy (copy, NULL); + + if (i % 128 == 0) + { + putchar ('.'); + fflush (stdout); + } + } + fputs (" good.\n", stdout); + + avl_destroy (tree, NULL); + } + + return 0; +} +#endif /* SELF_TEST */ + +/* + Local variables: + compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./avl-test avl.c" + End: +*/ + diff --git a/avl-1.4.0/avl.h b/avl-1.4.0/avl.h new file mode 100644 index 0000000..436a461 --- /dev/null +++ b/avl-1.4.0/avl.h @@ -0,0 +1,148 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avl.h in libavl. */ + +#if !avl_h +#define avl_h 1 + +/* The default maximum height of 32 allows for AVL trees having + between 5,704,880 and 4,294,967,295 nodes, depending on order of + insertion. You may change this compile-time constant as you + wish. */ +#ifndef AVL_MAX_HEIGHT +#define AVL_MAX_HEIGHT 32 +#endif + +/* Structure for a node in an AVL tree. */ +typedef struct avl_node + { + void *data; /* Pointer to data. */ + struct avl_node *link[2]; /* Subtrees. */ + signed char bal; /* Balance factor. */ + char cache; /* Used during insertion. */ + signed char pad[2]; /* Unused. Reserved for threaded trees. */ + } +avl_node; + +/* Used for traversing an AVL tree. */ +typedef struct avl_traverser + { + int init; /* Initialized? */ + int nstack; /* Top of stack. */ + const avl_node *p; /* Used for traversal. */ + const avl_node *stack[AVL_MAX_HEIGHT];/* Descended trees. */ + } +avl_traverser; + +/* Initializer for avl_traverser. */ +#define AVL_TRAVERSER_INIT {0} + +/* Function types. */ +#if !AVL_FUNC_TYPES +#define AVL_FUNC_TYPES 1 +typedef int (*avl_comparison_func) (const void *a, const void *b, void *param); +typedef void (*avl_node_func) (void *data, void *param); +typedef void *(*avl_copy_func) (void *data, void *param); +#endif + +/* Structure which holds information about an AVL tree. */ +typedef struct avl_tree + { +#if PSPP + struct arena **owner; /* Arena to store nodes. */ +#endif + avl_node root; /* Tree root node. */ + avl_comparison_func cmp; /* Used to compare keys. */ + int count; /* Number of nodes in the tree. */ + void *param; /* Arbitary user data. */ + } +avl_tree; + +#if PSPP +#define MAYBE_ARENA struct arena **owner, +#else +#define MAYBE_ARENA /* nothing */ +#endif + +/* General functions. */ +avl_tree *avl_create (MAYBE_ARENA avl_comparison_func, void *param); +void avl_destroy (avl_tree *, avl_node_func); +void avl_free (avl_tree *); +int avl_count (const avl_tree *); +avl_tree *avl_copy (MAYBE_ARENA const avl_tree *, avl_copy_func); + +/* Walk the tree. */ +void avl_walk (const avl_tree *, avl_node_func, void *param); +void *avl_traverse (const avl_tree *, avl_traverser *); +#define avl_init_traverser(TRAVERSER) ((TRAVERSER)->init = 0) + +/* Search for a given item. */ +void **avl_probe (avl_tree *, void *); +void *avl_delete (avl_tree *, const void *); +void *avl_find (const avl_tree *, const void *); +void *avl_find_close (const avl_tree *, const void *); + +#if __GCC__ >= 2 +extern inline void * +avl_insert (avl_tree *tree, void *item) +{ + void **p = avl_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +extern inline void * +avl_replace (avl_tree *tree, void *item) +{ + void **p = avl_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} +#else /* not gcc */ +void *avl_insert (avl_tree *tree, void *item); +void *avl_replace (avl_tree *tree, void *item); +#endif /* not gcc */ + +/* Easy assertions on insertion & deletion. */ +#ifndef NDEBUG +#define avl_force_insert(A, B) \ + do \ + { \ + void *r = avl_insert (A, B); \ + assert (r == NULL); \ + } \ + while (0) +void *avl_force_delete (avl_tree *, void *); +#else +#define avl_force_insert(A, B) \ + avl_insert (A, B) +#define avl_force_delete(A, B) \ + avl_delete (A, B) +#endif + +#endif /* avl_h */ diff --git a/avl-1.4.0/avl.html b/avl-1.4.0/avl.html new file mode 100644 index 0000000..ef3e51e --- /dev/null +++ b/avl-1.4.0/avl.html @@ -0,0 +1,1046 @@ + + + + +libavl manual + + + +

libavl

+

A library for manipulation of balanced binary trees

+
Ben Pfaff
+

+


+

Table of Contents

+ +


+ + +

Introduction to balanced binary trees

+ +

+ +Consider some techniques that can be used to find a particular item in a +data set. Typical methods include sequential searching, digital +searching, hash tables, and binary searching. + +

+

+Sequential searching is simple, but slow (O(n)). Digital searching +requires that the entire data set be known in advance, and memory +efficient implementations are slow. + +

+

+Hash tables are fast (O(1)) for static data sets, but they can be +wasteful of memory. It can be difficult to choose an effective hash +function. Some hash tables variants also make deletion an expensive +operation. + +

+

+ +Binary search techniques work almost as quickly (O(log(n)) on an ordered +table, or on a binary tree. Binary trees also allow easy iteration over +the data in the tree in sorted order. With hash tables it is necessary +to sort the data before iterating, and after sorting the data is no +longer in hash form. + +

+

+Binary trees are efficient for insertion, deletion, and searching, if +data are inserted in random order. But, if data are inserted in order +using a naive algorithm, binary search degenerates to sequential search. + +

+

+ + + +In turn, this problem can be solved by rebalancing the tree after +each insertion or deletion. In rebalancing, nodes are rearranged via +transformations called rotations using an algorithm that tends to +minimize the tree's height. + +

+

+There are several schemes for rebalancing binary trees. The two most +common types of balanced tree are AVL trees and red-black +trees. libavl implements both types: + +

+ +
    +
  • + + + +AVL trees, invented by Russian mathematicians G. M. Adel'son-Velskii and +E. M. Landis, ensure that, for each node, the difference in height +between its subtrees (the balance factor) is not greater than 1. + +
  • + +Red-black trees, invented by R. Bayer and studied at length by +L. J. Guibas and R. Sedgewick, assign each node of a tree a color (red +or black), and specify a set of rules governing how red and black nodes +may be arranged. +
+ +

+The table below presents a comparison among unbalanced binary trees, AVL +trees, and red-black trees. In the table, n is the number of +nodes in the tree and h is the tree's height before the +operation. lg is the base-2 logarithm function. + +

+ + +Operation +
+ +Time per insertion or deletion +
+ +Time for insertion of k nodes having sequential values +
+ +Time for insertion of k nodes having random values +
+ +Maximum number of rotations per insertion +
+ +Maximum number of rotations per deletion +
+ +Maximum h as a function of n +
+ +Minimum n as a function of h +
+ +
Binary Tree + AVL Tree + Red-Black Tree + +
+
O(h) + O(lg n) + O(lg n) + +
+
O(k^2) + O(n lg n) + O(n lg n) + +
+
O(n lg n) + O(n lg n) + O(n lg n) + +
+
0 + 1 + lg n + +
+
0 + lg n + lg n + +
+
n + 1.44 lg (n + 2) - .328 + 2 lg (n + 1) + +
+
h + 2^((h + .328) / 1.44) - 2 + 2^(h / 2) - 1 +
+ +There are alternatives to AVL trees that share some of their properties. +For instance, skip lists, 2-3 trees, and splay trees all allow O(log(n)) +insertion and deletion. The main disadvantage of these methods is that +their operations are not as well documented in the literature. + + + +

Introduction to threaded trees

+ +

+Threading is a clever method that simplifies binary tree +traversal. + +

+

+Nodes in a unthreaded binary tree that have zero or one subnodes have +two or one null subnode pointers, respectively. In a threaded binary +tree, a left child pointer that would otherwise be null is used to point +to the node's inorder(1) +predecessor, and in a null right child pointer points to its inorder +successor. + +

+

+In a threaded tree, it is always possible to find the next node and the +previous node of a node, given only a pointer to the node in question. +In an unthreaded tree, it's also necessary to have a list of the nodes +between the node in question and root of the tree. + +

+

+Advantages of a threaded tree compared to an unthreaded one include: + +

+ +
    +
  • + +Faster traversal and less memory usage during traversal, since no stack +need be maintained. + +
  • + +Greater generality, since one can go from a node to its successor or +predecessor given only the node, simplifying algorithms that require +moving forward and backward in a tree. +
+ +

+Some disadvantages of threaded trees are: + +

+ +
    +
  • + +Slower insertion and deletion, since threads need to be maintained. In +somes cases, this can be alleviated by constructing the tree as an +unthreaded tree, then threading it with a special libavl function. + +
  • + +In theory, threaded trees need two extra bits per node to indicate +whether each child pointer points to an ordinary node or the node's +successor/predecessor node. In libavl, however, these bits are stored +in a byte that is used for structure alignment padding in unthreaded +binary trees, so no extra storage is used. +
+ +

+A right-threaded binary tree is similar to a threaded binary tree, +but threads are only maintained on the right side of each node. This +allows for traversal to the right (toward larger values) but not to the +left (toward smaller values). Right-threaded trees are convenient when +the properties of a threaded tree are desirable, but traversal in +reverse sort order is not necessary. Not threading the left links saves +time in insertions and deletions. + +

+

+Left-threaded binary trees also exist, but they are not implemented by +libavl. The same effect can be obtained by sorting the tree in the +opposite order. + +

+ + +

Types

+ +

+The following types are defined and used by libavl: + +

+

+

+
Data Type: avl_tree +
+
Data Type: avlt_tree +
+
Data Type: avltr_tree +
+
Data Type: rb_tree +
+These are the data types used to represent a tree. Although they are +defined in the libavl header files, it should never be necessary to +access them directly. Instead, all accesses should take place through +libavl functions. +
+ +

+

+

+
Data Type: avl_node +
+
Data Type: avlt_node +
+
Data Type: avltr_node +
+
Data Type: rb_node +
+These are the data types used to represent individual nodes in a tree. +Similar cautions apply as with avl_tree structures. +
+ +

+

+

+
Data Type: avl_traverser +
+
Data Type: avlt_traverser +
+
Data Type: avltr_traverser +
+
Data Type: rb_traverser +
+These are the data types used by the avl_traverse family of +functions to iterate across the tree. Again, these are opaque +structures. +
+ +

+

+

+
Data Type: avl_comparison_func +
+Every tree must have an ordering defined by a function of this type. It +must have the following signature: + +

+ +
+int compare (const void *a, const void *b, void *param)
+
+ +

+The return value is expected to be like that returned by strcmp +in the standard C library: negative if a < b, zero if +a = b, positive if a > b. param is an +arbitrary value defined by the user when the tree was created. +

+ +

+

+

+
Data Type: avl_node_func +
+This is a class of function called to perform an operation on a data +item. Functions of this type have the following signature: + +

+ +
+void operate (void *data, void *param)
+
+ +

+data is the data item and param is an arbitrary user-defined +value set when the tree was created. +

+ +

+

+

+
Data Type: avl_copy_func +
+ +

+

+This is a class of function called to make a new copy of a node's data. +Functions of this type have the following signature: + +

+ +
+void *copy (void *data, void *param)
+
+ +

+The function should return a new copy of data. param is an +arbitrary user-defined value set when the tree was created. +

+ +

+

+

+
Macro: AVL_MAX_HEIGHT +
+This macro defines the maximum height of an AVL tree that can be handled +by functions that maintain a stack of nodes descended. The default +value is 32, which allows for AVL trees with a maximum number of nodes +between 5,704,880 and 4,294,967,295, depending on order of insertion. +This macro may be defined by the user before including any AVL tree +header file, in which case libavl will honor that value. +
+ +

+

+

+
Macro: RB_MAX_HEIGHT +
+This macro defines the maximum height of an AVL tree that can be handled +by functions that maintain a stack of nodes descended. The default +value is 32, which allows for red-black trees with a maximum number of +nodes of at least 65535. This macro may be defined by the user before +including the red-black tree header file, in which case libavl will +honor that value. +
+ +

+ + +

Functions

+ +

+ + + +libavl is four libraries in one: + +

+ +
    +
  • + +An unthreaded AVL tree library. + +
  • + +A threaded AVL tree library. + +
  • + +A right-threaded AVL tree library. + +
  • + +A red-black tree library. +
+ +

+Identifiers in these libraries are prefixed by avl_, +avlt_, avltr_, and rb_, with corresponding header +files `avl.h', `avlt.h', `avltr.h', and `rb.h', +respectively. The functions that they declare are defined in the +`.c' files with the same names. + +

+

+Most tree functions are implemented in all three libraries, but +threading allows more generality of operation. So, the threaded and +right-threaded libraries offer a few additional functions for finding +the next or previous node from a given node. In addition, they offer +functions for converting trees from threaded or right-threaded +representations to unthreaded, and vice versa.(2) + +

+ + +

Tree Creation

+ +

+These functions deal with creation and destruction of AVL trees. + +

+

+

+
Function: avl_tree * avl_create (avl_comparison_func compare, void *param) +
+
Function: avlt_tree * avlt_create (avlt_comparison_func compare, void *param) +
+
Function: avltr_tree * avltr_create (avltr_comparison_func compare, void *param) +
+
Function: rb_tree * rb_create (avl_comparison_func compare, void *param) +
+Create a new, empty tree with comparison function compare. +Arbitrary user data param is saved so that it can be passed to +user callback functions. +
+ +

+

+

+
Function: void avl_destroy (avl_tree *tree, avl_node_func free) +
+
Function: void avlt_destroy (avlt_tree *tree, avl_node_func free) +
+
Function: void avltr_destroy (avltr_tree *tree, avl_node_func free) +
+
Function: void rb_destroy (rb_tree *tree, avl_node_func free) +
+Destroys tree, releasing all of its storage. If free is +non-null, then it is called for every node in postorder before that node +is freed. +
+ +

+

+

+
Function: void avl_free (avl_tree *tree) +
+
Function: void avlt_free (avlt_tree *tree) +
+
Function: void avltr_free (avltr_tree *tree) +
+
Function: void rb_free (rb_tree *tree) +
+Destroys tree, releasing all of its storage. The data in each +node is freed with a call to the standard C library function +free. +
+ +

+

+

+
Function: avl_tree * avl_copy (const avl_tree *tree, avl_copy_func copy) +
+
Function: avlt_tree * avl_copy (const avlt_tree *tree, avl_copy_func copy) +
+
Function: avltr_tree * avl_copy (const avltr_tree *tree, avl_copy_func copy) +
+
Function: rb_tree * rb_copy (const rb_tree *tree, avl_copy_func copy) +
+Copies the contents of tree into a new tree, and returns the new +tree. If copy is non-null, then it is called to make a new copy +of each node's data; otherwise, the node data is copied verbatim into +the new tree. +
+ +

+

+

+
Function: int avl_count (const avl_tree *tree) +
+
Function: int avlt_count (const avlt_tree *tree) +
+
Function: int avltr_count (const avltr_tree *tree) +
+
Function: int rb_count (const rb_tree *tree) +
+Returns the number of nodes in tree. +
+ +

+

+

+
Function: void * xmalloc (size_t size) +
+This is not a function defined by libavl. Instead, it is a function +that the user program can define. It must allocate size bytes +using malloc and return it. It can handle out-of-memory errors +however it chooses, but it may not ever return a null pointer. + +

+

+If there is an xmalloc function defined for use by libavl, the +source files (`avl.c', `avlt.c', `avltr.c', `rb.c') +must be compiled with HAVE_XMALLOC defined. Otherwise, the +library will use its internal static xmalloc, which handles +out-of-memory errors by printing a message `virtual memory +exhausted' to stderr and terminating the program with exit code +EXIT_FAILURE. +

+ +

+ + +

Insertion and Deletion

+ +

+These function insert nodes, delete nodes, and search for nodes in +trees. + +

+

+

+
Function: void ** avl_probe (avl_tree *tree, void *data) +
+
Function: void ** avlt_probe (avlt_tree *tree, void *data) +
+
Function: void ** avltr_probe (avltr_tree *tree, void *data) +
+
Function: void ** rb_probe (rb_tree *tree, void *data) +
+These are the workhorse functions for tree insertion. They search +tree for a node with data matching data. If found, a +pointer to the matching data is returned. Otherwise, a new node is +created for data, and a pointer to that data is returned. In +either case, the pointer returned can be changed by the user, but the +key data used by the tree's comparison must not be changed(3). + +

+

+It is usually easier to use one of the avl_insert or +avl_replace functions instead of avl_probe directly. + +

+

+Please note: It's not a particularly good idea to insert a null +pointer as a data item into a tree, because several libavl functions +return a null pointer to indicate failure. You can sometimes avoid a +problem by using functions that return a pointer to a pointer instead of +a plain pointer. Also be wary of this when casting an arithmetic type +to a void pointer for insertion--on typical architectures, 0's become +null pointers when this is done. +

+ +

+

+

+
Function: void * avl_insert (avl_tree *tree, void *data) +
+
Function: void * avlt_insert (avlt_tree *tree, void *data) +
+
Function: void * avltr_insert (avltr_tree *tree, void *data) +
+
Function: void * rb_insert (rb_tree *tree, void *data) +
+If a node with data matching data exists in tree, returns +the matching data item. Otherwise, inserts data into tree +and returns a null pointer. +
+ +

+

+

+
Function: void avl_force_insert (avl_tree *tree, void *data) +
+
Function: void avlt_force_insert (avlt_tree *tree, void *data) +
+
Function: void avltr_force_insert (avltr_tree *tree, void *data) +
+
Function: void rb_force_insert (rb_tree *tree, void *data) +
+Inserts data into tree. If a node with data matching +data exists in tree, aborts the program with an assertion +violation. This function is implemented as a macro; if it is used, the +standard C header assert.h must also be included. If macro +NDEBUG is defined when a libavl header is included, these +functions are short-circuited to a direct call to avl_insert, +and no check is performed. +
+ +

+

+

+
Function: void * avl_replace (avl_tree *tree, void *data) +
+
Function: void * avlt_replace (avlt_tree *tree, void *data) +
+
Function: void * avltr_replace (avltr_tree *tree, void *data) +
+
Function: void * rb_replace (rb_tree *tree, void *data) +
+If a node with data matching data, such that the comparison +function returns 0, exists in tree, replaces the node's data with +data and returns the node's former contents. Otherwise, inserts +data into tree and returns a null pointer. +
+ +

+

+

+
Function: void * avl_delete (avl_tree *tree, const void *data) +
+
Function: void * avlt_delete (avlt_tree *tree, const void *data) +
+
Function: void * avltr_delete (avltr_tree *tree, const void *data) +
+
Function: void * rb_delete (rb_tree *tree, const void *data) +
+Searches tree for a node with data matching data. If found, +the node is deleted and its data is returned. Otherwise, returns a null +pointer. +
+ +

+

+

+
Function: void * avl_force_delete (avl_tree *tree, const void *data) +
+
Function: void * avlt_force_delete (avlt_tree *tree, const void *data) +
+
Function: void * avltr_force_delete (avltr_tree *tree, const void *data) +
+
Function: void * rb_force_delete (rb_tree *tree, const void *data) +
+Deletes a node with data matching data from tree. If no +matching node is found, aborts the program with an assertion violation. +If macro NDEBUG is declared when a libavl header is included, +these functions are short-circuited to a direct call to +avl_delete, and no check is performed. +
+ +

+ + +

Searching

+ +

+These function search a tree for an item without making an insertion or +a deletion. + +

+

+

+
Function: void * avl_find (avl_tree *tree, const void *data) +
+
Function: void ** avlt_find (avlt_tree *tree, const void *data) +
+
Function: void ** avltr_find (avltr_tree *tree, const void *data) +
+
Function: void * rb_find (rb_tree *tree, const void *data) +
+Searches tree for a node with data matching data, If found, +returns the node's data (for threaded and right-threaded trees, a +pointer to the node's data). Otherwise, returns a null pointer. +
+ +

+

+

+
Function: void * avl_find_close (avl_tree *tree, const void *data) +
+
Function: void ** avlt_find_close (avlt_tree *tree, const void *data) +
+
Function: void ** avltr_find_close (avltr_tree *tree, const void *data) +
+
Function: void * rb_find_close (rb_tree *tree, const void *data) +
+Searches tree for a node with data matching data. If found, +returns the node's data (for threaded and right-threaded trees, a +pointer to the node's data). If no matching item is found, then it +finds a node whose data is "close" to data; either the node +closest in value to data, or the node either before or after the +node with the closest value. Returns a null pointer if the tree does +not contain any nodes. +
+ +

+ + +

Iteration

+ +

+These functions allow the caller to iterate across the items in a tree. + +

+

+

+
Function: void avl_walk (const avl_tree *tree, avl_node_func operate, void *param) +
+
Function: void avlt_walk (const avlt_tree *tree, avl_node_func operate, void *param) +
+
Function: void avltr_walk (const avltr_tree *tree, avl_node_func operate, void *param) +
+
Function: void rb_walk (const rb_tree *tree, avl_node_func operate, void *param) +
+Walks through all the nodes in tree, and calls function +operate for each node in inorder. param overrides the value +passed to avl_create (and family) for this operation only. +operate must not change the key data in the nodes in a way that +would reorder the data values or cause two values to become equal. +
+ +

+

+

+
Function: void * avl_traverse (const avl_tree *tree, avl_traverser *trav) +
+
Function: void * avlt_traverse (const avlt_tree *tree, avlt_traverser *trav) +
+
Function: void * avltr_traverse (const avltr_tree *tree, avltr_traverser *trav) +
+
Function: void * rb_traverse (const rb_tree *tree, rb_traverser *trav) +
+Returns each of tree's nodes' data values in sequence, then a null +pointer to indicate the last item. trav must be initialized +before the first call, either in a declaration like that below, or using +one of the functions below. + +

+ +
+avl_traverser trav = AVL_TRAVERSER_INIT;
+
+ +

+Each avl_traverser (and family) is a separate, independent +iterator. + +

+

+For threaded and right-threaded trees, avlt_next or +avltr_next, respectively, are faster and more memory-efficient +than avlt_traverse or avltr_traverse. +

+ +

+

+

+
Function: void * avl_init_traverser (avl_traverser *trav) +
+
Function: void * avlt_init_traverser (avlt_traverser *trav) +
+
Function: void * avltr_init_traverser (avltr_traverser *trav) +
+
Function: void * rb_init_traverser (rb_traverser *trav) +
+Initializes the specified tree traverser structure. After this function +is called, the next call to the corresponding *_traverse function +will return the smallest value in the appropriate tree. +
+ +

+

+

+
Function: void ** avlt_next (const avlt_tree *tree, void **data) +
+
Function: void ** avltr_next (const avltr_tree *tree, void **data) +
+data must be a null pointer or a pointer to a data item in AVL +tree tree. Returns a pointer to the next data item after +data in tree in inorder (this is the first item if +data is a null pointer), or a null pointer if data was the +last item in tree. +
+ +

+

+

+
Function: void ** avltr_prev (const avltr_tree *tree, void **data) +
+data must be a null pointer or a pointer to a data item in AVL +tree tree. Returns a pointer to the previous data item before +data in tree in inorder (this is the last, or greatest +valued, item if data is a null pointer), or a null pointer if +data was the first item in tree. +
+ +

+ + +

Conversion

+ +

+

+
Function: avlt_tree * avlt_thread (avl_tree *tree) +
+
Function: avltr_tree * avltr_thread (avl_tree *tree) +
+Adds symmetric threads or right threads, respectively, to unthreaded AVL +tree tree and returns a pointer to tree cast to the +appropriate type. After one of these functions is called, threaded or +right-threaded functions, as appropriate, must be used with tree; +unthreaded functions may not be used. +
+ +

+

+

+
Function: avl_tree * avlt_unthread (avlt_tree *tree) +
+
Function: avl_tree * avltr_unthread (avltr_tree *tree) +
+Cuts all threads in threaded or right-threaded, respectively, AVL tree +tree and returns a pointer to tree cast to avl_tree +*. After one of these functions is called, unthreaded functions must +be used with tree; threaded or right-threaded functions may not be +used. +
+ +

+ + +

Author

+ +

+ + + + +libavl was written by Ben Pfaff blp@gnu.org. + +

+

+libavl's generic tree algorithms and AVL algorithms are based on those +found in Donald Knuth's venerable Art of Computer Programming +series from Addison-Wesley, primarily Volumes 1 and 3. libavl's +red-black tree algorithms are based on those found in Cormen et al., +Introduction to Algorithms, 2nd ed., from MIT Press. + +

+ + +

Index

+ +

+

a

+ +
  • Adel'son-Velskii, G. M. +
  • Art of Computer Programming +
  • author +
  • AVL tree +
  • avl_comparison_func +
  • avl_copy, avl_copy, avl_copy +
  • avl_copy_func +
  • avl_count +
  • avl_create +
  • avl_delete +
  • avl_destroy +
  • avl_find +
  • avl_find_close +
  • avl_force_delete +
  • avl_force_insert +
  • avl_free +
  • avl_init_traverser +
  • avl_insert +
  • AVL_MAX_HEIGHT +
  • avl_node +
  • avl_node_func +
  • avl_probe +
  • avl_replace +
  • avl_traverse +
  • avl_traverser +
  • avl_tree +
  • avl_walk +
  • avlt_count +
  • avlt_create +
  • avlt_delete +
  • avlt_destroy +
  • avlt_find +
  • avlt_find_close +
  • avlt_force_delete +
  • avlt_force_insert +
  • avlt_free +
  • avlt_init_traverser +
  • avlt_insert +
  • avlt_next +
  • avlt_node +
  • avlt_probe +
  • avlt_replace +
  • avlt_thread +
  • avlt_traverse +
  • avlt_traverser +
  • avlt_tree +
  • avlt_unthread +
  • avlt_walk +
  • avltr_count +
  • avltr_create +
  • avltr_delete +
  • avltr_destroy +
  • avltr_find +
  • avltr_find_close +
  • avltr_force_delete +
  • avltr_force_insert +
  • avltr_free +
  • avltr_init_traverser +
  • avltr_insert +
  • avltr_next +
  • avltr_node +
  • avltr_prev +
  • avltr_probe +
  • avltr_replace +
  • avltr_thread +
  • avltr_traverse +
  • avltr_traverser +
  • avltr_tree +
  • avltr_unthread +
  • avltr_walk +
  • +

    b

    + +
  • binary tree +
  • +

    h

    + +
  • hash table +
  • +

    k

    + +
  • Knuth, Donald Ervin +
  • +

    l

    + +
  • Landis, E. M. +
  • +

    p

    + +
  • Pfaff, Benjamin Levy +
  • +

    r

    + +
  • rb_copy +
  • rb_count +
  • rb_create +
  • rb_delete +
  • rb_destroy +
  • rb_find +
  • rb_find_close +
  • rb_force_delete +
  • rb_force_insert +
  • rb_free +
  • rb_init_traverser +
  • rb_insert +
  • RB_MAX_HEIGHT +
  • rb_node +
  • rb_probe +
  • rb_replace +
  • rb_traverse +
  • rb_traverser +
  • rb_tree +
  • rb_walk +
  • rebalancing +
  • red-black tree +
  • right threads +
  • +

    t

    + +
  • threads +
  • +

    u

    + +
  • unthreaded +
  • +

    x

    + +
  • xmalloc +
  • + +

    +


    +

    Footnotes

    +

    (1)

    +

    In tree traversal, inorder refers +to visiting the nodes in their sorted order from smallest to largest. +

    (2)

    +

    In general, you +should build the sort of tree that you need to use, but occasionally it +is useful to convert between tree types. +

    (3)

    +

    It +can be changed if this would not change the ordering of the nodes in the +tree; i.e., if this would not cause the data in the node to be less than +or equal to the previous node's data or greater than or equal to the +next node's data. +


    +This document was generated on 6 October 1999 using the +texi2html +translator version 1.51a.

    + + diff --git a/avl-1.4.0/avl.info b/avl-1.4.0/avl.info new file mode 100644 index 0000000..8dd5330 --- /dev/null +++ b/avl-1.4.0/avl.info @@ -0,0 +1,708 @@ +This is avl.info, produced by makeinfo version 3.12n from avl.texinfo. + + This file documents libavl, a library for the manipulation of +balanced binary trees. + + Copyright 1998, 1999 Free Software Foundation, Inc. + + 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. + + +File: avl.info, Node: Top, Next: Introduction to balanced binary trees, Prev: (dir), Up: (dir) + + This document describes libavl, a library for manipulation of +balanced binary trees. + + This document applies to libavl version 1.4.0. + +* Menu: + +* Introduction to balanced binary trees:: +* Introduction to threaded trees:: +* Types:: +* Functions:: +* Tree Creation:: +* Insertion:: +* Searching:: +* Iteration:: +* Conversion:: +* Author:: +* Index:: + + +File: avl.info, Node: Introduction to balanced binary trees, Next: Introduction to threaded trees, Prev: Top, Up: Top + +Introduction to balanced binary trees +************************************* + + Consider some techniques that can be used to find a particular item +in a data set. Typical methods include sequential searching, digital +searching, hash tables, and binary searching. + + Sequential searching is simple, but slow (O(n)). Digital searching +requires that the entire data set be known in advance, and memory +efficient implementations are slow. + + Hash tables are fast (O(1)) for static data sets, but they can be +wasteful of memory. It can be difficult to choose an effective hash +function. Some hash tables variants also make deletion an expensive +operation. + + Binary search techniques work almost as quickly (O(log(n)) on an +ordered table, or on a binary tree. Binary trees also allow easy +iteration over the data in the tree in sorted order. With hash tables +it is necessary to sort the data before iterating, and after sorting +the data is no longer in hash form. + + Binary trees are efficient for insertion, deletion, and searching, if +data are inserted in random order. But, if data are inserted in order +using a naive algorithm, binary search degenerates to sequential search. + + In turn, this problem can be solved by "rebalancing" the tree after +each insertion or deletion. In rebalancing, nodes are rearranged via +transformations called "rotations" using an algorithm that tends to +minimize the tree's height. + + There are several schemes for rebalancing binary trees. The two most +common types of balanced tree are "AVL trees" and "red-black trees". +libavl implements both types: + + * AVL trees, invented by Russian mathematicians G. M. + Adel'son-Velskii and E. M. Landis, ensure that, for each node, the + difference in height between its subtrees (the "balance factor") + is not greater than 1. + + * Red-black trees, invented by R. Bayer and studied at length by L. + J. Guibas and R. Sedgewick, assign each node of a tree a color (red + or black), and specify a set of rules governing how red and black + nodes may be arranged. + + The table below presents a comparison among unbalanced binary trees, +AVL trees, and red-black trees. In the table, N is the number of nodes +in the tree and H is the tree's height before the operation. "lg" is +the base-2 logarithm function. + +Operation + Binary Tree AVL Tree Red-Black Tree +Time per insertion or deletion + O(H) O(lg N) O(lg N) +Time for insertion of K nodes having sequential values + O(K^2) O(N lg N) O(N lg N) +Time for insertion of K nodes having random values + O(N lg N) O(N lg N) O(N lg N) +Maximum number of rotations per insertion + 0 1 lg N +Maximum number of rotations per deletion + 0 lg N lg N +Maximum H as a function of N + N 1.44 lg (N + 2) - .328 2 lg (N + 1) +Minimum N as a function of H + H 2^((H + .328) / 1.44) - 2 2^(H / 2) - 1 + + There are alternatives to AVL trees that share some of their +properties. For instance, skip lists, 2-3 trees, and splay trees all +allow O(log(n)) insertion and deletion. The main disadvantage of these +methods is that their operations are not as well documented in the +literature. + + +File: avl.info, Node: Introduction to threaded trees, Next: Types, Prev: Introduction to balanced binary trees, Up: Top + +Introduction to threaded trees +****************************** + + "Threading" is a clever method that simplifies binary tree traversal. + + Nodes in a unthreaded binary tree that have zero or one subnodes have +two or one null subnode pointers, respectively. In a threaded binary +tree, a left child pointer that would otherwise be null is used to point +to the node's inorder(1) predecessor, and in a null right child pointer +points to its inorder successor. + + In a threaded tree, it is always possible to find the next node and +the previous node of a node, given only a pointer to the node in +question. In an unthreaded tree, it's also necessary to have a list of +the nodes between the node in question and root of the tree. + + Advantages of a threaded tree compared to an unthreaded one include: + + * Faster traversal and less memory usage during traversal, since no + stack need be maintained. + + * Greater generality, since one can go from a node to its successor + or predecessor given only the node, simplifying algorithms that + require moving forward and backward in a tree. + + Some disadvantages of threaded trees are: + + * Slower insertion and deletion, since threads need to be + maintained. In somes cases, this can be alleviated by + constructing the tree as an unthreaded tree, then threading it + with a special libavl function. + + * In theory, threaded trees need two extra bits per node to indicate + whether each child pointer points to an ordinary node or the node's + successor/predecessor node. In libavl, however, these bits are + stored in a byte that is used for structure alignment padding in + unthreaded binary trees, so no extra storage is used. + + A "right-threaded binary tree" is similar to a threaded binary tree, +but threads are only maintained on the right side of each node. This +allows for traversal to the right (toward larger values) but not to the +left (toward smaller values). Right-threaded trees are convenient when +the properties of a threaded tree are desirable, but traversal in +reverse sort order is not necessary. Not threading the left links saves +time in insertions and deletions. + + Left-threaded binary trees also exist, but they are not implemented +by libavl. The same effect can be obtained by sorting the tree in the +opposite order. + + ---------- Footnotes ---------- + + (1) In tree traversal, "inorder" refers to visiting the nodes in +their sorted order from smallest to largest. + + +File: avl.info, Node: Types, Next: Functions, Prev: Introduction to threaded trees, Up: Top + +Types +***** + + The following types are defined and used by libavl: + + - Data Type: avl_tree + - Data Type: avlt_tree + - Data Type: avltr_tree + - Data Type: rb_tree + These are the data types used to represent a tree. Although they + are defined in the libavl header files, it should never be + necessary to access them directly. Instead, all accesses should + take place through libavl functions. + + - Data Type: avl_node + - Data Type: avlt_node + - Data Type: avltr_node + - Data Type: rb_node + These are the data types used to represent individual nodes in a + tree. Similar cautions apply as with `avl_tree' structures. + + - Data Type: avl_traverser + - Data Type: avlt_traverser + - Data Type: avltr_traverser + - Data Type: rb_traverser + These are the data types used by the `avl_traverse' family of + functions to iterate across the tree. Again, these are opaque + structures. + + - Data Type: avl_comparison_func + Every tree must have an ordering defined by a function of this + type. It must have the following signature: + + int COMPARE (const void *A, const void *B, void *PARAM) + + The return value is expected to be like that returned by `strcmp' + in the standard C library: negative if A < B, zero if A = B, + positive if A > B. PARAM is an arbitrary value defined by the + user when the tree was created. + + - Data Type: avl_node_func + This is a class of function called to perform an operation on a + data item. Functions of this type have the following signature: + + void OPERATE (void *DATA, void *PARAM) + + DATA is the data item and PARAM is an arbitrary user-defined value + set when the tree was created. + + - Data Type: avl_copy_func + This is a class of function called to make a new copy of a node's + data. Functions of this type have the following signature: + + void *COPY (void *DATA, void *PARAM) + + The function should return a new copy of DATA. PARAM is an + arbitrary user-defined value set when the tree was created. + + - Macro: AVL_MAX_HEIGHT + This macro defines the maximum height of an AVL tree that can be + handled by functions that maintain a stack of nodes descended. + The default value is 32, which allows for AVL trees with a maximum + number of nodes between 5,704,880 and 4,294,967,295, depending on + order of insertion. This macro may be defined by the user before + including any AVL tree header file, in which case libavl will + honor that value. + + - Macro: RB_MAX_HEIGHT + This macro defines the maximum height of an AVL tree that can be + handled by functions that maintain a stack of nodes descended. + The default value is 32, which allows for red-black trees with a + maximum number of nodes of at least 65535. This macro may be + defined by the user before including the red-black tree header + file, in which case libavl will honor that value. + + +File: avl.info, Node: Functions, Next: Tree Creation, Prev: Types, Up: Top + +Functions +********* + + libavl is four libraries in one: + + * An unthreaded AVL tree library. + + * A threaded AVL tree library. + + * A right-threaded AVL tree library. + + * A red-black tree library. + + Identifiers in these libraries are prefixed by `avl_', `avlt_', +`avltr_', and `rb_', with corresponding header files `avl.h', `avlt.h', +`avltr.h', and `rb.h', respectively. The functions that they declare +are defined in the `.c' files with the same names. + + Most tree functions are implemented in all three libraries, but +threading allows more generality of operation. So, the threaded and +right-threaded libraries offer a few additional functions for finding +the next or previous node from a given node. In addition, they offer +functions for converting trees from threaded or right-threaded +representations to unthreaded, and vice versa.(1) + + ---------- Footnotes ---------- + + (1) In general, you should build the sort of tree that you need to +use, but occasionally it is useful to convert between tree types. + + +File: avl.info, Node: Tree Creation, Next: Insertion, Prev: Functions, Up: Top + +Tree Creation +************* + + These functions deal with creation and destruction of AVL trees. + + - Function: avl_tree * avl_create (avl_comparison_func COMPARE, void + *PARAM) + - Function: avlt_tree * avlt_create (avlt_comparison_func COMPARE, + void *PARAM) + - Function: avltr_tree * avltr_create (avltr_comparison_func COMPARE, + void *PARAM) + - Function: rb_tree * rb_create (avl_comparison_func COMPARE, void + *PARAM) + Create a new, empty tree with comparison function COMPARE. + Arbitrary user data PARAM is saved so that it can be passed to + user callback functions. + + - Function: void avl_destroy (avl_tree *TREE, avl_node_func FREE) + - Function: void avlt_destroy (avlt_tree *TREE, avl_node_func FREE) + - Function: void avltr_destroy (avltr_tree *TREE, avl_node_func FREE) + - Function: void rb_destroy (rb_tree *TREE, avl_node_func FREE) + Destroys TREE, releasing all of its storage. If FREE is non-null, + then it is called for every node in postorder before that node is + freed. + + - Function: void avl_free (avl_tree *TREE) + - Function: void avlt_free (avlt_tree *TREE) + - Function: void avltr_free (avltr_tree *TREE) + - Function: void rb_free (rb_tree *TREE) + Destroys TREE, releasing all of its storage. The data in each + node is freed with a call to the standard C library function + `free'. + + - Function: avl_tree * avl_copy (const avl_tree *TREE, avl_copy_func + COPY) + - Function: avlt_tree * avl_copy (const avlt_tree *TREE, avl_copy_func + COPY) + - Function: avltr_tree * avl_copy (const avltr_tree *TREE, + avl_copy_func COPY) + - Function: rb_tree * rb_copy (const rb_tree *TREE, avl_copy_func COPY) + Copies the contents of TREE into a new tree, and returns the new + tree. If COPY is non-null, then it is called to make a new copy + of each node's data; otherwise, the node data is copied verbatim + into the new tree. + + - Function: int avl_count (const avl_tree *TREE) + - Function: int avlt_count (const avlt_tree *TREE) + - Function: int avltr_count (const avltr_tree *TREE) + - Function: int rb_count (const rb_tree *TREE) + Returns the number of nodes in TREE. + + - Function: void * xmalloc (size_t SIZE) + This is not a function defined by libavl. Instead, it is a + function that the user program can define. It must allocate SIZE + bytes using `malloc' and return it. It can handle out-of-memory + errors however it chooses, but it may not ever return a null + pointer. + + If there is an `xmalloc' function defined for use by libavl, the + source files (`avl.c', `avlt.c', `avltr.c', `rb.c') must be + compiled with `HAVE_XMALLOC' defined. Otherwise, the library will + use its internal static `xmalloc', which handles out-of-memory + errors by printing a message `virtual memory exhausted' to stderr + and terminating the program with exit code `EXIT_FAILURE'. + + +File: avl.info, Node: Insertion, Next: Searching, Prev: Tree Creation, Up: Top + +Insertion and Deletion +********************** + + These function insert nodes, delete nodes, and search for nodes in +trees. + + - Function: void ** avl_probe (avl_tree *TREE, void *DATA) + - Function: void ** avlt_probe (avlt_tree *TREE, void *DATA) + - Function: void ** avltr_probe (avltr_tree *TREE, void *DATA) + - Function: void ** rb_probe (rb_tree *TREE, void *DATA) + These are the workhorse functions for tree insertion. They search + TREE for a node with data matching DATA. If found, a pointer to + the matching data is returned. Otherwise, a new node is created + for DATA, and a pointer to that data is returned. In either case, + the pointer returned can be changed by the user, but the key data + used by the tree's comparison must not be changed(1). + + It is usually easier to use one of the `avl_insert' or + `avl_replace' functions instead of `avl_probe' directly. + + *Please note:* It's not a particularly good idea to insert a null + pointer as a data item into a tree, because several libavl + functions return a null pointer to indicate failure. You can + sometimes avoid a problem by using functions that return a pointer + to a pointer instead of a plain pointer. Also be wary of this + when casting an arithmetic type to a void pointer for + insertion--on typical architectures, 0's become null pointers when + this is done. + + - Function: void * avl_insert (avl_tree *TREE, void *DATA) + - Function: void * avlt_insert (avlt_tree *TREE, void *DATA) + - Function: void * avltr_insert (avltr_tree *TREE, void *DATA) + - Function: void * rb_insert (rb_tree *TREE, void *DATA) + If a node with data matching DATA exists in TREE, returns the + matching data item. Otherwise, inserts DATA into TREE and returns + a null pointer. + + - Function: void avl_force_insert (avl_tree *TREE, void *DATA) + - Function: void avlt_force_insert (avlt_tree *TREE, void *DATA) + - Function: void avltr_force_insert (avltr_tree *TREE, void *DATA) + - Function: void rb_force_insert (rb_tree *TREE, void *DATA) + Inserts DATA into TREE. If a node with data matching DATA exists + in TREE, aborts the program with an assertion violation. This + function is implemented as a macro; if it is used, the standard C + header `assert.h' must also be included. If macro `NDEBUG' is + defined when a libavl header is included, these functions are + short-circuited to a direct call to `avl_insert', and no check is + performed. + + - Function: void * avl_replace (avl_tree *TREE, void *DATA) + - Function: void * avlt_replace (avlt_tree *TREE, void *DATA) + - Function: void * avltr_replace (avltr_tree *TREE, void *DATA) + - Function: void * rb_replace (rb_tree *TREE, void *DATA) + If a node with data matching DATA, such that the comparison + function returns 0, exists in TREE, replaces the node's data with + DATA and returns the node's former contents. Otherwise, inserts + DATA into TREE and returns a null pointer. + + - Function: void * avl_delete (avl_tree *TREE, const void *DATA) + - Function: void * avlt_delete (avlt_tree *TREE, const void *DATA) + - Function: void * avltr_delete (avltr_tree *TREE, const void *DATA) + - Function: void * rb_delete (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA. If found, the + node is deleted and its data is returned. Otherwise, returns a + null pointer. + + - Function: void * avl_force_delete (avl_tree *TREE, const void *DATA) + - Function: void * avlt_force_delete (avlt_tree *TREE, const void + *DATA) + - Function: void * avltr_force_delete (avltr_tree *TREE, const void + *DATA) + - Function: void * rb_force_delete (rb_tree *TREE, const void *DATA) + Deletes a node with data matching DATA from TREE. If no matching + node is found, aborts the program with an assertion violation. If + macro `NDEBUG' is declared when a libavl header is included, these + functions are short-circuited to a direct call to `avl_delete', + and no check is performed. + + ---------- Footnotes ---------- + + (1) It can be changed if this would not change the ordering of the +nodes in the tree; i.e., if this would not cause the data in the node +to be less than or equal to the previous node's data or greater than or +equal to the next node's data. + + +File: avl.info, Node: Searching, Next: Iteration, Prev: Insertion, Up: Top + +Searching +********* + + These function search a tree for an item without making an insertion +or a deletion. + + - Function: void * avl_find (avl_tree *TREE, const void *DATA) + - Function: void ** avlt_find (avlt_tree *TREE, const void *DATA) + - Function: void ** avltr_find (avltr_tree *TREE, const void *DATA) + - Function: void * rb_find (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA, If found, + returns the node's data (for threaded and right-threaded trees, a + pointer to the node's data). Otherwise, returns a null pointer. + + - Function: void * avl_find_close (avl_tree *TREE, const void *DATA) + - Function: void ** avlt_find_close (avlt_tree *TREE, const void *DATA) + - Function: void ** avltr_find_close (avltr_tree *TREE, const void + *DATA) + - Function: void * rb_find_close (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA. If found, + returns the node's data (for threaded and right-threaded trees, a + pointer to the node's data). If no matching item is found, then it + finds a node whose data is "close" to DATA; either the node + closest in value to DATA, or the node either before or after the + node with the closest value. Returns a null pointer if the tree + does not contain any nodes. + + +File: avl.info, Node: Iteration, Next: Conversion, Prev: Searching, Up: Top + +Iteration +********* + + These functions allow the caller to iterate across the items in a +tree. + + - Function: void avl_walk (const avl_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void avlt_walk (const avlt_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void avltr_walk (const avltr_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void rb_walk (const rb_tree *TREE, avl_node_func OPERATE, + void *PARAM) + Walks through all the nodes in TREE, and calls function OPERATE + for each node in inorder. PARAM overrides the value passed to + `avl_create' (and family) for this operation only. OPERATE must + not change the key data in the nodes in a way that would reorder + the data values or cause two values to become equal. + + - Function: void * avl_traverse (const avl_tree *TREE, avl_traverser + *TRAV) + - Function: void * avlt_traverse (const avlt_tree *TREE, + avlt_traverser *TRAV) + - Function: void * avltr_traverse (const avltr_tree *TREE, + avltr_traverser *TRAV) + - Function: void * rb_traverse (const rb_tree *TREE, rb_traverser + *TRAV) + Returns each of TREE's nodes' data values in sequence, then a null + pointer to indicate the last item. TRAV must be initialized + before the first call, either in a declaration like that below, or + using one of the functions below. + + avl_traverser trav = AVL_TRAVERSER_INIT; + + Each `avl_traverser' (and family) is a separate, independent + iterator. + + For threaded and right-threaded trees, `avlt_next' or + `avltr_next', respectively, are faster and more memory-efficient + than `avlt_traverse' or `avltr_traverse'. + + - Function: void * avl_init_traverser (avl_traverser *TRAV) + - Function: void * avlt_init_traverser (avlt_traverser *TRAV) + - Function: void * avltr_init_traverser (avltr_traverser *TRAV) + - Function: void * rb_init_traverser (rb_traverser *TRAV) + Initializes the specified tree traverser structure. After this + function is called, the next call to the corresponding + `*_traverse' function will return the smallest value in the + appropriate tree. + + - Function: void ** avlt_next (const avlt_tree *TREE, void **DATA) + - Function: void ** avltr_next (const avltr_tree *TREE, void **DATA) + DATA must be a null pointer or a pointer to a data item in AVL + tree TREE. Returns a pointer to the next data item after DATA in + TREE in inorder (this is the first item if DATA is a null + pointer), or a null pointer if DATA was the last item in TREE. + + - Function: void ** avltr_prev (const avltr_tree *TREE, void **DATA) + DATA must be a null pointer or a pointer to a data item in AVL + tree TREE. Returns a pointer to the previous data item before + DATA in TREE in inorder (this is the last, or greatest valued, + item if DATA is a null pointer), or a null pointer if DATA was the + first item in TREE. + + +File: avl.info, Node: Conversion, Next: Author, Prev: Iteration, Up: Top + +Conversion +********** + + - Function: avlt_tree * avlt_thread (avl_tree *TREE) + - Function: avltr_tree * avltr_thread (avl_tree *TREE) + Adds symmetric threads or right threads, respectively, to + unthreaded AVL tree TREE and returns a pointer to TREE cast to the + appropriate type. After one of these functions is called, + threaded or right-threaded functions, as appropriate, must be used + with TREE; unthreaded functions may not be used. + + - Function: avl_tree * avlt_unthread (avlt_tree *TREE) + - Function: avl_tree * avltr_unthread (avltr_tree *TREE) + Cuts all threads in threaded or right-threaded, respectively, AVL + tree TREE and returns a pointer to TREE cast to `avl_tree *'. + After one of these functions is called, unthreaded functions must + be used with TREE; threaded or right-threaded functions may not be + used. + + +File: avl.info, Node: Author, Next: Index, Prev: Conversion, Up: Top + +Author +****** + + libavl was written by Ben Pfaff . + + libavl's generic tree algorithms and AVL algorithms are based on +those found in Donald Knuth's venerable `Art of Computer Programming' +series from Addison-Wesley, primarily Volumes 1 and 3. libavl's +red-black tree algorithms are based on those found in Cormen et al., +`Introduction to Algorithms', 2nd ed., from MIT Press. + + +File: avl.info, Node: Index, Prev: Author, Up: Top + +Index +***** + +* Menu: + +* `Art of Computer Programming': Author. +* Adel'son-Velskii, G. M.: Introduction to balanced binary trees. +* author: Author. +* AVL tree: Introduction to balanced binary trees. +* avl_comparison_func: Types. +* avl_copy: Tree Creation. +* avl_copy_func: Types. +* avl_count: Tree Creation. +* avl_create: Tree Creation. +* avl_delete: Insertion. +* avl_destroy: Tree Creation. +* avl_find: Searching. +* avl_find_close: Searching. +* avl_force_delete: Insertion. +* avl_force_insert: Insertion. +* avl_free: Tree Creation. +* avl_init_traverser: Iteration. +* avl_insert: Insertion. +* AVL_MAX_HEIGHT: Types. +* avl_node: Types. +* avl_node_func: Types. +* avl_probe: Insertion. +* avl_replace: Insertion. +* avl_traverse: Iteration. +* avl_traverser: Types. +* avl_tree: Types. +* avl_walk: Iteration. +* avlt_count: Tree Creation. +* avlt_create: Tree Creation. +* avlt_delete: Insertion. +* avlt_destroy: Tree Creation. +* avlt_find: Searching. +* avlt_find_close: Searching. +* avlt_force_delete: Insertion. +* avlt_force_insert: Insertion. +* avlt_free: Tree Creation. +* avlt_init_traverser: Iteration. +* avlt_insert: Insertion. +* avlt_next: Iteration. +* avlt_node: Types. +* avlt_probe: Insertion. +* avlt_replace: Insertion. +* avlt_thread: Conversion. +* avlt_traverse: Iteration. +* avlt_traverser: Types. +* avlt_tree: Types. +* avlt_unthread: Conversion. +* avlt_walk: Iteration. +* avltr_count: Tree Creation. +* avltr_create: Tree Creation. +* avltr_delete: Insertion. +* avltr_destroy: Tree Creation. +* avltr_find: Searching. +* avltr_find_close: Searching. +* avltr_force_delete: Insertion. +* avltr_force_insert: Insertion. +* avltr_free: Tree Creation. +* avltr_init_traverser: Iteration. +* avltr_insert: Insertion. +* avltr_next: Iteration. +* avltr_node: Types. +* avltr_prev: Iteration. +* avltr_probe: Insertion. +* avltr_replace: Insertion. +* avltr_thread: Conversion. +* avltr_traverse: Iteration. +* avltr_traverser: Types. +* avltr_tree: Types. +* avltr_unthread: Conversion. +* avltr_walk: Iteration. +* binary tree: Introduction to balanced binary trees. +* hash table: Introduction to balanced binary trees. +* Knuth, Donald Ervin: Author. +* Landis, E. M.: Introduction to balanced binary trees. +* Pfaff, Benjamin Levy: Author. +* rb_copy: Tree Creation. +* rb_count: Tree Creation. +* rb_create: Tree Creation. +* rb_delete: Insertion. +* rb_destroy: Tree Creation. +* rb_find: Searching. +* rb_find_close: Searching. +* rb_force_delete: Insertion. +* rb_force_insert: Insertion. +* rb_free: Tree Creation. +* rb_init_traverser: Iteration. +* rb_insert: Insertion. +* RB_MAX_HEIGHT: Types. +* rb_node: Types. +* rb_probe: Insertion. +* rb_replace: Insertion. +* rb_traverse: Iteration. +* rb_traverser: Types. +* rb_tree: Types. +* rb_walk: Iteration. +* rebalancing: Introduction to balanced binary trees. +* red-black tree: Introduction to balanced binary trees. +* right threads: Functions. +* threads: Functions. +* unthreaded: Functions. +* xmalloc: Tree Creation. + + + +Tag Table: +Node: Top891 +Node: Introduction to balanced binary trees1340 +Node: Introduction to threaded trees5260 +Ref: Introduction to threaded trees-Footnote-17757 +Node: Types7871 +Node: Functions10904 +Ref: Functions-Footnote-111877 +Node: Tree Creation12014 +Node: Insertion15035 +Ref: Insertion-Footnote-119214 +Node: Searching19458 +Node: Iteration20863 +Node: Conversion23929 +Node: Author24875 +Node: Index25345 + +End Tag Table diff --git a/avl-1.4.0/avl.texinfo b/avl-1.4.0/avl.texinfo new file mode 100644 index 0000000..9d06324 --- /dev/null +++ b/avl-1.4.0/avl.texinfo @@ -0,0 +1,679 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename avl.info +@settitle libavl manual +@setchapternewpage on +@c %**end of header + +@syncodeindex vr cp +@syncodeindex fn cp +@syncodeindex tp cp + +@ifinfo +This file documents libavl, a library for the manipulation of balanced +binary trees. + +Copyright 1998, 1999 Free Software Foundation, Inc. + +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. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries a 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 libavl +@subtitle A library for manipulation of balanced binary trees +@author Ben Pfaff + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1998, 1999 Free Software Foundation, Inc. + +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. +@end titlepage + +@node Top, Introduction to balanced binary trees, (dir), (dir) + +@ifinfo +This document describes libavl, a library for manipulation of balanced +binary trees. + +This document applies to libavl version 1.4.0. +@end ifinfo + +@menu +* Introduction to balanced binary trees:: +* Introduction to threaded trees:: +* Types:: +* Functions:: +* Tree Creation:: +* Insertion:: +* Searching:: +* Iteration:: +* Conversion:: +* Author:: +* Index:: +@end menu + +@node Introduction to balanced binary trees, Introduction to threaded trees, Top, Top +@chapter Introduction to balanced binary trees + +@cindex hash table +Consider some techniques that can be used to find a particular item in a +data set. Typical methods include sequential searching, digital +searching, hash tables, and binary searching. + +Sequential searching is simple, but slow (O(n)). Digital searching +requires that the entire data set be known in advance, and memory +efficient implementations are slow. + +Hash tables are fast (O(1)) for static data sets, but they can be +wasteful of memory. It can be difficult to choose an effective hash +function. Some hash tables variants also make deletion an expensive +operation. + +@cindex binary tree +Binary search techniques work almost as quickly (O(log(n)) on an ordered +table, or on a binary tree. Binary trees also allow easy iteration over +the data in the tree in sorted order. With hash tables it is necessary +to sort the data before iterating, and after sorting the data is no +longer in hash form. + +Binary trees are efficient for insertion, deletion, and searching, if +data are inserted in random order. But, if data are inserted in order +using a naive algorithm, binary search degenerates to sequential search. + +@cindex red-black tree +@cindex AVL tree +@cindex rebalancing +In turn, this problem can be solved by @dfn{rebalancing} the tree after +each insertion or deletion. In rebalancing, nodes are rearranged via +transformations called @dfn{rotations} using an algorithm that tends to +minimize the tree's height. + +There are several schemes for rebalancing binary trees. The two most +common types of balanced tree are @dfn{AVL trees} and @dfn{red-black +trees}. libavl implements both types: + +@itemize @bullet +@item +@cindex Landis, E. M. +@cindex Adel'son-Velskii, G. M. +AVL trees, invented by Russian mathematicians G. M. Adel'son-Velskii and +E. M. Landis, ensure that, for each node, the difference in height +between its subtrees (the @dfn{balance factor}) is not greater than 1. + +@item +Red-black trees, invented by R. Bayer and studied at length by +L. J. Guibas and R. Sedgewick, assign each node of a tree a color (red +or black), and specify a set of rules governing how red and black nodes +may be arranged. +@end itemize + +The table below presents a comparison among unbalanced binary trees, AVL +trees, and red-black trees. In the table, @var{n} is the number of +nodes in the tree and @var{h} is the tree's height before the +operation. @dfn{lg} is the base-2 logarithm function. + +@multitable @columnfractions .05 .30 .35 .30 + +@need 333 +@item @w{Operation} +@item +@tab Binary Tree +@tab AVL Tree +@tab Red-Black Tree + +@need 333 +@item @w{Time per insertion or deletion} +@item +@tab O(@var{h}) +@tab O(lg @var{n}) +@tab O(lg @var{n}) + +@need 333 +@item @w{Time for insertion of @var{k} nodes having sequential values} +@item +@tab O(@math{@var{k}^2}) +@tab O(@var{n} lg @var{n}) +@tab O(@var{n} lg @var{n}) + +@need 333 +@item @w{Time for insertion of @var{k} nodes having random values} +@item +@tab O(@var{n} lg @var{n}) +@tab O(@var{n} lg @var{n}) +@tab O(@var{n} lg @var{n}) + +@need 333 +@item @w{Maximum number of rotations per insertion} +@item +@tab 0 +@tab 1 +@tab lg @var{n} + +@need 333 +@item @w{Maximum number of rotations per deletion} +@item +@tab 0 +@tab lg @var{n} +@tab lg @var{n} + +@need 333 +@item @w{Maximum @var{h} as a function of @var{n}} +@item +@tab @var{n} +@tab 1.44 lg (@var{n} + 2) - .328 +@tab 2 lg (@var{n} + 1) + +@need 333 +@item @w{Minimum @var{n} as a function of @var{h}} +@item +@tab @var{h} +@tab 2^((@var{h} + .328) / 1.44) - 2 +@tab 2^(@var{h} / 2) - 1 +@end multitable + +There are alternatives to AVL trees that share some of their properties. +For instance, skip lists, 2-3 trees, and splay trees all allow O(log(n)) +insertion and deletion. The main disadvantage of these methods is that +their operations are not as well documented in the literature. + +@node Introduction to threaded trees, Types, Introduction to balanced binary trees, Top +@chapter Introduction to threaded trees + +@dfn{Threading} is a clever method that simplifies binary tree +traversal. + +Nodes in a unthreaded binary tree that have zero or one subnodes have +two or one null subnode pointers, respectively. In a threaded binary +tree, a left child pointer that would otherwise be null is used to point +to the node's inorder@footnote{In tree traversal, @dfn{inorder} refers +to visiting the nodes in their sorted order from smallest to largest.} +predecessor, and in a null right child pointer points to its inorder +successor. + +In a threaded tree, it is always possible to find the next node and the +previous node of a node, given only a pointer to the node in question. +In an unthreaded tree, it's also necessary to have a list of the nodes +between the node in question and root of the tree. + +Advantages of a threaded tree compared to an unthreaded one include: + +@itemize @bullet +@item +Faster traversal and less memory usage during traversal, since no stack +need be maintained. + +@item +Greater generality, since one can go from a node to its successor or +predecessor given only the node, simplifying algorithms that require +moving forward and backward in a tree. +@end itemize + +Some disadvantages of threaded trees are: + +@itemize @bullet +@item +Slower insertion and deletion, since threads need to be maintained. In +somes cases, this can be alleviated by constructing the tree as an +unthreaded tree, then threading it with a special libavl function. + +@item +In theory, threaded trees need two extra bits per node to indicate +whether each child pointer points to an ordinary node or the node's +successor/predecessor node. In libavl, however, these bits are stored +in a byte that is used for structure alignment padding in unthreaded +binary trees, so no extra storage is used. +@end itemize + +A @dfn{right-threaded binary tree} is similar to a threaded binary tree, +but threads are only maintained on the right side of each node. This +allows for traversal to the right (toward larger values) but not to the +left (toward smaller values). Right-threaded trees are convenient when +the properties of a threaded tree are desirable, but traversal in +reverse sort order is not necessary. Not threading the left links saves +time in insertions and deletions. + +Left-threaded binary trees also exist, but they are not implemented by +libavl. The same effect can be obtained by sorting the tree in the +opposite order. + +@node Types, Functions, Introduction to threaded trees, Top +@chapter Types + +The following types are defined and used by libavl: + +@deftp {Data Type} avl_tree +@deftpx {Data Type} avlt_tree +@deftpx {Data Type} avltr_tree +@deftpx {Data Type} rb_tree +These are the data types used to represent a tree. Although they are +defined in the libavl header files, it should never be necessary to +access them directly. Instead, all accesses should take place through +libavl functions. +@end deftp + +@deftp {Data Type} avl_node +@deftpx {Data Type} avlt_node +@deftpx {Data Type} avltr_node +@deftpx {Data Type} rb_node +These are the data types used to represent individual nodes in a tree. +Similar cautions apply as with @code{avl_tree} structures. +@end deftp + +@deftp {Data Type} avl_traverser +@deftpx {Data Type} avlt_traverser +@deftpx {Data Type} avltr_traverser +@deftpx {Data Type} rb_traverser +These are the data types used by the @code{avl_traverse} family of +functions to iterate across the tree. Again, these are opaque +structures. +@end deftp + +@deftp {Data Type} avl_comparison_func +Every tree must have an ordering defined by a function of this type. It +must have the following signature: + +@smallexample +int @var{compare} (const void *@var{a}, const void *@var{b}, void *@var{param}) +@end smallexample + +The return value is expected to be like that returned by @code{strcmp} +in the standard C library: negative if @var{a} < @var{b}, zero if +@var{a} = @var{b}, positive if @var{a} > @var{b}. @var{param} is an +arbitrary value defined by the user when the tree was created. +@end deftp + +@deftp {Data Type} avl_node_func +This is a class of function called to perform an operation on a data +item. Functions of this type have the following signature: + +@smallexample +void @var{operate} (void *@var{data}, void *@var{param}) +@end smallexample + +@var{data} is the data item and @var{param} is an arbitrary user-defined +value set when the tree was created. +@end deftp + +@deftp {Data Type} avl_copy_func + +This is a class of function called to make a new copy of a node's data. +Functions of this type have the following signature: + +@smallexample +void *@var{copy} (void *@var{data}, void *@var{param}) +@end smallexample + +The function should return a new copy of @var{data}. @var{param} is an +arbitrary user-defined value set when the tree was created. +@end deftp + +@defmac AVL_MAX_HEIGHT +This macro defines the maximum height of an AVL tree that can be handled +by functions that maintain a stack of nodes descended. The default +value is 32, which allows for AVL trees with a maximum number of nodes +between 5,704,880 and 4,294,967,295, depending on order of insertion. +This macro may be defined by the user before including any AVL tree +header file, in which case libavl will honor that value. +@end defmac + +@defmac RB_MAX_HEIGHT +This macro defines the maximum height of an AVL tree that can be handled +by functions that maintain a stack of nodes descended. The default +value is 32, which allows for red-black trees with a maximum number of +nodes of at least 65535. This macro may be defined by the user before +including the red-black tree header file, in which case libavl will +honor that value. +@end defmac + +@node Functions, Tree Creation, Types, Top +@chapter Functions + +@cindex unthreaded +@cindex threads +@cindex right threads +libavl is four libraries in one: + +@itemize @bullet +@item +An unthreaded AVL tree library. + +@item +A threaded AVL tree library. + +@item +A right-threaded AVL tree library. + +@item +A red-black tree library. +@end itemize + +Identifiers in these libraries are prefixed by @code{avl_}, +@code{avlt_}, @code{avltr_}, and @code{rb_}, with corresponding header +files @file{avl.h}, @file{avlt.h}, @file{avltr.h}, and @file{rb.h}, +respectively. The functions that they declare are defined in the +@file{.c} files with the same names. + +Most tree functions are implemented in all three libraries, but +threading allows more generality of operation. So, the threaded and +right-threaded libraries offer a few additional functions for finding +the next or previous node from a given node. In addition, they offer +functions for converting trees from threaded or right-threaded +representations to unthreaded, and vice versa.@footnote{In general, you +should build the sort of tree that you need to use, but occasionally it +is useful to convert between tree types.} + +@node Tree Creation, Insertion, Functions, Top +@chapter Tree Creation + +These functions deal with creation and destruction of AVL trees. + +@deftypefun {avl_tree *} avl_create (avl_comparison_func @var{compare}, void *@var{param}) +@deftypefunx {avlt_tree *} avlt_create (avlt_comparison_func @var{compare}, void *@var{param}) +@deftypefunx {avltr_tree *} avltr_create (avltr_comparison_func @var{compare}, void *@var{param}) +@deftypefunx {rb_tree *} rb_create (avl_comparison_func @var{compare}, void *@var{param}) +Create a new, empty tree with comparison function @var{compare}. +Arbitrary user data @var{param} is saved so that it can be passed to +user callback functions. +@end deftypefun + +@deftypefun {void} avl_destroy (avl_tree *@var{tree}, avl_node_func @var{free}) +@deftypefunx {void} avlt_destroy (avlt_tree *@var{tree}, avl_node_func @var{free}) +@deftypefunx {void} avltr_destroy (avltr_tree *@var{tree}, avl_node_func @var{free}) +@deftypefunx {void} rb_destroy (rb_tree *@var{tree}, avl_node_func @var{free}) +Destroys @var{tree}, releasing all of its storage. If @var{free} is +non-null, then it is called for every node in postorder before that node +is freed. +@end deftypefun + +@deftypefun {void} avl_free (avl_tree *@var{tree}) +@deftypefunx {void} avlt_free (avlt_tree *@var{tree}) +@deftypefunx {void} avltr_free (avltr_tree *@var{tree}) +@deftypefunx {void} rb_free (rb_tree *@var{tree}) +Destroys @var{tree}, releasing all of its storage. The data in each +node is freed with a call to the standard C library function +@code{free}. +@end deftypefun + +@deftypefun {avl_tree *} avl_copy (const avl_tree *@var{tree}, avl_copy_func @var{copy}) +@deftypefunx {avlt_tree *} avl_copy (const avlt_tree *@var{tree}, avl_copy_func @var{copy}) +@deftypefunx {avltr_tree *} avl_copy (const avltr_tree *@var{tree}, avl_copy_func @var{copy}) +@deftypefunx {rb_tree *} rb_copy (const rb_tree *@var{tree}, avl_copy_func @var{copy}) +Copies the contents of @var{tree} into a new tree, and returns the new +tree. If @var{copy} is non-null, then it is called to make a new copy +of each node's data; otherwise, the node data is copied verbatim into +the new tree. +@end deftypefun + +@deftypefun int avl_count (const avl_tree *@var{tree}) +@deftypefunx int avlt_count (const avlt_tree *@var{tree}) +@deftypefunx int avltr_count (const avltr_tree *@var{tree}) +@deftypefunx int rb_count (const rb_tree *@var{tree}) +Returns the number of nodes in @var{tree}. +@end deftypefun + +@deftypefun {void *} xmalloc (size_t @var{size}) +This is not a function defined by libavl. Instead, it is a function +that the user program can define. It must allocate @var{size} bytes +using @code{malloc} and return it. It can handle out-of-memory errors +however it chooses, but it may not ever return a null pointer. + +If there is an @code{xmalloc} function defined for use by libavl, the +source files (@file{avl.c}, @file{avlt.c}, @file{avltr.c}, @file{rb.c}) +must be compiled with @code{HAVE_XMALLOC} defined. Otherwise, the +library will use its internal static @code{xmalloc}, which handles +out-of-memory errors by printing a message @samp{virtual memory +exhausted} to stderr and terminating the program with exit code +@code{EXIT_FAILURE}. +@end deftypefun + +@node Insertion, Searching, Tree Creation, Top +@chapter Insertion and Deletion + +These function insert nodes, delete nodes, and search for nodes in +trees. + +@deftypefun {void **} avl_probe (avl_tree *@var{tree}, void *@var{data}) +@deftypefunx {void **} avlt_probe (avlt_tree *@var{tree}, void *@var{data}) +@deftypefunx {void **} avltr_probe (avltr_tree *@var{tree}, void *@var{data}) +@deftypefunx {void **} rb_probe (rb_tree *@var{tree}, void *@var{data}) +These are the workhorse functions for tree insertion. They search +@var{tree} for a node with data matching @var{data}. If found, a +pointer to the matching data is returned. Otherwise, a new node is +created for @var{data}, and a pointer to that data is returned. In +either case, the pointer returned can be changed by the user, but the +key data used by the tree's comparison must not be changed@footnote{It +can be changed if this would not change the ordering of the nodes in the +tree; i.e., if this would not cause the data in the node to be less than +or equal to the previous node's data or greater than or equal to the +next node's data.}. + +It is usually easier to use one of the @code{avl_insert} or +@code{avl_replace} functions instead of @code{avl_probe} directly. + +@strong{Please note:} It's not a particularly good idea to insert a null +pointer as a data item into a tree, because several libavl functions +return a null pointer to indicate failure. You can sometimes avoid a +problem by using functions that return a pointer to a pointer instead of +a plain pointer. Also be wary of this when casting an arithmetic type +to a void pointer for insertion---on typical architectures, 0's become +null pointers when this is done. +@end deftypefun + +@deftypefun {void *} avl_insert (avl_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} avlt_insert (avlt_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} avltr_insert (avltr_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} rb_insert (rb_tree *@var{tree}, void *@var{data}) +If a node with data matching @var{data} exists in @var{tree}, returns +the matching data item. Otherwise, inserts @var{data} into @var{tree} +and returns a null pointer. +@end deftypefun + +@deftypefun void avl_force_insert (avl_tree *@var{tree}, void *@var{data}) +@deftypefunx void avlt_force_insert (avlt_tree *@var{tree}, void *@var{data}) +@deftypefunx void avltr_force_insert (avltr_tree *@var{tree}, void *@var{data}) +@deftypefunx void rb_force_insert (rb_tree *@var{tree}, void *@var{data}) +Inserts @var{data} into @var{tree}. If a node with data matching +@var{data} exists in @var{tree}, aborts the program with an assertion +violation. This function is implemented as a macro; if it is used, the +standard C header @code{assert.h} must also be included. If macro +@code{NDEBUG} is defined when a libavl header is included, these +functions are short-circuited to a direct call to @code{avl_insert}, +and no check is performed. +@end deftypefun + +@deftypefun {void *} avl_replace (avl_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} avlt_replace (avlt_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} avltr_replace (avltr_tree *@var{tree}, void *@var{data}) +@deftypefunx {void *} rb_replace (rb_tree *@var{tree}, void *@var{data}) +If a node with data matching @var{data}, such that the comparison +function returns 0, exists in @var{tree}, replaces the node's data with +@var{data} and returns the node's former contents. Otherwise, inserts +@var{data} into @var{tree} and returns a null pointer. +@end deftypefun + +@deftypefun {void *} avl_delete (avl_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} avlt_delete (avlt_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} avltr_delete (avltr_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} rb_delete (rb_tree *@var{tree}, const void *@var{data}) +Searches @var{tree} for a node with data matching @var{data}. If found, +the node is deleted and its data is returned. Otherwise, returns a null +pointer. +@end deftypefun + +@deftypefun {void *} avl_force_delete (avl_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} avlt_force_delete (avlt_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} avltr_force_delete (avltr_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} rb_force_delete (rb_tree *@var{tree}, const void *@var{data}) +Deletes a node with data matching @var{data} from @var{tree}. If no +matching node is found, aborts the program with an assertion violation. +If macro @code{NDEBUG} is declared when a libavl header is included, +these functions are short-circuited to a direct call to +@code{avl_delete}, and no check is performed. +@end deftypefun + +@node Searching, Iteration, Insertion, Top +@chapter Searching + +These function search a tree for an item without making an insertion or +a deletion. + +@deftypefun {void *} avl_find (avl_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void **} avlt_find (avlt_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void **} avltr_find (avltr_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} rb_find (rb_tree *@var{tree}, const void *@var{data}) +Searches @var{tree} for a node with data matching @var{data}, If found, +returns the node's data (for threaded and right-threaded trees, a +pointer to the node's data). Otherwise, returns a null pointer. +@end deftypefun + +@deftypefun {void *} avl_find_close (avl_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void **} avlt_find_close (avlt_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void **} avltr_find_close (avltr_tree *@var{tree}, const void *@var{data}) +@deftypefunx {void *} rb_find_close (rb_tree *@var{tree}, const void *@var{data}) +Searches @var{tree} for a node with data matching @var{data}. If found, +returns the node's data (for threaded and right-threaded trees, a +pointer to the node's data). If no matching item is found, then it +finds a node whose data is ``close'' to @var{data}; either the node +closest in value to @var{data}, or the node either before or after the +node with the closest value. Returns a null pointer if the tree does +not contain any nodes. +@end deftypefun + +@node Iteration, Conversion, Searching, Top +@chapter Iteration + +These functions allow the caller to iterate across the items in a tree. + +@deftypefun void avl_walk (const avl_tree *@var{tree}, avl_node_func @var{operate}, void *@var{param}) +@deftypefunx void avlt_walk (const avlt_tree *@var{tree}, avl_node_func @var{operate}, void *@var{param}) +@deftypefunx void avltr_walk (const avltr_tree *@var{tree}, avl_node_func @var{operate}, void *@var{param}) +@deftypefunx void rb_walk (const rb_tree *@var{tree}, avl_node_func @var{operate}, void *@var{param}) +Walks through all the nodes in @var{tree}, and calls function +@var{operate} for each node in inorder. @var{param} overrides the value +passed to @code{avl_create} (and family) for this operation only. +@var{operate} must not change the key data in the nodes in a way that +would reorder the data values or cause two values to become equal. +@end deftypefun + +@deftypefun {void *} avl_traverse (const avl_tree *@var{tree}, avl_traverser *@var{trav}) +@deftypefunx {void *} avlt_traverse (const avlt_tree *@var{tree}, avlt_traverser *@var{trav}) +@deftypefunx {void *} avltr_traverse (const avltr_tree *@var{tree}, avltr_traverser *@var{trav}) +@deftypefunx {void *} rb_traverse (const rb_tree *@var{tree}, rb_traverser *@var{trav}) +Returns each of @var{tree}'s nodes' data values in sequence, then a null +pointer to indicate the last item. @var{trav} must be initialized +before the first call, either in a declaration like that below, or using +one of the functions below. + +@smallexample +avl_traverser trav = AVL_TRAVERSER_INIT; +@end smallexample + +Each @code{avl_traverser} (and family) is a separate, independent +iterator. + +For threaded and right-threaded trees, @code{avlt_next} or +@code{avltr_next}, respectively, are faster and more memory-efficient +than @code{avlt_traverse} or @code{avltr_traverse}. +@end deftypefun + +@deftypefun {void *} avl_init_traverser (avl_traverser *@var{trav}) +@deftypefunx {void *} avlt_init_traverser (avlt_traverser *@var{trav}) +@deftypefunx {void *} avltr_init_traverser (avltr_traverser *@var{trav}) +@deftypefunx {void *} rb_init_traverser (rb_traverser *@var{trav}) +Initializes the specified tree traverser structure. After this function +is called, the next call to the corresponding @code{*_traverse} function +will return the smallest value in the appropriate tree. +@end deftypefun + +@deftypefun {void **} avlt_next (const avlt_tree *@var{tree}, void **@var{data}) +@deftypefunx {void **} avltr_next (const avltr_tree *@var{tree}, void **@var{data}) +@var{data} must be a null pointer or a pointer to a data item in AVL +tree @var{tree}. Returns a pointer to the next data item after +@var{data} in @var{tree} in inorder (this is the first item if +@var{data} is a null pointer), or a null pointer if @var{data} was the +last item in @var{tree}. +@end deftypefun + +@deftypefun {void **} avltr_prev (const avltr_tree *@var{tree}, void **@var{data}) +@var{data} must be a null pointer or a pointer to a data item in AVL +tree @var{tree}. Returns a pointer to the previous data item before +@var{data} in @var{tree} in inorder (this is the last, or greatest +valued, item if @var{data} is a null pointer), or a null pointer if +@var{data} was the first item in @var{tree}. +@end deftypefun + +@node Conversion, Author, Iteration, Top +@chapter Conversion + +@deftypefun {avlt_tree *} avlt_thread (avl_tree *@var{tree}) +@deftypefunx {avltr_tree *} avltr_thread (avl_tree *@var{tree}) +Adds symmetric threads or right threads, respectively, to unthreaded AVL +tree @var{tree} and returns a pointer to @var{tree} cast to the +appropriate type. After one of these functions is called, threaded or +right-threaded functions, as appropriate, must be used with @var{tree}; +unthreaded functions may not be used. +@end deftypefun + +@deftypefun {avl_tree *} avlt_unthread (avlt_tree *@var{tree}) +@deftypefunx {avl_tree *} avltr_unthread (avltr_tree *@var{tree}) +Cuts all threads in threaded or right-threaded, respectively, AVL tree +@var{tree} and returns a pointer to @var{tree} cast to @code{avl_tree +*}. After one of these functions is called, unthreaded functions must +be used with @var{tree}; threaded or right-threaded functions may not be +used. +@end deftypefun + +@node Author, Index, Conversion, Top +@chapter Author + +@cindex Pfaff, Benjamin Levy +@cindex author +@cindex Knuth, Donald Ervin +@cindex @cite{Art of Computer Programming} +libavl was written by Ben Pfaff @email{blp@@gnu.org}. + +libavl's generic tree algorithms and AVL algorithms are based on those +found in Donald Knuth's venerable @cite{Art of Computer Programming} +series from Addison-Wesley, primarily Volumes 1 and 3. libavl's +red-black tree algorithms are based on those found in Cormen et al., +@cite{Introduction to Algorithms}, 2nd ed., from MIT Press. + +@node Index, , Author, Top +@unnumbered Index + +@printindex cp + +@contents +@bye diff --git a/avl-1.4.0/avl.text b/avl-1.4.0/avl.text new file mode 100644 index 0000000..9804050 --- /dev/null +++ b/avl-1.4.0/avl.text @@ -0,0 +1,636 @@ +This file documents libavl, a library for the manipulation of balanced +binary trees. + + Copyright 1998, 1999 Free Software Foundation, Inc. + + 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. + +This document +describes libavl, a library for manipulation of balanced binary trees. + + This document applies to libavl version 1.4.0. + +Introduction to balanced binary trees +************************************* + + Consider some techniques that can be used to find a particular item +in a data set. Typical methods include sequential searching, digital +searching, hash tables, and binary searching. + + Sequential searching is simple, but slow (O(n)). Digital searching +requires that the entire data set be known in advance, and memory +efficient implementations are slow. + + Hash tables are fast (O(1)) for static data sets, but they can be +wasteful of memory. It can be difficult to choose an effective hash +function. Some hash tables variants also make deletion an expensive +operation. + + Binary search techniques work almost as quickly (O(log(n)) on an +ordered table, or on a binary tree. Binary trees also allow easy +iteration over the data in the tree in sorted order. With hash tables +it is necessary to sort the data before iterating, and after sorting +the data is no longer in hash form. + + Binary trees are efficient for insertion, deletion, and searching, if +data are inserted in random order. But, if data are inserted in order +using a naive algorithm, binary search degenerates to sequential search. + + In turn, this problem can be solved by "rebalancing" the tree after +each insertion or deletion. In rebalancing, nodes are rearranged via +transformations called "rotations" using an algorithm that tends to +minimize the tree's height. + + There are several schemes for rebalancing binary trees. The two most +common types of balanced tree are "AVL trees" and "red-black trees". +libavl implements both types: + + * AVL trees, invented by Russian mathematicians G. M. + Adel'son-Velskii and E. M. Landis, ensure that, for each node, the + difference in height between its subtrees (the "balance factor") + is not greater than 1. + + * Red-black trees, invented by R. Bayer and studied at length by L. + J. Guibas and R. Sedgewick, assign each node of a tree a color (red + or black), and specify a set of rules governing how red and black + nodes may be arranged. + + The table below presents a comparison among unbalanced binary trees, +AVL trees, and red-black trees. In the table, N is the number of nodes +in the tree and H is the tree's height before the operation. "lg" is +the base-2 logarithm function. + +Operation + Binary Tree AVL Tree Red-Black Tree +Time per insertion or deletion + O(H) O(lg N) O(lg N) +Time for insertion of K nodes having sequential values + O(K^2) O(N lg N) O(N lg N) +Time for insertion of K nodes having random values + O(N lg N) O(N lg N) O(N lg N) +Maximum number of rotations per insertion + 0 1 lg N +Maximum number of rotations per deletion + 0 lg N lg N +Maximum H as a function of N + N 1.44 lg (N + 2) - .328 2 lg (N + 1) +Minimum N as a function of H + H 2^((H + .328) / 1.44) - 2 2^(H / 2) - 1 + + There are alternatives to AVL trees that share some of their +properties. For instance, skip lists, 2-3 trees, and splay trees all +allow O(log(n)) insertion and deletion. The main disadvantage of these +methods is that their operations are not as well documented in the +literature. + +Introduction to threaded trees +****************************** + + "Threading" is a clever method that simplifies binary tree traversal. + + Nodes in a unthreaded binary tree that have zero or one subnodes have +two or one null subnode pointers, respectively. In a threaded binary +tree, a left child pointer that would otherwise be null is used to point +to the node's inorder(1) predecessor, and in a null right child pointer +points to its inorder successor. + + In a threaded tree, it is always possible to find the next node and +the previous node of a node, given only a pointer to the node in +question. In an unthreaded tree, it's also necessary to have a list of +the nodes between the node in question and root of the tree. + + Advantages of a threaded tree compared to an unthreaded one include: + + * Faster traversal and less memory usage during traversal, since no + stack need be maintained. + + * Greater generality, since one can go from a node to its successor + or predecessor given only the node, simplifying algorithms that + require moving forward and backward in a tree. + + Some disadvantages of threaded trees are: + + * Slower insertion and deletion, since threads need to be + maintained. In somes cases, this can be alleviated by + constructing the tree as an unthreaded tree, then threading it + with a special libavl function. + + * In theory, threaded trees need two extra bits per node to indicate + whether each child pointer points to an ordinary node or the node's + successor/predecessor node. In libavl, however, these bits are + stored in a byte that is used for structure alignment padding in + unthreaded binary trees, so no extra storage is used. + + A "right-threaded binary tree" is similar to a threaded binary tree, +but threads are only maintained on the right side of each node. This +allows for traversal to the right (toward larger values) but not to the +left (toward smaller values). Right-threaded trees are convenient when +the properties of a threaded tree are desirable, but traversal in +reverse sort order is not necessary. Not threading the left links saves +time in insertions and deletions. + + Left-threaded binary trees also exist, but they are not implemented +by libavl. The same effect can be obtained by sorting the tree in the +opposite order. + + ---------- Footnotes ---------- + + (1) In tree traversal, "inorder" refers to visiting the nodes in +their sorted order from smallest to largest. + +Types +***** + + The following types are defined and used by libavl: + + - Data Type: avl_tree + - Data Type: avlt_tree + - Data Type: avltr_tree + - Data Type: rb_tree + These are the data types used to represent a tree. Although they + are defined in the libavl header files, it should never be + necessary to access them directly. Instead, all accesses should + take place through libavl functions. + + - Data Type: avl_node + - Data Type: avlt_node + - Data Type: avltr_node + - Data Type: rb_node + These are the data types used to represent individual nodes in a + tree. Similar cautions apply as with `avl_tree' structures. + + - Data Type: avl_traverser + - Data Type: avlt_traverser + - Data Type: avltr_traverser + - Data Type: rb_traverser + These are the data types used by the `avl_traverse' family of + functions to iterate across the tree. Again, these are opaque + structures. + + - Data Type: avl_comparison_func + Every tree must have an ordering defined by a function of this + type. It must have the following signature: + + int COMPARE (const void *A, const void *B, void *PARAM) + + The return value is expected to be like that returned by `strcmp' + in the standard C library: negative if A < B, zero if A = B, + positive if A > B. PARAM is an arbitrary value defined by the + user when the tree was created. + + - Data Type: avl_node_func + This is a class of function called to perform an operation on a + data item. Functions of this type have the following signature: + + void OPERATE (void *DATA, void *PARAM) + + DATA is the data item and PARAM is an arbitrary user-defined value + set when the tree was created. + + - Data Type: avl_copy_func + This is a class of function called to make a new copy of a node's + data. Functions of this type have the following signature: + + void *COPY (void *DATA, void *PARAM) + + The function should return a new copy of DATA. PARAM is an + arbitrary user-defined value set when the tree was created. + + - Macro: AVL_MAX_HEIGHT + This macro defines the maximum height of an AVL tree that can be + handled by functions that maintain a stack of nodes descended. + The default value is 32, which allows for AVL trees with a maximum + number of nodes between 5,704,880 and 4,294,967,295, depending on + order of insertion. This macro may be defined by the user before + including any AVL tree header file, in which case libavl will + honor that value. + + - Macro: RB_MAX_HEIGHT + This macro defines the maximum height of an AVL tree that can be + handled by functions that maintain a stack of nodes descended. + The default value is 32, which allows for red-black trees with a + maximum number of nodes of at least 65535. This macro may be + defined by the user before including the red-black tree header + file, in which case libavl will honor that value. + +Functions +********* + + libavl is four libraries in one: + + * An unthreaded AVL tree library. + + * A threaded AVL tree library. + + * A right-threaded AVL tree library. + + * A red-black tree library. + + Identifiers in these libraries are prefixed by `avl_', `avlt_', +`avltr_', and `rb_', with corresponding header files `avl.h', `avlt.h', +`avltr.h', and `rb.h', respectively. The functions that they declare +are defined in the `.c' files with the same names. + + Most tree functions are implemented in all three libraries, but +threading allows more generality of operation. So, the threaded and +right-threaded libraries offer a few additional functions for finding +the next or previous node from a given node. In addition, they offer +functions for converting trees from threaded or right-threaded +representations to unthreaded, and vice versa.(1) + + ---------- Footnotes ---------- + + (1) In general, you should build the sort of tree that you need to +use, but occasionally it is useful to convert between tree types. + +Tree Creation +************* + + These functions deal with creation and destruction of AVL trees. + + - Function: avl_tree * avl_create (avl_comparison_func COMPARE, void + *PARAM) + - Function: avlt_tree * avlt_create (avlt_comparison_func COMPARE, + void *PARAM) + - Function: avltr_tree * avltr_create (avltr_comparison_func COMPARE, + void *PARAM) + - Function: rb_tree * rb_create (avl_comparison_func COMPARE, void + *PARAM) + Create a new, empty tree with comparison function COMPARE. + Arbitrary user data PARAM is saved so that it can be passed to + user callback functions. + + - Function: void avl_destroy (avl_tree *TREE, avl_node_func FREE) + - Function: void avlt_destroy (avlt_tree *TREE, avl_node_func FREE) + - Function: void avltr_destroy (avltr_tree *TREE, avl_node_func FREE) + - Function: void rb_destroy (rb_tree *TREE, avl_node_func FREE) + Destroys TREE, releasing all of its storage. If FREE is non-null, + then it is called for every node in postorder before that node is + freed. + + - Function: void avl_free (avl_tree *TREE) + - Function: void avlt_free (avlt_tree *TREE) + - Function: void avltr_free (avltr_tree *TREE) + - Function: void rb_free (rb_tree *TREE) + Destroys TREE, releasing all of its storage. The data in each + node is freed with a call to the standard C library function + `free'. + + - Function: avl_tree * avl_copy (const avl_tree *TREE, avl_copy_func + COPY) + - Function: avlt_tree * avl_copy (const avlt_tree *TREE, avl_copy_func + COPY) + - Function: avltr_tree * avl_copy (const avltr_tree *TREE, + avl_copy_func COPY) + - Function: rb_tree * rb_copy (const rb_tree *TREE, avl_copy_func COPY) + Copies the contents of TREE into a new tree, and returns the new + tree. If COPY is non-null, then it is called to make a new copy + of each node's data; otherwise, the node data is copied verbatim + into the new tree. + + - Function: int avl_count (const avl_tree *TREE) + - Function: int avlt_count (const avlt_tree *TREE) + - Function: int avltr_count (const avltr_tree *TREE) + - Function: int rb_count (const rb_tree *TREE) + Returns the number of nodes in TREE. + + - Function: void * xmalloc (size_t SIZE) + This is not a function defined by libavl. Instead, it is a + function that the user program can define. It must allocate SIZE + bytes using `malloc' and return it. It can handle out-of-memory + errors however it chooses, but it may not ever return a null + pointer. + + If there is an `xmalloc' function defined for use by libavl, the + source files (`avl.c', `avlt.c', `avltr.c', `rb.c') must be + compiled with `HAVE_XMALLOC' defined. Otherwise, the library will + use its internal static `xmalloc', which handles out-of-memory + errors by printing a message `virtual memory exhausted' to stderr + and terminating the program with exit code `EXIT_FAILURE'. + +Insertion and Deletion +********************** + + These function insert nodes, delete nodes, and search for nodes in +trees. + + - Function: void ** avl_probe (avl_tree *TREE, void *DATA) + - Function: void ** avlt_probe (avlt_tree *TREE, void *DATA) + - Function: void ** avltr_probe (avltr_tree *TREE, void *DATA) + - Function: void ** rb_probe (rb_tree *TREE, void *DATA) + These are the workhorse functions for tree insertion. They search + TREE for a node with data matching DATA. If found, a pointer to + the matching data is returned. Otherwise, a new node is created + for DATA, and a pointer to that data is returned. In either case, + the pointer returned can be changed by the user, but the key data + used by the tree's comparison must not be changed(1). + + It is usually easier to use one of the `avl_insert' or + `avl_replace' functions instead of `avl_probe' directly. + + *Please note:* It's not a particularly good idea to insert a null + pointer as a data item into a tree, because several libavl + functions return a null pointer to indicate failure. You can + sometimes avoid a problem by using functions that return a pointer + to a pointer instead of a plain pointer. Also be wary of this + when casting an arithmetic type to a void pointer for + insertion--on typical architectures, 0's become null pointers when + this is done. + + - Function: void * avl_insert (avl_tree *TREE, void *DATA) + - Function: void * avlt_insert (avlt_tree *TREE, void *DATA) + - Function: void * avltr_insert (avltr_tree *TREE, void *DATA) + - Function: void * rb_insert (rb_tree *TREE, void *DATA) + If a node with data matching DATA exists in TREE, returns the + matching data item. Otherwise, inserts DATA into TREE and returns + a null pointer. + + - Function: void avl_force_insert (avl_tree *TREE, void *DATA) + - Function: void avlt_force_insert (avlt_tree *TREE, void *DATA) + - Function: void avltr_force_insert (avltr_tree *TREE, void *DATA) + - Function: void rb_force_insert (rb_tree *TREE, void *DATA) + Inserts DATA into TREE. If a node with data matching DATA exists + in TREE, aborts the program with an assertion violation. This + function is implemented as a macro; if it is used, the standard C + header `assert.h' must also be included. If macro `NDEBUG' is + defined when a libavl header is included, these functions are + short-circuited to a direct call to `avl_insert', and no check is + performed. + + - Function: void * avl_replace (avl_tree *TREE, void *DATA) + - Function: void * avlt_replace (avlt_tree *TREE, void *DATA) + - Function: void * avltr_replace (avltr_tree *TREE, void *DATA) + - Function: void * rb_replace (rb_tree *TREE, void *DATA) + If a node with data matching DATA, such that the comparison + function returns 0, exists in TREE, replaces the node's data with + DATA and returns the node's former contents. Otherwise, inserts + DATA into TREE and returns a null pointer. + + - Function: void * avl_delete (avl_tree *TREE, const void *DATA) + - Function: void * avlt_delete (avlt_tree *TREE, const void *DATA) + - Function: void * avltr_delete (avltr_tree *TREE, const void *DATA) + - Function: void * rb_delete (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA. If found, the + node is deleted and its data is returned. Otherwise, returns a + null pointer. + + - Function: void * avl_force_delete (avl_tree *TREE, const void *DATA) + - Function: void * avlt_force_delete (avlt_tree *TREE, const void + *DATA) + - Function: void * avltr_force_delete (avltr_tree *TREE, const void + *DATA) + - Function: void * rb_force_delete (rb_tree *TREE, const void *DATA) + Deletes a node with data matching DATA from TREE. If no matching + node is found, aborts the program with an assertion violation. If + macro `NDEBUG' is declared when a libavl header is included, these + functions are short-circuited to a direct call to `avl_delete', + and no check is performed. + + ---------- Footnotes ---------- + + (1) It can be changed if this would not change the ordering of the +nodes in the tree; i.e., if this would not cause the data in the node +to be less than or equal to the previous node's data or greater than or +equal to the next node's data. + +Searching +********* + + These function search a tree for an item without making an insertion +or a deletion. + + - Function: void * avl_find (avl_tree *TREE, const void *DATA) + - Function: void ** avlt_find (avlt_tree *TREE, const void *DATA) + - Function: void ** avltr_find (avltr_tree *TREE, const void *DATA) + - Function: void * rb_find (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA, If found, + returns the node's data (for threaded and right-threaded trees, a + pointer to the node's data). Otherwise, returns a null pointer. + + - Function: void * avl_find_close (avl_tree *TREE, const void *DATA) + - Function: void ** avlt_find_close (avlt_tree *TREE, const void *DATA) + - Function: void ** avltr_find_close (avltr_tree *TREE, const void + *DATA) + - Function: void * rb_find_close (rb_tree *TREE, const void *DATA) + Searches TREE for a node with data matching DATA. If found, + returns the node's data (for threaded and right-threaded trees, a + pointer to the node's data). If no matching item is found, then it + finds a node whose data is "close" to DATA; either the node + closest in value to DATA, or the node either before or after the + node with the closest value. Returns a null pointer if the tree + does not contain any nodes. + +Iteration +********* + + These functions allow the caller to iterate across the items in a +tree. + + - Function: void avl_walk (const avl_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void avlt_walk (const avlt_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void avltr_walk (const avltr_tree *TREE, avl_node_func + OPERATE, void *PARAM) + - Function: void rb_walk (const rb_tree *TREE, avl_node_func OPERATE, + void *PARAM) + Walks through all the nodes in TREE, and calls function OPERATE + for each node in inorder. PARAM overrides the value passed to + `avl_create' (and family) for this operation only. OPERATE must + not change the key data in the nodes in a way that would reorder + the data values or cause two values to become equal. + + - Function: void * avl_traverse (const avl_tree *TREE, avl_traverser + *TRAV) + - Function: void * avlt_traverse (const avlt_tree *TREE, + avlt_traverser *TRAV) + - Function: void * avltr_traverse (const avltr_tree *TREE, + avltr_traverser *TRAV) + - Function: void * rb_traverse (const rb_tree *TREE, rb_traverser + *TRAV) + Returns each of TREE's nodes' data values in sequence, then a null + pointer to indicate the last item. TRAV must be initialized + before the first call, either in a declaration like that below, or + using one of the functions below. + + avl_traverser trav = AVL_TRAVERSER_INIT; + + Each `avl_traverser' (and family) is a separate, independent + iterator. + + For threaded and right-threaded trees, `avlt_next' or + `avltr_next', respectively, are faster and more memory-efficient + than `avlt_traverse' or `avltr_traverse'. + + - Function: void * avl_init_traverser (avl_traverser *TRAV) + - Function: void * avlt_init_traverser (avlt_traverser *TRAV) + - Function: void * avltr_init_traverser (avltr_traverser *TRAV) + - Function: void * rb_init_traverser (rb_traverser *TRAV) + Initializes the specified tree traverser structure. After this + function is called, the next call to the corresponding + `*_traverse' function will return the smallest value in the + appropriate tree. + + - Function: void ** avlt_next (const avlt_tree *TREE, void **DATA) + - Function: void ** avltr_next (const avltr_tree *TREE, void **DATA) + DATA must be a null pointer or a pointer to a data item in AVL + tree TREE. Returns a pointer to the next data item after DATA in + TREE in inorder (this is the first item if DATA is a null + pointer), or a null pointer if DATA was the last item in TREE. + + - Function: void ** avltr_prev (const avltr_tree *TREE, void **DATA) + DATA must be a null pointer or a pointer to a data item in AVL + tree TREE. Returns a pointer to the previous data item before + DATA in TREE in inorder (this is the last, or greatest valued, + item if DATA is a null pointer), or a null pointer if DATA was the + first item in TREE. + +Conversion +********** + + - Function: avlt_tree * avlt_thread (avl_tree *TREE) + - Function: avltr_tree * avltr_thread (avl_tree *TREE) + Adds symmetric threads or right threads, respectively, to + unthreaded AVL tree TREE and returns a pointer to TREE cast to the + appropriate type. After one of these functions is called, + threaded or right-threaded functions, as appropriate, must be used + with TREE; unthreaded functions may not be used. + + - Function: avl_tree * avlt_unthread (avlt_tree *TREE) + - Function: avl_tree * avltr_unthread (avltr_tree *TREE) + Cuts all threads in threaded or right-threaded, respectively, AVL + tree TREE and returns a pointer to TREE cast to `avl_tree *'. + After one of these functions is called, unthreaded functions must + be used with TREE; threaded or right-threaded functions may not be + used. + +Author +****** + + libavl was written by Ben Pfaff . + + libavl's generic tree algorithms and AVL algorithms are based on +those found in Donald Knuth's venerable `Art of Computer Programming' +series from Addison-Wesley, primarily Volumes 1 and 3. libavl's +red-black tree algorithms are based on those found in Cormen et al., +`Introduction to Algorithms', 2nd ed., from MIT Press. + +Index +***** + +* Menu: + +* `Art of Computer Programming': Author. +* Adel'son-Velskii, G. M.: Introduction to balanced binary trees. +* author: Author. +* AVL tree: Introduction to balanced binary trees. +* avl_comparison_func: Types. +* avl_copy: Tree Creation. +* avl_copy_func: Types. +* avl_count: Tree Creation. +* avl_create: Tree Creation. +* avl_delete: Insertion. +* avl_destroy: Tree Creation. +* avl_find: Searching. +* avl_find_close: Searching. +* avl_force_delete: Insertion. +* avl_force_insert: Insertion. +* avl_free: Tree Creation. +* avl_init_traverser: Iteration. +* avl_insert: Insertion. +* AVL_MAX_HEIGHT: Types. +* avl_node: Types. +* avl_node_func: Types. +* avl_probe: Insertion. +* avl_replace: Insertion. +* avl_traverse: Iteration. +* avl_traverser: Types. +* avl_tree: Types. +* avl_walk: Iteration. +* avlt_count: Tree Creation. +* avlt_create: Tree Creation. +* avlt_delete: Insertion. +* avlt_destroy: Tree Creation. +* avlt_find: Searching. +* avlt_find_close: Searching. +* avlt_force_delete: Insertion. +* avlt_force_insert: Insertion. +* avlt_free: Tree Creation. +* avlt_init_traverser: Iteration. +* avlt_insert: Insertion. +* avlt_next: Iteration. +* avlt_node: Types. +* avlt_probe: Insertion. +* avlt_replace: Insertion. +* avlt_thread: Conversion. +* avlt_traverse: Iteration. +* avlt_traverser: Types. +* avlt_tree: Types. +* avlt_unthread: Conversion. +* avlt_walk: Iteration. +* avltr_count: Tree Creation. +* avltr_create: Tree Creation. +* avltr_delete: Insertion. +* avltr_destroy: Tree Creation. +* avltr_find: Searching. +* avltr_find_close: Searching. +* avltr_force_delete: Insertion. +* avltr_force_insert: Insertion. +* avltr_free: Tree Creation. +* avltr_init_traverser: Iteration. +* avltr_insert: Insertion. +* avltr_next: Iteration. +* avltr_node: Types. +* avltr_prev: Iteration. +* avltr_probe: Insertion. +* avltr_replace: Insertion. +* avltr_thread: Conversion. +* avltr_traverse: Iteration. +* avltr_traverser: Types. +* avltr_tree: Types. +* avltr_unthread: Conversion. +* avltr_walk: Iteration. +* binary tree: Introduction to balanced binary trees. +* hash table: Introduction to balanced binary trees. +* Knuth, Donald Ervin: Author. +* Landis, E. M.: Introduction to balanced binary trees. +* Pfaff, Benjamin Levy: Author. +* rb_copy: Tree Creation. +* rb_count: Tree Creation. +* rb_create: Tree Creation. +* rb_delete: Insertion. +* rb_destroy: Tree Creation. +* rb_find: Searching. +* rb_find_close: Searching. +* rb_force_delete: Insertion. +* rb_force_insert: Insertion. +* rb_free: Tree Creation. +* rb_init_traverser: Iteration. +* rb_insert: Insertion. +* RB_MAX_HEIGHT: Types. +* rb_node: Types. +* rb_probe: Insertion. +* rb_replace: Insertion. +* rb_traverse: Iteration. +* rb_traverser: Types. +* rb_tree: Types. +* rb_walk: Iteration. +* rebalancing: Introduction to balanced binary trees. +* red-black tree: Introduction to balanced binary trees. +* right threads: Functions. +* threads: Functions. +* unthreaded: Functions. +* xmalloc: Tree Creation. + diff --git a/avl-1.4.0/avlt.c b/avl-1.4.0/avlt.c new file mode 100644 index 0000000..d050fba --- /dev/null +++ b/avl-1.4.0/avlt.c @@ -0,0 +1,1597 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avlt.c in libavl. */ + +#if HAVE_CONFIG_H +#include +#endif +#if SELF_TEST +#include +#include +#endif +#include +#include +#include +#include +#include "avlt.h" + +/* Tag types. */ +#define PLUS +1 +#define MINUS -1 + +#if !__GCC__ && !defined (inline) +#define inline +#endif + +#if __GNUC__ >= 2 +#define unused __attribute__ ((unused)) +#else +#define unused +#endif + +#ifdef HAVE_XMALLOC +void *xmalloc (size_t); +#else /* !HAVE_XMALLOC */ +/* Allocates SIZE bytes of space using malloc(). Aborts if out of + memory. */ +static void * +xmalloc (size_t size) +{ + void *vp; + if (size == 0) + return NULL; + vp = malloc (size); + assert (vp != NULL); + if (vp == NULL) + { + fprintf (stderr, "virtual memory exhausted\n"); + exit (EXIT_FAILURE); + } + return vp; +} +#endif /* !HAVE_XMALLOC */ + +/* Creates an AVL tree in arena OWNER (which can be NULL). The arena + is owned by the caller, not by the AVL tree. CMP is a order + function for the data to be stored in the tree. PARAM is arbitrary + data that becomes an argument to the comparison function. */ +avlt_tree * +avlt_create (avl_comparison_func cmp, void *param) +{ + avlt_tree *tree; + + assert (cmp != NULL); + tree = xmalloc (sizeof (avlt_tree)); + + tree->root.link[0] = tree->root.link[1] = &tree->root; + tree->root.tag[0] = MINUS; + tree->root.tag[1] = PLUS; + tree->cmp = cmp; + tree->count = 0; + tree->param = param; + + return tree; +} + +/* Destroy tree TREE. Function FREE_FUNC is called for every node in + the tree as it is destroyed. + + No effect if the tree has an arena owner and free_func is NULL. + The caller owns the arena and must destroy it itself. + + Do not attempt to reuse the tree after it has been freed. Create a + new one. */ +void +avlt_destroy (avlt_tree *tree, avl_node_func free_func) +{ + assert (tree != NULL); + + if (tree->root.link[0] != &tree->root) + { + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal). */ + + /* T1. */ + avlt_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + avlt_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + for (;;) + { + /* T3. */ + ab[ap] = 0; + an[ap++] = p; + if (p->tag[0] == MINUS) + break; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if (ab[ap] == 0) + { + ab[ap++] = 1; + if (p->tag[1] == MINUS) + continue; + p = p->link[1]; + break; + } + + if (free_func) + free_func (p->data, tree->param); + free (p); + } + } + } + + done: + free (tree); +} + +/* avlt_destroy() with FREE_FUNC hardcoded as free(). */ +void +avlt_free (avlt_tree *tree) +{ + avlt_destroy (tree, (avl_node_func) free); +} + +/* Return the number of nodes in TREE. */ +int +avlt_count (const avlt_tree *tree) +{ + assert (tree != NULL); + return tree->count; +} + +/* Copy the contents of TREE to a new tree in arena OWNER. If COPY is + non-NULL, then each data item is passed to function COPY, and the + return values are inserted into the new tree; otherwise, the items + are copied verbatim from the old tree to the new tree. Returns the + new tree. */ +avlt_tree * +avlt_copy (const avlt_tree *tree, avl_copy_func copy) +{ + /* Knuth's Algorithm 2.3.1C (copying a binary tree). Additionally + uses Algorithm 2.3.1I (insertion into a threaded binary tree) and + Algorithm 2.3.1 exercise 17 (preorder successor in threaded + binary tree). */ + + avlt_tree *new_tree; + + const avlt_node *p; + avlt_node *q; + + assert (tree != NULL); + new_tree = avlt_create (tree->cmp, tree->param); + new_tree->count = tree->count; + p = &tree->root; + if (p->link[0] == p) + return new_tree; + q = &new_tree->root; + + for (;;) + { + /* C4. This is Algorithm 2.3.1I modified for insertion to the + left. Step I2 is not necessary. */ + if (p->tag[0] == PLUS) + { + avlt_node *r = xmalloc (sizeof (avlt_node)); + + r->link[0] = q->link[0]; + r->tag[0] = q->tag[0]; + q->link[0] = r; + q->tag[0] = PLUS; + r->link[1] = q; + r->tag[1] = MINUS; + } + + /* C5: Find preorder successors of P and Q. This is Algorithm + 2.3.1 exercise 17 but applies its actions to Q as well as + P. */ + if (p->tag[0] == PLUS) + { + p = p->link[0]; + q = q->link[0]; + } + else + { + while (p->tag[1] == MINUS) + { + p = p->link[1]; + q = q->link[1]; + } + p = p->link[1]; + q = q->link[1]; + } + + /* C6. */ + if (p == &tree->root) + { + assert (q == &new_tree->root); + return new_tree; + } + + /* C2. This is Algorithm 2.3.1I. Step I2 is not necessary. */ + if (p->tag[1] == PLUS) + { + avlt_node *r = xmalloc (sizeof (avlt_node)); + + r->link[1] = q->link[1]; + r->tag[1] = q->tag[1]; + q->link[1] = r; + q->tag[1] = PLUS; + r->link[0] = q; + r->tag[0] = MINUS; + } + + /* C3. */ + q->bal = p->bal; + if (copy == NULL) + q->data = p->data; + else + q->data = copy (p->data, tree->param); + } +} + +/* Threads the unthreaded AVL tree TREE in-place, and returns TREE cast to + avlt_tree *. */ +avlt_tree * +avlt_thread (struct avl_tree *_tree) +{ + /* Uses Knuth's Algorithm 2.3.1 exercise 30 (thread an unthreaded + tree, with Algorithm 2.3.1T (inorder traversal) for computing + Q$. */ + + avlt_tree *tree = (avlt_tree *) _tree; + + /* Algorithm T's variables. */ + avlt_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + avlt_node **ap; /* Stack A: stack pointer. */ + avlt_node *tp; /* P. */ + + /* Algorithm L's variables. */ + avlt_node *p, *q; + + assert (tree != NULL); + + /* T1. */ + ap = an; + tp = tree->root.link[0]; + + /* L1. */ + q = &tree->root; + q->link[1] = q; + + for (;;) + { + /* L2. */ + { + /* T2. */ + while (tp != NULL) + { + /* T3. */ + *ap++ = tp; + tp = tp->link[0]; + } + + /* T4. Modified to visit HEAD after fully traversing the + tree. */ + if (ap == an) + tp = &tree->root; + else + tp = *--ap; + + /* T5: Visit P. */ + p = tp; + } + + /* L3. */ + if (q->link[1] == NULL) + { + q->link[1] = p; + q->tag[1] = MINUS; + } + else + q->tag[1] = PLUS; + + if (p->link[0] == NULL) + { + p->link[0] = q; + p->tag[0] = MINUS; + } + else + p->tag[0] = PLUS; + + /* L4. */ + if (p == &tree->root) + return tree; + q = p; + + /* T5: Next. */ + tp = tp->link[1]; + } +} + +/* Unthreads the threaded tree TREE in-place, and returns TREE cast to + avl_tree *. */ +struct avl_tree * +avlt_unthread (avlt_tree *tree) +{ + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal). */ + + /* T1. */ + avlt_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + avlt_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p != &tree->root) + for (;;) + { + /* T2. */ + for (;;) + { + /* T3. */ + ab[ap] = 0; + an[ap++] = p; + if (p->tag[0] == MINUS) + break; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if (ab[ap] == 0) + { + ab[ap++] = 1; + if (p->tag[1] == MINUS) + continue; + p = p->link[1]; + break; + } + + if (p->tag[0] == MINUS) + p->link[0] = NULL; + if (p->tag[1] == MINUS) + p->link[1] = NULL; + } + } + else + tree->root.link[0] = NULL; + + done: + tree->root.link[1] = NULL; + return (struct avl_tree *) tree; +} + +/* Walk tree TREE in inorder, calling WALK_FUNC at each node. Passes + PARAM to WALK_FUNC. */ +void +avlt_walk (const avlt_tree *tree, avl_node_func walk_func, void *param) +{ + const avlt_node *p; + + /* Uses Knuth's algorithm 2.3.1D (threaded inorder successor). */ + assert (tree && walk_func); + + p = &tree->root; + for (;;) + { + if (p->tag[1] == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->tag[0] == PLUS) + p = p->link[0]; + } + + if (p == &tree->root) + return; + + walk_func (p->data, param); + } +} + +/* Each call to this function for a given TREE and TRAV return the + next item in the tree in inorder. Initialize the first element of + TRAV (init) to 0 before calling the first time. Returns NULL when + out of elements. */ +void * +avlt_traverse (const avlt_tree *tree, avlt_traverser *trav) +{ + const avlt_node *p; + + assert (tree && trav); + + if (trav->init == 0) + { + p = &tree->root; + trav->init = 1; + } + else + p = trav->p; + + /* Knuth's Algorithm 2.3.1S (threaded inorder successor). */ + if (p->tag[1] == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->tag[0] == PLUS) + p = p->link[0]; + } + + if (p == &tree->root) + { + trav->init = 0; + return NULL; + } + else + { + trav->p = p; + return (void *) p->data; + } +} + +/* Given ITEM, a pointer to a data item in TREE (or NULL), returns a + pointer to the next item in the tree in comparison order, or NULL + if ITEM is the last item. */ +void ** +avlt_next (const avlt_tree *tree, void **item) +{ + const avlt_node *p; + + assert (tree != NULL); + if (item == NULL) + p = &tree->root; + else + p = (avlt_node *) (((char *) item) - offsetof (avlt_node, data)); + + /* Knuth's Algorithm 2.3.1S (threaded inorder successor). */ + if (p->tag[1] == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->tag[0] == PLUS) + p = p->link[0]; + } + + if (p == &tree->root) + return NULL; + + return (void **) &p->data; +} + +/* Given ITEM, a pointer to a data item in TREE (or NULL), returns a + pointer to the previous item in the tree in comparison order, or + NULL if ITEM is the first item. */ +void ** +avlt_prev (const avlt_tree *tree, void **item) +{ + const avlt_node *p; + + assert (tree != NULL); + if (item == NULL) + { + /* Find node with greatest value. */ + p = tree->root.link[0]; + if (p == &tree->root) + return NULL; + while (p->tag[1] == PLUS) + p = p->link[1]; + } + else + { + p = (avlt_node *) (((char *) item) - offsetof (avlt_node, data)); + + /* Knuth's Algorithm 2.3.1S (threaded inorder successor) + modified to find the predecessor node. */ + if (p->tag[0] == MINUS) + p = p->link[0]; + else + { + assert (p->tag[0] == PLUS); + p = p->link[0]; + while (p->tag[1] == PLUS) + p = p->link[1]; + } + } + + if (p == &tree->root) + return NULL; + + return (void **) &p->data; +} + +/* Search TREE for an item matching ITEM. If found, returns a pointer + to the address of the item. If none is found, ITEM is inserted + into the tree, and a pointer to the address of ITEM is returned. + In either case, the pointer returned can be changed by the caller, + or the returned data item can be directly edited, but the key data + in the item must not be changed. */ +void ** +avlt_probe (avlt_tree *tree, void *item) +{ + /* Uses Knuth's Algorithm 6.2.3A (balanced tree search and + insertion), modified for a threaded binary tree. Caches results + of comparisons. In empirical tests this eliminates about 25% of + the comparisons seen under random insertions. */ + + /* A1. */ + avlt_node *t; + avlt_node *s, *p, *q, *r; + + assert (tree != NULL); + t = &tree->root; + s = p = t->link[0]; + + if (t->tag[0] == MINUS) + { + tree->count++; + assert (tree->count == 1); + t->tag[0] = PLUS; + q = t->link[0] = xmalloc (sizeof (avlt_node)); + q->data = item; + q->link[0] = q->link[1] = t; + q->tag[0] = q->tag[1] = MINUS; + q->bal = 0; + return &q->data; + } + + for (;;) + { + /* A2. */ + int diff = tree->cmp (item, p->data, tree->param); + + /* A3. */ + if (diff < 0) + { + p->cache = 0; + q = p->link[0]; + if (p->tag[0] == MINUS) + { + q = xmalloc (sizeof (avlt_node)); + q->link[0] = p->link[0]; + q->tag[0] = p->tag[0]; + p->link[0] = q; + p->tag[0] = PLUS; + q->link[1] = p; + q->tag[1] = MINUS; + break; + } + } + /* A4. */ + else if (diff > 0) + { + p->cache = 1; + q = p->link[1]; + if (p->tag[1] == MINUS) + { + q = xmalloc (sizeof (avlt_node)); + q->link[1] = p->link[1]; + q->tag[1] = p->tag[1]; + p->link[1] = q; + p->tag[1] = PLUS; + q->link[0] = p; + q->tag[0] = MINUS; + break; + } + } + else + /* A2. */ + return &p->data; + + /* A3, A4. */ + if (q->bal != 0) + t = p, s = q; + p = q; + } + + /* A5. */ + tree->count++; + q->data = item; + q->bal = 0; + + /* A6. */ + r = p = s->link[(int) s->cache]; + while (p != q) + { + p->bal = p->cache * 2 - 1; + p = p->link[(int) p->cache]; + } + + /* A7. */ + if (s->cache == 0) + { + /* a = -1. */ + if (s->bal == 0) + { + s->bal = -1; + return &q->data; + } + else if (s->bal == +1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == -1); + if (r->bal == -1) + { + /* A8. */ + p = r; + s->link[0] = r->link[1]; + s->tag[0] = r->tag[1]; + r->link[1] = s; + r->tag[1] = PLUS; + if (s->link[0] == s) + { + s->link[0] = r; + s->tag[0] = MINUS; + } + r->tag[0] = r->tag[1] = PLUS; + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == +1); + p = r->link[1]; + r->link[1] = p->link[0]; + p->link[0] = r; + s->link[0] = p->link[1]; + p->link[1] = s; + if (p->bal == -1) + s->bal = 1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == +1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + p->tag[0] = p->tag[1] = PLUS; + if (s->link[0] == s) + { + s->link[0] = p; + s->tag[0] = MINUS; + } + if (r->link[1] == r) + { + r->link[1] = p; + r->tag[1] = MINUS; + } + } + } + else + { + /* a == +1. */ + if (s->bal == 0) + { + s->bal = 1; + return &q->data; + } + else if (s->bal == -1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == +1); + if (r->bal == +1) + { + /* A8. */ + p = r; + s->link[1] = r->link[0]; + s->tag[1] = r->tag[0]; + r->link[0] = s; + r->tag[0] = PLUS; + if (s->link[1] == s) + { + s->link[1] = r; + s->tag[1] = MINUS; + } + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == -1); + p = r->link[0]; + r->link[0] = p->link[1]; + p->link[1] = r; + s->link[1] = p->link[0]; + p->link[0] = s; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = 1; + } + p->tag[0] = p->tag[1] = PLUS; + if (s->link[1] == s) + { + s->link[1] = p; + s->tag[1] = MINUS; + } + if (r->link[0] == r) + { + r->link[0] = p; + r->tag[0] = MINUS; + } + p->bal = 0; + } + } + + /* A10. */ + if (t != &tree->root && s == t->link[1]) + t->link[1] = p; + else + t->link[0] = p; + + return &q->data; +} + +/* Search TREE for an item matching ITEM, and return a pointer to it + if found. */ +void ** +avlt_find (const avlt_tree *tree, const void *item) +{ + const avlt_node *p; + + assert (tree != NULL); + if (tree->root.tag[0] == MINUS) + /* Tree is empty. */ + return NULL; + + p = tree->root.link[0]; + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + int t; + + /* A3. */ + if (diff < 0) + t = 0; + else if (diff > 0) + t = 1; + else + return (void **) &p->data; + + if (p->tag[t] == PLUS) + p = p->link[t]; + else + return NULL; + } +} + +/* Search TREE for an item close to the value of ITEM, and return it. + This function will return a null pointer only if TREE is empty. */ +void ** +avlt_find_close (const avlt_tree *tree, const void *item) +{ + const avlt_node *p; + + assert (tree != NULL); + if (tree->root.tag[0] == MINUS) + /* Tree is empty. */ + return NULL; + + p = tree->root.link[0]; + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + int t; + + /* A3. */ + if (diff < 0) + t = 0; + else if (diff > 0) + t = 1; + else + return (void **) &p->data; + + if (p->tag[t] == PLUS) + p = p->link[t]; + else + return (void **) &p->data; + } +} + +/* Searches AVL tree TREE for an item matching ITEM. If found, the + item is removed from the tree and the actual item found is returned + to the caller. If no item matching ITEM exists in the tree, + returns NULL. */ +void * +avlt_delete (avlt_tree *tree, const void *item) +{ + /* Uses my Algorithm DT, which can be found at + http://www.msu.edu/user/pfaffben/avl. Algorithm DT is based on + Knuth's Algorithms 6.2.2D (Tree deletion), 6.2.3A (Balanced tree + search and insertion), 2.3.1I (Insertion into a threaded binary + trees), and the notes on pages 465-466 of Vol. 3. */ + + /* D1. */ + avlt_node *pa[AVL_MAX_HEIGHT]; /* Stack P: Nodes. */ + unsigned char a[AVL_MAX_HEIGHT]; /* Stack P: Bits. */ + int k = 1; /* Stack P: Pointer. */ + + avlt_node *p; + + assert (tree != NULL); + + if (tree->root.tag[0] == MINUS) + /* Empty tree. */ + return NULL; + + a[0] = 0; + pa[0] = &tree->root; + p = tree->root.link[0]; + for (;;) + { + /* D2. */ + int diff = tree->cmp (item, p->data, tree->param); + + if (diff == 0) + break; + + /* D3, D4. */ + pa[k] = p; + if (diff < 0) + { + if (p->tag[0] == PLUS) + { + p = p->link[0]; + a[k] = 0; + } + else + return NULL; + } + else if (diff > 0) + { + if (p->tag[1] == PLUS) + { + p = p->link[1]; + a[k] = 1; + } + else + return NULL; + } + + k++; + } + tree->count--; + + item = p->data; + + { + avlt_node *t = p; + avlt_node **q = &pa[k - 1]->link[(int) a[k - 1]]; + + /* D5. */ + if (t->tag[1] == MINUS) + { + if (t->tag[0] == PLUS) + { + avlt_node *const x = t->link[0]; + + *q = x; + (*q)->bal = 0; + if (x->tag[1] == MINUS) + { + if (a[k - 1] == 1) + x->link[1] = t->link[1]; + else + x->link[1] = pa[k - 1]; + } + } + else + { + *q = t->link[a[k - 1]]; + pa[k - 1]->tag[a[k - 1]] = MINUS; + } + } + else + { + /* D6. */ + avlt_node *r = t->link[1]; + if (r->tag[0] == MINUS) + { + r->link[0] = t->link[0]; + r->tag[0] = t->tag[0]; + r->bal = t->bal; + if (r->tag[0] == PLUS) + { + avlt_node *s = r->link[0]; + while (s->tag[1] == PLUS) + s = s->link[1]; + assert (s->tag[1] == MINUS); + s->link[1] = r; + } + *q = r; + a[k] = 1; + pa[k++] = r; + } + else + { + /* D7. */ + avlt_node *s = r->link[0]; + + a[k] = 1; + pa[k++] = t; + + a[k] = 0; + pa[k++] = r; + + /* D8. */ + while (s->tag[0] != MINUS) + { + r = s; + s = r->link[0]; + a[k] = 0; + pa[k++] = r; + } + + /* D9. */ + t->data = s->data; + if (s->tag[1] == MINUS) + { + r->tag[0] = MINUS; + r->link[0] = t; + } + else + { + r->link[0] = s->link[1]; + if (s->link[1]->tag[0] == MINUS) + s->link[1]->link[0] = t; + } + p = s; + } + } + } + + free (p); + + assert (k > 0); + /* D10. */ + while (--k) + { + avlt_node *const s = pa[k]; + + if (a[k] == 0) + { + avlt_node *const r = s->link[1]; + + /* D10. */ + if (s->bal == -1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = +1; + break; + } + + assert (s->bal == +1); + if (s->tag[1] == MINUS || r->bal == 0) + { + /* D11. */ + s->link[1] = r->link[0]; + r->link[0] = s; + r->bal = -1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == +1) + { + /* D12. */ + if (PLUS == (s->tag[1] = r->tag[0])) + s->link[1] = r->link[0]; + r->link[0] = s; + r->tag[0] = PLUS; + s->bal = r->bal = 0; + pa[k - 1]->link[a[k - 1]] = r; + } + else + { + /* D13. */ + assert (r->bal == -1); + p = r->link[0]; + if (PLUS == (r->tag[0] = p->tag[1])) + r->link[0] = p->link[1]; + p->link[1] = r; + p->tag[1] = PLUS; + if (MINUS == (s->tag[1] = p->tag[0])) + s->link[1] = p; + else + s->link[1] = p->link[0]; + p->link[0] = s; + p->tag[0] = PLUS; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = +1; + } + p->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = p; + pa[k - 1]->tag[(int) a[k - 1]] = PLUS; + } + } + else + { + avlt_node *const r = s->link[0]; + + /* D10. */ + if (s->bal == +1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = -1; + break; + } + + assert (s->bal == -1); + if (s->tag[0] == MINUS || r->bal == 0) + { + /* D11. */ + s->link[0] = r->link[1]; + r->link[1] = s; + r->bal = +1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == -1) + { + /* D12. */ + if (PLUS == (s->tag[0] = r->tag[1])) + s->link[0] = r->link[1]; + r->link[1] = s; + r->tag[1] = PLUS; + s->bal = r->bal = 0; + pa[k - 1]->link[a[k - 1]] = r; + } + else + { + /* D13. */ + assert (r->bal == +1); + p = r->link[1]; + if (PLUS == (r->tag[1] = p->tag[0])) + r->link[1] = p->link[0]; + p->link[0] = r; + p->tag[0] = PLUS; + if (MINUS == (s->tag[0] = p->tag[1])) + s->link[0] = p; + else + s->link[0] = p->link[1]; + p->link[1] = s; + p->tag[1] = PLUS; + if (p->bal == -1) + s->bal = +1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == +1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = p; + pa[k - 1]->tag[(int) a[k - 1]] = PLUS; + } + } + } + + return (void *) item; +} + +/* Inserts ITEM into TREE. Returns NULL if the item was inserted, + otherwise a pointer to the duplicate item. */ +void * +avlt_insert (avlt_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avlt_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +/* If ITEM does not exist in TREE, inserts it and returns NULL. If a + matching item does exist, it is replaced by ITEM and the item + replaced is returned. The caller is responsible for freeing the + item returned. */ +void * +avlt_replace (avlt_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avlt_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} + +/* Delete ITEM from TREE when you know that ITEM must be in TREE. For + debugging purposes. */ +void * +(avlt_force_delete) (avlt_tree *tree, void *item) +{ + void *found = avlt_delete (tree, item); + assert (found != NULL); + return found; +} + +#if SELF_TEST + +/* Size of the tree used for testing. */ +#define TREE_SIZE 1024 + +/* Used to flag delayed aborting. */ +int done = 0; + +/* Count the number of nodes in TREE below and including NODE. */ +int +count (avlt_tree *tree, avlt_node *node) +{ + int n = 1; + if (node->tag[0] == PLUS) + n += count (tree, node->link[0]); + if (node->tag[1] == PLUS) + n += count (tree, node->link[1]); + return n; +} + +/* Print the structure of node NODE of an avl tree, which is LEVEL + levels from the top of the tree. Uses different delimiters to + visually distinguish levels. */ +void +print_structure (avlt_tree *tree, avlt_node *node, int level) +{ + char lc[] = "([{<`"; + char rc[] = ")]}>'"; + + assert (node != NULL); + if (level >= 10) + { + printf ("Too deep, giving up.\n"); + done = 1; + return; + } + if (node == &tree->root) + { + printf (" root"); + return; + } + printf (" %c%d", lc[level % 5], (int) node->data); + fflush (stdout); + + { + int i; + + for (i = 0; i <= 1; i++) + { + if (node->tag[i] == PLUS) + print_structure (tree, node->link[i], level + 1); + else if (node->link[i] != &tree->root) + printf (" :%d", (int) node->link[i]->data); + else + printf (" :r"); + fflush (stdout); + } + } + printf ("%c", rc[level % 5]); + fflush (stdout); +} + +/* Compare two integers A and B and return a strcmp()-type result. */ +int +compare_ints (const void *a, const void *b, void *param unused) +{ + return ((int) a) - ((int) b); +} + +/* Print the value of integer A. */ +void +print_int (void *a, void *param unused) +{ + printf (" %d", (int) a); +} + +/* Linearly print contents of TREE. */ +void +print_contents (avlt_tree *tree) +{ + avlt_walk (tree, print_int, NULL); + printf ("\n"); +} + +/* Examine NODE in a avl tree. *COUNT is increased by the number of + nodes in the tree, including the current one. If the node is the + root of the tree, PARENT should be INT_MIN, otherwise it should be + the parent node value. DIR is the direction that the current node + is linked from the parent: -1 for left child, +1 for right child; + it is not used if PARENT is INT_MIN. Returns the height of the + tree rooted at NODE. */ +int +recurse_tree (avlt_tree *tree, avlt_node *node, int *count, int parent, + int dir, unsigned char *nodes, unsigned char *threads) +{ + if (node != &tree->root) + { + int d = (int) node->data; + int nl = 0; + int nr = 0; + + (*count)++; + + assert (d >= 0 && d < TREE_SIZE); + if (nodes[d / 8] & (1 << (d % 8))) + { + printf (" Arrived at node %d by two different paths.\n", d); + done = 1; + } + else + nodes[d / 8] |= 1 << (d % 8); + + if (node->tag[0] == PLUS) + nl = recurse_tree (tree, node->link[0], count, d, -1, nodes, threads); + else if (node->link[0] != &tree->root) + { + int dl = (int) node->link[0]->data; + assert (dl >= 0 && dl < TREE_SIZE); + threads[dl / 8] |= 1 << (dl % 8); + } + + if (node->tag[1] == PLUS) + nr = recurse_tree (tree, node->link[1], count, d, 1, nodes, threads); + else if (node->link[1] != &tree->root) + { + int dr = (int) node->link[1]->data; + assert (dr >= 0 && dr < TREE_SIZE); + threads[dr / 8] |= 1 << (dr % 8); + } + + if (nr - nl != node->bal) + { + printf (" Node %d has incorrect balance: right height=%d, " + "left height=%d, difference=%d, but balance factor=%d.\n", + d, nr, nl, nr - nl, node->bal); + done = 1; + } + + if (node->bal < -1 || node->bal > 1) + { + printf (" Node %d has invalid balance factor %d.\n", + d, node->bal); + done = 1; + } + + if (parent != INT_MIN) + { + assert (dir == -1 || dir == +1); + if (dir == -1 && d > parent) + { + printf (" Node %d is smaller than its left child %d.\n", + parent, d); + done = 1; + } + else if (dir == +1 && d < parent) + { + printf (" Node %d is larger than its right child %d.\n", + parent, d); + done = 1; + } + } + assert (node->bal >= -1 && node->bal <= 1); + return 1 + (nl > nr ? nl : nr); + } + else return 0; +} + +/* Check that everything about TREE is kosher. */ +void +verify_tree (avlt_tree *tree) +{ + { + unsigned char nodes[(TREE_SIZE + 7) / 8]; + unsigned char threads[(TREE_SIZE + 7) / 8]; + + int count = 0; + int i; + + memset (nodes, 0, (TREE_SIZE + 7) / 8); + memset (threads, 0, (TREE_SIZE + 7) / 8); + + recurse_tree (tree, tree->root.link[0], &count, INT_MIN, 0, nodes, + threads); + + if (count != tree->count) + { + printf (" Tree should have %d nodes, but tree count by recursive " + "descent is %d.\n", tree->count, count); + done = 1; + } + + for (i = 0; i < TREE_SIZE; i++) + { + int thread = threads[i / 8] & (1 << (i % 8)); + int node = nodes[i / 8] & (1 << (i % 8)); + + if (thread && !node) + { + printf (" A thread leads to ``node'' %d, which is " + "not in the tree.", i); + done = 1; + } + } + } + + /* Check right threads. */ + { + int count = 0; + int last = INT_MIN; + void **data = NULL; + + while (NULL != (data = avlt_next (tree, data))) + { + if (((int) *data) < last) + { + printf (" Misordered right threads.\n"); + abort (); + } + else if (((int) *data) == last) + { + printf (" Loop in right threads detected on %d.\n", last); + abort (); + } + last = (int) *data; + count++; + } + if (count != tree->count) + { + printf (" Tree should have %d nodes, but tree count by right threads " + "is %d.\n", tree->count, count); + done = 1; + } + } + + /* Check left threads. */ + { + int count = 0; + int last = INT_MAX; + void **data = NULL; + + while (NULL != (data = avlt_prev (tree, data))) + { + if (((int) *data) > last) + { + printf (" Misordered left threads.\n"); + abort (); + } + else if (((int) *data) == last) + { + printf (" Loop in left threads detected on %d.\n", last); + abort (); + } + last = (int) *data; + count++; + } + if (count != tree->count) + { + printf (" Tree should have %d nodes, but tree count by left threads " + "is %d.\n", tree->count, count); + done = 1; + } + } + + if (done) + abort (); +} + +/* Arrange the N elements of ARRAY in random order. */ +void +shuffle (int *array, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + int j = i + rand () % (n - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Compares avl trees rooted at A and B, making sure that they are + identical. */ +void +compare_trees (avlt_node *a, avlt_node *b) +{ + int diff = 0; + + assert (a && b); + + /* Separating these conditions makes it easier to pinpoint bad data + under a memory debugger like Checker because each test is a + separate statement. */ + diff |= a->data != b->data; + diff |= a->bal != b->bal; + diff |= ((a->tag[0] == PLUS) ^ (b->tag[0] == PLUS)); + diff |= ((a->tag[1] == PLUS) ^ (b->tag[1] == PLUS)); + if (diff) + { + printf (" Copied nodes differ: %d b=%d a->bal=%d b->bal=%d a:", + (int) a->data, (int) b->data, a->bal, b->bal); + if (a->link[0]) + printf ("l"); + if (a->link[1]) + printf ("r"); + printf (" b:"); + if (b->link[0]) + printf ("l"); + if (b->link[1]) + printf ("r"); + printf ("\n"); + abort (); + } + if (a->tag[0] == PLUS) + compare_trees (a->link[0], b->link[0]); + if (a->tag[1] == PLUS) + compare_trees (a->link[1], b->link[1]); +} + +/* Simple stress test procedure for the AVL tree routines. Does the + following: + + * Generate a random number seed. By default this is generated from + the current time. You can also pass a seed value on the command + line if you want to test the same case. The seed value is + displayed. + + * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 + into it, in random order. Verify the tree structure after each + insertion. + + * Remove each integer from the tree, in a different random order. + After each deletion, verify the tree structure; also, make a copy + of the tree into a new tree, verify the copy and compare it to the + original, then destroy the copy. + + * Destroy the tree, increment the random seed value, and start over. + + If you make any modifications to the avl tree routines, then you + might want to insert some calls to print_structure() at strategic + places in order to be able to see what's really going on. Also, + memory debuggers like Checker or Purify are very handy. */ +#define N_ITERATIONS 16 +int +main (int argc, char **argv) +{ + int array[TREE_SIZE]; + int seed; + int iteration; + + if (argc == 2) + seed = atoi (argv[1]); + else + seed = time (0) * 257 % 32768; + + fputs ("Testing avlt...\n", stdout); + + for (iteration = 1; iteration <= N_ITERATIONS; iteration++) + { + avlt_tree *tree; + int i; + + printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); + fflush (stdout); + + srand (seed++); + + for (i = 0; i < TREE_SIZE; i++) + array[i] = i; + shuffle (array, TREE_SIZE); + + tree = avlt_create (compare_ints, NULL); + for (i = 0; i < TREE_SIZE; i++) + avlt_force_insert (tree, (void *) (array[i])); + verify_tree (tree); + + shuffle (array, TREE_SIZE); + for (i = 0; i < TREE_SIZE; i++) + { + avlt_tree *copy; + + avlt_delete (tree, (void *) (array[i])); + verify_tree (tree); + + copy = avlt_copy (tree, NULL); + verify_tree (copy); + if (tree->root.link[0] != &tree->root) + compare_trees (tree->root.link[0], copy->root.link[0]); + else if (copy->root.link[1] != ©->root) + printf (" Empty tree results in nonempty copy.\n"), abort (); + avlt_destroy (copy, NULL); + + if (i % 128 == 0) + { + putchar ('.'); + fflush (stdout); + } + } + fputs (" good.\n", stdout); + + avlt_destroy (tree, NULL); + } + + return 0; +} +#endif /* SELF_TEST */ + +/* + Local variables: + compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./avlt-test avlt.c" + End: +*/ + diff --git a/avl-1.4.0/avlt.h b/avl-1.4.0/avlt.h new file mode 100644 index 0000000..94272b4 --- /dev/null +++ b/avl-1.4.0/avlt.h @@ -0,0 +1,142 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avlt.h in libavl. */ + +#if !avlt_h +#define avlt_h 1 + +/* The default maximum height of 32 allows for AVL trees having + between 5,704,880 and 4,294,967,295 nodes, depending on order of + insertion. You may change this compile-time constant as you + wish. */ +#ifndef AVL_MAX_HEIGHT +#define AVL_MAX_HEIGHT 32 +#endif + +/* Structure for a node in a threaded AVL tree. */ +typedef struct avlt_node + { + void *data; /* Pointer to data. */ + struct avlt_node *link[2]; /* Subtrees or threads. */ + signed char bal; /* Balance factor. */ + char cache; /* Used during insertion. */ + signed char tag[2]; /* Left and right thread tags. */ + } +avlt_node; + +/* Used for traversing a threaded AVL tree. */ +typedef struct avlt_traverser + { + int init; /* Initialized? */ + const avlt_node *p; /* Last node returned. */ + } +avlt_traverser; + +/* Initializer for avlt_traverser. */ +#define AVLT_TRAVERSER_INIT {0} + +/* Function types. */ +#if !AVL_FUNC_TYPES +#define AVL_FUNC_TYPES 1 +typedef int (*avl_comparison_func) (const void *a, const void *b, void *param); +typedef void (*avl_node_func) (void *data, void *param); +typedef void *(*avl_copy_func) (void *data, void *param); +#endif + +/* Structure which holds information about a threaded AVL tree. */ +typedef struct avlt_tree + { + avlt_node root; /* Tree root node. */ + avl_comparison_func cmp; /* Used to compare keys. */ + int count; /* Number of nodes in the tree. */ + void *param; /* Arbitary user data. */ + } +avlt_tree; + +/* General functions. */ +avlt_tree *avlt_create (avl_comparison_func, void *param); +void avlt_destroy (avlt_tree *, avl_node_func); +void avlt_free (avlt_tree *); +int avlt_count (const avlt_tree *); +avlt_tree *avlt_copy (const avlt_tree *, avl_copy_func); +struct avl_tree; +avlt_tree *avlt_thread (struct avl_tree *); +struct avl_tree *avlt_unthread (avlt_tree *); + +/* Walk the tree. */ +void avlt_walk (const avlt_tree *, avl_node_func, void *param); +void *avlt_traverse (const avlt_tree *, avlt_traverser *); +#define avlt_init_traverser(TRAVERSER) ((TRAVERSER)->init = 0) +void **avlt_next (const avlt_tree *tree, void **item); +void **avlt_prev (const avlt_tree *tree, void **item); + +/* Search for a given item. */ +void **avlt_probe (avlt_tree *, void *); +void *avlt_delete (avlt_tree *, const void *); +void **avlt_find (const avlt_tree *, const void *); +void **avlt_find_close (const avlt_tree *, const void *); + +#if __GCC__ >= 2 +extern inline void * +avlt_insert (avlt_tree *tree, void *item) +{ + void **p = avlt_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +extern inline void * +avlt_replace (avlt_tree *tree, void *item) +{ + void **p = avlt_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} +#else /* not gcc */ +void *avlt_insert (avlt_tree *tree, void *item); +void *avlt_replace (avlt_tree *tree, void *item); +#endif /* not gcc */ + +/* Easy assertions on insertion & deletion. */ +#ifndef NDEBUG +#define avlt_force_insert(A, B) \ + do \ + { \ + void *r = avlt_insert (A, B); \ + assert (r == NULL); \ + } \ + while (0) +void *avlt_force_delete (avlt_tree *, void *); +#else +#define avlt_force_insert(A, B) \ + avlt_insert (A, B) +#define avlt_force_delete(A, B) \ + avlt_delete (A, B) +#endif + +#endif /* avlt_h */ diff --git a/avl-1.4.0/avltr.c b/avl-1.4.0/avltr.c new file mode 100644 index 0000000..2831bee --- /dev/null +++ b/avl-1.4.0/avltr.c @@ -0,0 +1,1538 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avltr.c in libavl. */ + +#if HAVE_CONFIG_H +#include +#endif +#if SELF_TEST +#include +#include +#endif +#include +#include +#include +#include +#include "avltr.h" + +/* Tag types. */ +#define PLUS +1 +#define MINUS -1 + +#if !__GCC__ && !defined (inline) +#define inline +#endif + +void +print_structure (avltr_tree *tree, avltr_node *node, int level); + +#if __GNUC__ >= 2 +#define unused __attribute__ ((unused)) +#else +#define unused +#endif + +#ifdef HAVE_XMALLOC +void *xmalloc (size_t); +#else /* !HAVE_XMALLOC */ +/* Allocates SIZE bytes of space using malloc(). Aborts if out of + memory. */ +static void * +xmalloc (size_t size) +{ + void *vp; + if (size == 0) + return NULL; + vp = malloc (size); + assert (vp != NULL); + if (vp == NULL) + { + fprintf (stderr, "virtual memory exhausted\n"); + exit (EXIT_FAILURE); + } + return vp; +} +#endif /* !HAVE_XMALLOC */ + +/* Creates an AVL tree in arena OWNER (which can be NULL). The arena + is owned by the caller, not by the AVL tree. CMP is a order + function for the data to be stored in the tree. PARAM is arbitrary + data that becomes an argument to the comparison function. */ +avltr_tree * +avltr_create (avl_comparison_func cmp, void *param) +{ + avltr_tree *tree; + + assert (cmp != NULL); + tree = xmalloc (sizeof (avltr_tree)); + + tree->root.link[0] = NULL; + tree->root.link[1] = &tree->root; + tree->root.rtag = PLUS; + tree->cmp = cmp; + tree->count = 0; + tree->param = param; + + return tree; +} + +/* Destroy tree TREE. Function FREE_FUNC is called for every node in + the tree as it is destroyed. + + No effect if the tree has an arena owner and free_func is NULL. + The caller owns the arena and must destroy it itself. + + Do not attempt to reuse the tree after it has been freed. Create a + new one. */ +void +avltr_destroy (avltr_tree *tree, avl_node_func free_func) +{ + assert (tree != NULL); + + if (tree->root.link[0] != &tree->root) + { + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal), further modified for right-threaded + trees. */ + + /* T1. */ + avltr_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + avltr_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + while (p != NULL) + { + /* T3. */ + ab[ap] = 0; + an[ap++] = p; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if (ab[ap] == 0) + { + ab[ap++] = 1; + if (p->rtag == MINUS) + continue; + p = p->link[1]; + break; + } + + if (free_func) + free_func (p->data, tree->param); + free (p); + } + } + } + + done: + free (tree); +} + +/* avltr_destroy() with FREE_FUNC hardcoded as free(). */ +void +avltr_free (avltr_tree *tree) +{ + avltr_destroy (tree, (avl_node_func) free); +} + +/* Return the number of nodes in TREE. */ +int +avltr_count (const avltr_tree *tree) +{ + assert (tree != NULL); + return tree->count; +} + +/* Copy the contents of TREE to a new tree in arena OWNER. If COPY is + non-NULL, then each data item is passed to function COPY, and the + return values are inserted into the new tree; otherwise, the items + are copied verbatim from the old tree to the new tree. Returns the + new tree. */ +avltr_tree * +avltr_copy (const avltr_tree *tree, avl_copy_func copy) +{ + /* Knuth's Algorithm 2.3.1C (copying a binary tree). Additionally + uses Algorithm 2.3.1I (insertion into a threaded binary tree) and + Algorithm 2.3.1 exercise 17 (preorder successor in threaded + binary tree). */ + + avltr_tree *new_tree; + + const avltr_node *p; + avltr_node *q; + + assert (tree != NULL); + new_tree = avltr_create (tree->cmp, tree->param); + new_tree->count = tree->count; + p = &tree->root; + if (p->link[0] == p) + return new_tree; + q = &new_tree->root; + + for (;;) + { + /* C4. This is Algorithm 2.3.1 exercise 23 for insertion to the + left in a right-threaded binary tree. */ + if (p->link[0] != NULL) + { + avltr_node *r = xmalloc (sizeof (avltr_node)); + + q->link[0] = r; + r->link[0] = NULL; + r->link[1] = q; + r->rtag = MINUS; + } + + /* C5: Find preorder successors of P and Q. This is Algorithm + 2.3.1 exercise 17 but applies its actions to Q as well as + P. */ + if (p->link[0] != NULL) + { + p = p->link[0]; + q = q->link[0]; + } + else + { + while (p->rtag == MINUS) + { + p = p->link[1]; + q = q->link[1]; + } + p = p->link[1]; + q = q->link[1]; + } + + /* C6. */ + if (p == &tree->root) + { + assert (q == &new_tree->root); + return new_tree; + } + + /* C2. This is Algorithm 2.3.1 exercise 23 for insertion to the + right in a right-threaded binary tree. */ + if (p->rtag == PLUS) + { + avltr_node *r = xmalloc (sizeof (avltr_node)); + + r->link[1] = q->link[1]; + r->rtag = q->rtag; + q->link[1] = r; + q->rtag = PLUS; + r->link[0] = NULL; + } + + /* C3. */ + q->bal = p->bal; + if (copy == NULL) + q->data = p->data; + else + q->data = copy (p->data, tree->param); + } +} + +/* Threads the unthreaded AVL tree TREE in-place, and returns TREE cast to + avltr_tree *. */ +avltr_tree * +avltr_thread (struct avl_tree *_tree) +{ + /* Uses Knuth's Algorithm 2.3.1 exercise 30 (thread an unthreaded + tree, with Algorithm 2.3.1T (inorder traversal) for computing + Q$. */ + + avltr_tree *tree = (avltr_tree *) _tree; + + /* Algorithm T's variables. */ + avltr_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + avltr_node **ap; /* Stack A: stack pointer. */ + avltr_node *tp; /* P. */ + + /* Algorithm L's variables. */ + avltr_node *p, *q; + + assert (tree != NULL); + + /* T1. */ + ap = an; + tp = tree->root.link[0]; + + /* L1. */ + q = &tree->root; + q->link[1] = q; + + for (;;) + { + /* L2. */ + { + /* T2. */ + while (tp != NULL) + { + /* T3. */ + *ap++ = tp; + tp = tp->link[0]; + } + + /* T4. Modified to visit HEAD after fully traversing the + tree. */ + if (ap == an) + tp = &tree->root; + else + tp = *--ap; + + /* T5: Visit P. */ + p = tp; + } + + /* L3. */ + if (q->link[1] == NULL) + { + q->link[1] = p; + q->rtag = MINUS; + } + else + q->rtag = PLUS; + + /* L4. */ + if (p == &tree->root) + return tree; + q = p; + + /* T5: Next. */ + tp = tp->link[1]; + } +} + +/* Unthreads the threaded tree TREE in-place, and returns TREE cast to + avl_tree *. */ +struct avl_tree * +avltr_unthread (avltr_tree *tree) +{ + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal). */ + + /* T1. */ + avltr_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ + char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + avltr_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p != NULL) + for (;;) + { + /* T2. */ + for (;;) + { + /* T3. */ + ab[ap] = 0; + an[ap++] = p; + if (p->link[0] == NULL) + break; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if (ab[ap] == 0) + { + ab[ap++] = 1; + if (p->rtag == MINUS) + continue; + p = p->link[1]; + break; + } + + if (p->rtag == MINUS) + p->link[1] = NULL; + } + } + else + tree->root.link[0] = NULL; + + done: + tree->root.link[1] = NULL; + return (struct avl_tree *) tree; +} + +/* Walk tree TREE in inorder, calling WALK_FUNC at each node. Passes + PARAM to WALK_FUNC. */ +void +avltr_walk (const avltr_tree *tree, avl_node_func walk_func, void *param) +{ + const avltr_node *p = &tree->root; + + /* Uses Knuth's algorithm 2.3.1D (threaded inorder successor). */ + assert (tree && walk_func); + + for (;;) + { + if (p->rtag == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->link[0] != NULL) + p = p->link[0]; + } + + if (p == &tree->root) + return; + + walk_func (p->data, param); + } +} + +/* Each call to this function for a given TREE and TRAV return the + next item in the tree in inorder. Initialize the first element of + TRAV (init) to 0 before calling the first time. Returns NULL when + out of elements. */ +void * +avltr_traverse (const avltr_tree *tree, avltr_traverser *trav) +{ + const avltr_node *p; + + assert (tree && trav); + + if (trav->init == 0) + { + p = &tree->root; + trav->init = 1; + } + else + p = trav->p; + + /* Knuth's Algorithm 2.3.1S (threaded inorder successor). */ + if (p->rtag == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->link[0] != NULL) + p = p->link[0]; + } + + if (p == &tree->root) + { + trav->init = 0; + return NULL; + } + else + { + trav->p = p; + return (void *) p->data; + } +} + +/* Given ITEM, a pointer to a data item in TREE (or NULL), returns a + pointer to the next item in the tree in comparison order, or NULL + if ITEM is the last item. */ +void ** +avltr_next (const avltr_tree *tree, void **item) +{ + const avltr_node *p; + + assert (tree != NULL); + if (item == NULL) + p = &tree->root; + else + p = (avltr_node *) (((char *) item) - offsetof (avltr_node, data)); + + /* Knuth's Algorithm 2.3.1S (threaded inorder successor). */ + if (p->rtag == MINUS) + p = p->link[1]; + else + { + p = p->link[1]; + while (p->link[0] != NULL) + p = p->link[0]; + } + + if (p == &tree->root) + return NULL; + + return (void **) &p->data; +} + +/* Search TREE for an item matching ITEM. If found, returns a pointer + to the address of the item. If none is found, ITEM is inserted + into the tree, and a pointer to the address of ITEM is returned. + In either case, the pointer returned can be changed by the caller, + or the returned data item can be directly edited, but the key data + in the item must not be changed. */ +void ** +avltr_probe (avltr_tree *tree, void *item) +{ + /* Uses Knuth's Algorithm 6.2.3A (balanced tree search and + insertion), modified for a right-threaded binary tree. Caches + results of comparisons. In empirical tests this eliminates about + 25% of the comparisons seen under random insertions. */ + + /* A1. */ + avltr_node *t; + avltr_node *s, *p, *q, *r; + + assert (tree != NULL); + t = &tree->root; + s = p = t->link[0]; + + if (s == NULL) + { + tree->count++; + assert (tree->count == 1); + q = t->link[0] = xmalloc (sizeof (avltr_node)); + q->data = item; + q->link[0] = NULL; + q->link[1] = t; + q->rtag = MINUS; + q->bal = 0; + return &q->data; + } + + for (;;) + { + /* A2. */ + int diff = tree->cmp (item, p->data, tree->param); + + /* A3. */ + if (diff < 0) + { + p->cache = 0; + q = p->link[0]; + if (q == NULL) + { + /* Algorithm 2.3.1 exercise 23 for insertion to the left + in a right-threaded binary tree. */ + q = xmalloc (sizeof (avltr_node)); + p->link[0] = q; + q->link[0] = NULL; + q->link[1] = p; + q->rtag = MINUS; + break; + } + } + /* A4. */ + else if (diff > 0) + { + p->cache = 1; + q = p->link[1]; + if (p->rtag == MINUS) + { + /* Algorithm 2.3.1 exercise 23 for insertion to the right + in a right-threaded binary tree. */ + q = xmalloc (sizeof (avltr_node)); + q->link[1] = p->link[1]; + q->rtag = p->rtag; + p->link[1] = q; + p->rtag = PLUS; + q->link[0] = NULL; + break; + } + assert (q != NULL); + } + else + /* A2. */ + return &p->data; + + /* A3, A4. */ + if (q->bal != 0) + t = p, s = q; + p = q; + } + + /* A5. */ + tree->count++; + q->data = item; + q->bal = 0; + + /* A6. */ + r = p = s->link[(int) s->cache]; + while (p != q) + { + p->bal = p->cache * 2 - 1; + p = p->link[(int) p->cache]; + } + + /* A7. */ + if (s->cache == 0) + { + /* a = -1. */ + if (s->bal == 0) + { + s->bal = -1; + return &q->data; + } + else if (s->bal == +1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == -1); + if (r->bal == -1) + { + /* A8. */ + p = r; + if (r->rtag == MINUS) + { + s->link[0] = NULL; + r->link[1] = s; + r->rtag = PLUS; + } + else + { + s->link[0] = r->link[1]; + r->link[1] = s; + } + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == +1); + p = r->link[1]; + r->link[1] = p->link[0]; + p->link[0] = r; + s->link[0] = p->link[1]; + p->link[1] = s; + if (p->bal == -1) + s->bal = 1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == +1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + p->rtag = PLUS; + if (s->link[0] == s) + s->link[0] = NULL; + if (r->link[1] == NULL) + { + r->link[1] = p; + r->rtag = MINUS; + } + } + } + else + { + /* a == +1. */ + if (s->bal == 0) + { + s->bal = 1; + return &q->data; + } + else if (s->bal == -1) + { + s->bal = 0; + return &q->data; + } + + assert (s->bal == +1); + if (r->bal == +1) + { + /* A8. */ + p = r; + if (r->link[0] == NULL) + { + s->rtag = MINUS; + r->link[0] = s; + } + else + { + s->link[1] = r->link[0]; + s->rtag = PLUS; + r->link[0] = s; + } + s->bal = r->bal = 0; + } + else + { + /* A9. */ + assert (r->bal == -1); + p = r->link[0]; + r->link[0] = p->link[1]; + p->link[1] = r; + s->link[1] = p->link[0]; + p->link[0] = s; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = 1; + } + p->rtag = PLUS; + if (s->link[1] == NULL) + { + s->link[1] = p; + s->rtag = MINUS; + } + if (r->link[0] == r) + r->link[0] = NULL; + p->bal = 0; + } + } + + /* A10. */ + if (t != &tree->root && s == t->link[1]) + t->link[1] = p; + else + t->link[0] = p; + + return &q->data; +} + +/* Search TREE for an item matching ITEM, and return a pointer to it + if found. */ +void ** +avltr_find (const avltr_tree *tree, const void *item) +{ + const avltr_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p == NULL) + return NULL; + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + + /* A3. */ + if (diff < 0) + { + p = p->link[0]; + if (p == NULL) + return NULL; + } + else if (diff > 0) + { + if (p->rtag == MINUS) + return NULL; + p = p->link[1]; + } + else + return (void **) &p->data; + } +} + +/* Search TREE for an item close to the value of ITEM, and return it. + This function will return a null pointer only if TREE is empty. */ +void ** +avltr_find_close (const avltr_tree *tree, const void *item) +{ + const avltr_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p == NULL) + return NULL; + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + + /* A3. */ + if (diff < 0) + { + if (p->link[0]) + p = p->link[0]; + else + return (void **) &p->data; + } + else if (diff > 0) + { + if (p->rtag == MINUS) + return (void **) &p->data; + p = p->link[1]; + } + else + return (void **) &p->data; + } +} + +/* Searches AVL tree TREE for an item matching ITEM. If found, the + item is removed from the tree and the actual item found is returned + to the caller. If no item matching ITEM exists in the tree, + returns NULL. */ +void * +avltr_delete (avltr_tree *tree, const void *item) +{ + /* Uses my Algorithm DTR, which can be found at + http://www.msu.edu/user/pfaffben/avl. Algorithm DT is based on + Knuth's Algorithms 6.2.2D (Tree deletion), 6.2.3A (Balanced tree + search and insertion), 2.3.1I (Insertion into a threaded binary + trees), and the notes on pages 465-466 of Vol. 3. */ + + /* D1. */ + avltr_node *pa[AVL_MAX_HEIGHT]; /* Stack P: Nodes. */ + unsigned char a[AVL_MAX_HEIGHT]; /* Stack P: Bits. */ + int k = 1; /* Stack P: Pointer. */ + + avltr_node *p; + + assert (tree != NULL); + + a[0] = 0; + pa[0] = &tree->root; + p = tree->root.link[0]; + if (p == NULL) + return NULL; + for (;;) + { + /* D2. */ + int diff = tree->cmp (item, p->data, tree->param); + + if (diff == 0) + break; + + /* D3, D4. */ + pa[k] = p; + if (diff < 0) + { + if (p->link[0] != NULL) + { + p = p->link[0]; + a[k] = 0; + } + else + return NULL; + } + else if (diff > 0) + { + if (p->rtag == PLUS) + { + p = p->link[1]; + a[k] = 1; + } + else + return NULL; + } + + k++; + } + tree->count--; + + item = p->data; + + { + avltr_node *t = p; + avltr_node **q = &pa[k - 1]->link[(int) a[k - 1]]; + + /* D5. */ + if (t->rtag == MINUS) + { + if (t->link[0] != NULL) + { + avltr_node *const x = t->link[0]; + + *q = x; + (*q)->bal = 0; + if (x->rtag == MINUS) + { + if (a[k - 1] == 1) + x->link[1] = t->link[1]; + else + x->link[1] = pa[k - 1]; + } + } + else + { + *q = t->link[a[k - 1]]; + if (a[k - 1] == 0) + pa[k - 1]->link[0] = NULL; + else + pa[k - 1]->rtag = MINUS; + } + } + else + { + /* D6. */ + avltr_node *r = t->link[1]; + if (r->link[0] == NULL) + { + r->link[0] = t->link[0]; + r->bal = t->bal; + if (r->link[0] != NULL) + { + avltr_node *s = r->link[0]; + while (s->rtag == PLUS) + s = s->link[1]; + assert (s->rtag == MINUS); + s->link[1] = r; + } + *q = r; + a[k] = 1; + pa[k++] = r; + } + else + { + /* D7. */ + avltr_node *s = r->link[0]; + + a[k] = 1; + pa[k++] = t; + + a[k] = 0; + pa[k++] = r; + + /* D8. */ + while (s->link[0] != NULL) + { + r = s; + s = r->link[0]; + a[k] = 0; + pa[k++] = r; + } + + /* D9. */ + t->data = s->data; + if (s->rtag == PLUS) + r->link[0] = s->link[1]; + else + r->link[0] = NULL; + p = s; + } + } + } + + free (p); + + assert (k > 0); + /* D10. */ + while (--k) + { + avltr_node *const s = pa[k]; + + if (a[k] == 0) + { + avltr_node *const r = s->link[1]; + + /* D10. */ + if (s->bal == -1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = +1; + break; + } + + assert (s->bal == +1); + if (s->rtag == MINUS || r->bal == 0) + { + /* D11. */ + s->link[1] = r->link[0]; + r->link[0] = s; + r->bal = -1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == +1) + { + /* D12. */ + if (r->link[0] != NULL) + { + s->rtag = PLUS; + s->link[1] = r->link[0]; + } + else + s->rtag = MINUS; + r->link[0] = s; + s->bal = r->bal = 0; + pa[k - 1]->link[a[k - 1]] = r; + } + else + { + /* D13. */ + assert (r->bal == -1); + p = r->link[0]; + if (p->rtag == PLUS) + r->link[0] = p->link[1]; + else + r->link[0] = NULL; + p->link[1] = r; + p->rtag = PLUS; + if (p->link[0] == NULL) + { + s->link[1] = p; + s->rtag = MINUS; + } + else + { + s->link[1] = p->link[0]; + s->rtag = PLUS; + } + p->link[0] = s; + if (p->bal == +1) + s->bal = -1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == -1); + s->bal = 0, r->bal = +1; + } + p->bal = 0; + pa[k - 1]->link[(int) a[k - 1]] = p; + if (a[k - 1] == 1) + pa[k - 1]->rtag = PLUS; + } + } + else + { + avltr_node *const r = s->link[0]; + + /* D10. */ + if (s->bal == +1) + { + s->bal = 0; + continue; + } + else if (s->bal == 0) + { + s->bal = -1; + break; + } + + assert (s->bal == -1); + if (s->link[0] == NULL || r->bal == 0) + { + /* D11. */ + s->link[0] = r->link[1]; + r->link[1] = s; + r->bal = +1; + pa[k - 1]->link[(int) a[k - 1]] = r; + break; + } + else if (r->bal == -1) + { + /* D12. */ + if (r->rtag == PLUS) + s->link[0] = r->link[1]; + else + s->link[0] = NULL; + r->link[1] = s; + r->rtag = PLUS; + s->bal = r->bal = 0; + pa[k - 1]->link[a[k - 1]] = r; + } + else + { + /* D13. */ + assert (r->bal == +1); + p = r->link[1]; + if (p->link[0] != NULL) + { + r->rtag = PLUS; + r->link[1] = p->link[0]; + } + else + r->rtag = MINUS; + p->link[0] = r; + if (p->rtag == MINUS) + s->link[0] = NULL; + else + s->link[0] = p->link[1]; + p->link[1] = s; + p->rtag = PLUS; + if (p->bal == -1) + s->bal = +1, r->bal = 0; + else if (p->bal == 0) + s->bal = r->bal = 0; + else + { + assert (p->bal == +1); + s->bal = 0, r->bal = -1; + } + p->bal = 0; + if (a[k - 1] == 1) + pa[k - 1]->rtag = PLUS; + pa[k - 1]->link[(int) a[k - 1]] = p; + } + } + } + + return (void *) item; +} + +/* Inserts ITEM into TREE. Returns NULL if the item was inserted, + otherwise a pointer to the duplicate item. */ +void * +avltr_insert (avltr_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avltr_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +/* If ITEM does not exist in TREE, inserts it and returns NULL. If a + matching item does exist, it is replaced by ITEM and the item + replaced is returned. The caller is responsible for freeing the + item returned. */ +void * +avltr_replace (avltr_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = avltr_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} + +/* Delete ITEM from TREE when you know that ITEM must be in TREE. For + debugging purposes. */ +void * +(avltr_force_delete) (avltr_tree *tree, void *item) +{ + void *found = avltr_delete (tree, item); + assert (found != NULL); + return found; +} + +#if SELF_TEST + +/* Size of the tree used for testing. */ +#define TREE_SIZE 1024 + +/* Used to flag delayed aborting. */ +int done = 0; + +/* Count the number of nodes in TREE below and including NODE. */ +int +count (avltr_tree *tree, avltr_node *node) +{ + int n = 1; + if (node->link[0] != NULL) + n += count (tree, node->link[0]); + if (node->rtag == PLUS) + n += count (tree, node->link[1]); + return n; +} + +/* Print the structure of node NODE of an avl tree, which is LEVEL + levels from the top of the tree. Uses different delimiters to + visually distinguish levels. */ +void +print_structure (avltr_tree *tree, avltr_node *node, int level) +{ + char lc[] = "([{<`"; + char rc[] = ")]}>'"; + + if (node == NULL) + { + printf (" :nil"); + return; + } + else if (level >= 10) + { + printf ("Too deep, giving up.\n"); + done = 1; + return; + } + else if (node == &tree->root) + { + printf (" root"); + return; + } + printf (" %c%d", lc[level % 5], (int) node->data); + fflush (stdout); + + print_structure (tree, node->link[0], level + 1); + fflush (stdout); + + if (node->rtag == PLUS) + print_structure (tree, node->link[1], level + 1); + else if (node->link[1] != &tree->root) + printf (" :%d", (int) node->link[1]->data); + else + printf (" :r"); + fflush (stdout); + + printf ("%c", rc[level % 5]); + fflush (stdout); +} + +/* Compare two integers A and B and return a strcmp()-type result. */ +int +compare_ints (const void *a, const void *b, void *param unused) +{ + return ((int) a) - ((int) b); +} + +/* Print the value of integer A. */ +void +print_int (void *a, void *param unused) +{ + printf (" %d", (int) a); +} + +/* Linearly print contents of TREE. */ +void +print_contents (avltr_tree *tree) +{ + avltr_walk (tree, print_int, NULL); + printf ("\n"); +} + +/* Examine NODE in a avl tree. *COUNT is increased by the number of + nodes in the tree, including the current one. If the node is the + root of the tree, PARENT should be INT_MIN, otherwise it should be + the parent node value. DIR is the direction that the current node + is linked from the parent: -1 for left child, +1 for right child; + it is not used if PARENT is INT_MIN. Returns the height of the + tree rooted at NODE. */ +int +recurse_tree (avltr_tree *tree, avltr_node *node, int *count, int parent, + int dir, unsigned char *nodes, unsigned char *threads) +{ + if (node != NULL && node != &tree->root) + { + int d = (int) node->data; + int nl = 0; + int nr = 0; + + (*count)++; + + assert (d >= 0 && d < TREE_SIZE); + if (nodes[d / 8] & (1 << (d % 8))) + { + printf (" Arrived at node %d by two different paths.\n", d); + done = 1; + } + else + nodes[d / 8] |= 1 << (d % 8); + + if (node->link[0] != NULL) + nl = recurse_tree (tree, node->link[0], count, d, -1, nodes, threads); + + if (node->rtag == PLUS) + { + if (node->link[1] == NULL) + { + printf (" Null thread link.\n"); + done = 1; + } + nr = recurse_tree (tree, node->link[1], count, d, 1, nodes, threads); + } + else if (node->link[1] != &tree->root) + { + int dr = (int) node->link[1]->data; + assert (dr >= 0 && dr < TREE_SIZE); + if (threads[dr / 8] & (1 << dr % 8)) + { + printf (" Multiple threads to node %d.\n", d); + done = 1; + } + threads[dr / 8] |= 1 << (dr % 8); + } + + if (nr - nl != node->bal) + { + printf (" Node %d has incorrect balance: right height=%d, " + "left height=%d, difference=%d, but balance factor=%d.\n", + d, nr, nl, nr - nl, node->bal); + done = 1; + } + + if (node->bal < -1 || node->bal > 1) + { + printf (" Node %d has invalid balance factor %d.\n", d, node->bal); + done = 1; + } + + if (parent != INT_MIN) + { + assert (dir == -1 || dir == +1); + if (dir == -1 && d > parent) + { + printf (" Node %d is smaller than its left child %d.\n", + parent, d); + done = 1; + } + else if (dir == +1 && d < parent) + { + printf (" Node %d is larger than its right child %d.\n", + parent, d); + done = 1; + } + } + assert (node->bal >= -1 && node->bal <= 1); + return 1 + (nl > nr ? nl : nr); + } + else return 0; +} + +/* Check that everything about TREE is kosher. */ +void +verify_tree (avltr_tree *tree) +{ + { + unsigned char nodes[(TREE_SIZE + 7) / 8]; + unsigned char threads[(TREE_SIZE + 7) / 8]; + + int count = 0; + int i; + + memset (nodes, 0, (TREE_SIZE + 7) / 8); + memset (threads, 0, (TREE_SIZE + 7) / 8); + + recurse_tree (tree, tree->root.link[0], &count, INT_MIN, 0, nodes, + threads); + + if (count != tree->count) + { + printf (" Tree should have %d nodes, but tree count by recursive " + "descent is %d.\n", tree->count, count); + done = 1; + } + + for (i = 0; i < TREE_SIZE; i++) + { + int thread = threads[i / 8] & (1 << (i % 8)); + int node = nodes[i / 8] & (1 << (i % 8)); + + if (thread && !node) + { + printf (" A thread leads to ``node'' %d, " + "which is not in the tree.", i); + done = 1; + } + } + } + + /* Check threads. */ + { + int count = 0; + int last = INT_MIN; + void **data = NULL; + + while (NULL != (data = avltr_next (tree, data))) + { + if (((int) *data) < last) + { + printf (" Misordered right threads.\n"); + abort (); + } + else if (((int) *data) == last) + { + printf (" Loop in right threads detected on %d.\n", last); + abort (); + } + last = (int) *data; + count++; + } + + if (count != tree->count) + { + printf (" Tree should have %d nodes, but tree count by right threads " + "is %d.\n", tree->count, count); + done = 1; + } + } + + if (done) + abort (); +} + +/* Arrange the N elements of ARRAY in random order. */ +void +shuffle (int *array, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + int j = i + rand () % (n - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Compares avl trees rooted at A and B, making sure that they are + identical. */ +void +compare_trees (avltr_node *a, avltr_node *b) +{ + int diff = 0; + + assert (a && b); + + /* Separating these conditions makes it easier to pinpoint bad data + under a memory debugger like Checker because each test is a + separate statement. */ + diff |= a->data != b->data; + diff |= a->bal != b->bal; + diff |= ((a->link[0] != NULL) ^ (b->link[0] != NULL)); + diff |= ((a->rtag == PLUS) ^ (b->rtag == PLUS)); + if (diff) + { + printf (" Copied nodes differ: %d b=%d a->bal=%d b->bal=%d a:", + (int) a->data, (int) b->data, a->bal, b->bal); + if (a->link[0]) + printf ("l"); + if (a->link[1]) + printf ("r"); + printf (" b:"); + if (b->link[0]) + printf ("l"); + if (b->link[1]) + printf ("r"); + printf ("\n"); + abort (); + } + if (a->link[0] != NULL) + compare_trees (a->link[0], b->link[0]); + if (a->rtag == PLUS) + compare_trees (a->link[1], b->link[1]); +} + +/* Simple stress test procedure for the AVL tree routines. Does the + following: + + * Generate a random number seed. By default this is generated from + the current time. You can also pass a seed value on the command + line if you want to test the same case. The seed value is + displayed. + + * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 + into it, in random order. Verify the tree structure after each + insertion. + + * Remove each integer from the tree, in a different random order. + After each deletion, verify the tree structure; also, make a copy + of the tree into a new tree, verify the copy and compare it to the + original, then destroy the copy. + + * Destroy the tree, increment the random seed value, and start over. + + If you make any modifications to the avl tree routines, then you + might want to insert some calls to print_structure() at strategic + places in order to be able to see what's really going on. Also, + memory debuggers like Checker or Purify are very handy. */ +#define N_ITERATIONS 16 +int +main (int argc, char **argv) +{ + int array[TREE_SIZE]; + int seed; + int iteration; + + if (argc == 2) + seed = atoi (argv[1]); + else + seed = time (0) * 257 % 32768; + + fputs ("Testing avltr...\n", stdout); + + for (iteration = 1; iteration <= N_ITERATIONS; iteration++) + { + avltr_tree *tree; + int i; + + printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); + fflush (stdout); + + srand (seed++); + + for (i = 0; i < TREE_SIZE; i++) + array[i] = i; + shuffle (array, TREE_SIZE); + + tree = avltr_create (compare_ints, NULL); + for (i = 0; i < TREE_SIZE; i++) + avltr_force_insert (tree, (void *) (array[i])); + verify_tree (tree); + + shuffle (array, TREE_SIZE); + for (i = 0; i < TREE_SIZE; i++) + { + avltr_tree *copy; + + avltr_delete (tree, (void *) (array[i])); + verify_tree (tree); + + copy = avltr_copy (tree, NULL); + verify_tree (copy); + if (tree->root.link[0] != NULL) + compare_trees (tree->root.link[0], copy->root.link[0]); + else if (copy->root.link[0] != NULL) + { + printf (" Empty tree results in nonempty copy.\n"); + abort (); + } + avltr_destroy (copy, NULL); + + if (i % 128 == 0) + { + putchar ('.'); + fflush (stdout); + } + } + fputs (" good.\n", stdout); + + avltr_destroy (tree, NULL); + } + + return 0; +} +#endif /* SELF_TEST */ + +/* + Local variables: + compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./avltr-test avltr.c" + End: +*/ + diff --git a/avl-1.4.0/avltr.h b/avl-1.4.0/avltr.h new file mode 100644 index 0000000..27465ef --- /dev/null +++ b/avl-1.4.0/avltr.h @@ -0,0 +1,142 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file avltr.h in libavl. */ + +#if !avltr_h +#define avltr_h 1 + +/* The default maximum height of 32 allows for AVL trees having + between 5,704,880 and 4,294,967,295 nodes, depending on order of + insertion. You may change this compile-time constant as you + wish. */ +#ifndef AVL_MAX_HEIGHT +#define AVL_MAX_HEIGHT 32 +#endif + +/* Structure for a node in a right-threaded AVL tree. */ +typedef struct avltr_node + { + void *data; /* Pointer to data. */ + struct avltr_node *link[2]; /* Subtrees or threads. */ + signed char bal; /* Balance factor. */ + char cache; /* Used during insertion. */ + char pad; /* Reserved for fully threaded trees. */ + signed char rtag; /* Right thread tag. */ + } +avltr_node; + +/* Used for traversing a right-threaded AVL tree. */ +typedef struct avltr_traverser + { + int init; /* Initialized? */ + const avltr_node *p; /* Last node returned. */ + } +avltr_traverser; + +/* Initializer for avltr_traverser. */ +#define AVLTR_TRAVERSER_INIT {0} + +/* Function types. */ +#if !AVL_FUNC_TYPES +#define AVL_FUNC_TYPES 1 +typedef int (*avl_comparison_func) (const void *a, const void *b, void *param); +typedef void (*avl_node_func) (void *data, void *param); +typedef void *(*avl_copy_func) (void *data, void *param); +#endif + +/* Structure which holds information about a threaded AVL tree. */ +typedef struct avltr_tree + { + avltr_node root; /* Tree root node. */ + avl_comparison_func cmp; /* Used to compare keys. */ + int count; /* Number of nodes in the tree. */ + void *param; /* Arbitary user data. */ + } +avltr_tree; + +/* General functions. */ +avltr_tree *avltr_create (avl_comparison_func, void *param); +void avltr_destroy (avltr_tree *, avl_node_func); +void avltr_free (avltr_tree *); +int avltr_count (const avltr_tree *); +avltr_tree *avltr_copy (const avltr_tree *, avl_copy_func); +struct avl_tree; +avltr_tree *avltr_thread (struct avl_tree *); +struct avl_tree *avltr_unthread (avltr_tree *); + +/* Walk the tree. */ +void avltr_walk (const avltr_tree *, avl_node_func, void *param); +void *avltr_traverse (const avltr_tree *, avltr_traverser *); +#define avlt_init_traverser(TRAVERSER) ((TRAVERSER)->init = 0) +void **avltr_next (const avltr_tree *tree, void **item); + +/* Search for a given item. */ +void **avltr_probe (avltr_tree *, void *); +void *avltr_delete (avltr_tree *, const void *); +void **avltr_find (const avltr_tree *, const void *); +void **avltr_find_close (const avltr_tree *, const void *); + +#if __GCC__ >= 2 +extern inline void * +avltr_insert (avltr_tree *tree, void *item) +{ + void **p = avltr_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +extern inline void * +avltr_replace (avltr_tree *tree, void *item) +{ + void **p = avltr_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} +#else /* not gcc */ +void *avltr_insert (avltr_tree *tree, void *item); +void *avltr_replace (avltr_tree *tree, void *item); +#endif /* not gcc */ + +/* Easy assertions on insertion & deletion. */ +#ifndef NDEBUG +#define avltr_force_insert(A, B) \ + do \ + { \ + void *r = avltr_insert (A, B); \ + assert (r == NULL); \ + } \ + while (0) +void *avltr_force_delete (avltr_tree *, void *); +#else +#define avltr_force_insert(A, B) \ + avltr_insert (A, B) +#define avltr_force_delete(A, B) \ + avltr_delete (A, B) +#endif + +#endif /* avltr_h */ diff --git a/avl-1.4.0/configure b/avl-1.4.0/configure new file mode 100755 index 0000000..5b955a9 --- /dev/null +++ b/avl-1.4.0/configure @@ -0,0 +1,1297 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # 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 << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=avl.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:556: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:609: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:666: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=avl + +VERSION=1.4.0 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:712: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:725: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:738: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:751: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:764: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:780: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:810: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:861: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:893: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 904 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:935: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:940: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:968: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1002: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@RANLIB@%$RANLIB%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/avl-1.4.0/configure.in b/avl-1.4.0/configure.in new file mode 100644 index 0000000..118f3c8 --- /dev/null +++ b/avl-1.4.0/configure.in @@ -0,0 +1,5 @@ +AC_INIT(avl.c) +AM_INIT_AUTOMAKE(avl, 1.4.0) +AC_PROG_CC +AC_PROG_RANLIB +AC_OUTPUT(Makefile) diff --git a/avl-1.4.0/install-sh b/avl-1.4.0/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/avl-1.4.0/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/avl-1.4.0/missing b/avl-1.4.0/missing new file mode 100755 index 0000000..7789652 --- /dev/null +++ b/avl-1.4.0/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# 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. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/avl-1.4.0/mkinstalldirs b/avl-1.4.0/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/avl-1.4.0/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/avl-1.4.0/rb.c b/avl-1.4.0/rb.c new file mode 100644 index 0000000..b0ec05d --- /dev/null +++ b/avl-1.4.0/rb.c @@ -0,0 +1,1083 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file rb.c in libavl. */ + +#if HAVE_CONFIG_H +#include +#endif +#if SELF_TEST +#include +#include +#endif +#include +#include +#include +#include "rb.h" + +#if !PSPP && !__GCC__ +#define inline +#endif + +#if __GNUC__ >= 2 +#define unused __attribute__ ((unused)) +#else +#define unused +#endif + +#ifdef HAVE_XMALLOC +void *xmalloc (size_t); +#else /* !HAVE_XMALLOC */ +/* Allocates SIZE bytes of space using malloc(). Aborts if out of + memory. */ +static void * +xmalloc (size_t size) +{ + void *vp; + + if (size == 0) + return NULL; + vp = malloc (size); + + assert (vp != NULL); + if (vp == NULL) + { + fprintf (stderr, "virtual memory exhausted\n"); + exit (EXIT_FAILURE); + } + return vp; +} +#endif /* !HAVE_XMALLOC */ + +/* Creates a red-black tree in arena OWNER (which can be NULL). The + arena is owned by the caller, not by the red-black tree. CMP is a + order function for the data to be stored in the tree. PARAM is + arbitrary data that becomes an argument to the comparison + function. */ +rb_tree * +rb_create (MAYBE_ARENA avl_comparison_func cmp, void *param) +{ + rb_tree *tree; + + assert (cmp != NULL); + tree = xmalloc (sizeof (rb_tree)); + + tree->root.link[0] = NULL; + tree->root.link[1] = NULL; + tree->cmp = cmp; + tree->count = 0; + tree->param = param; + + return tree; +} + +/* Destroy tree TREE. Function FREE_FUNC is called for every node in + the tree as it is destroyed. + + No effect if the tree has an arena owner and free_func is NULL. + The caller owns the arena and must destroy it itself. + + Do not attempt to reuse the tree after it has been freed. Create a + new one. */ +void +rb_destroy (rb_tree *tree, avl_node_func free_func) +{ + assert (tree != NULL); + + { + /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 + (postorder traversal). */ + + /* T1. */ + rb_node *an[RB_MAX_HEIGHT]; /* Stack A: nodes. */ + unsigned long ab = 0; /* Stack A: bits. */ + int ap = 0; /* Stack A: height. */ + rb_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + while (p != NULL) + { + /* T3. */ + ab &= ~(1ul << ap); + an[ap++] = p; + p = p->link[0]; + } + + /* T4. */ + for (;;) + { + if (ap == 0) + goto done; + + p = an[--ap]; + if ((ab & (1ul << ap)) == 0) + { + ab |= (1ul << ap++); + p = p->link[1]; + break; + } + + if (free_func) + free_func (p->data, tree->param); + free (p); + } + } + } + + done: + free (tree); +} + +/* rb_destroy() with FREE_FUNC hardcoded as free(). */ +void +rb_free (rb_tree *tree) +{ + rb_destroy (tree, (avl_node_func) free); +} + +/* Return the number of nodes in TREE. */ +int +rb_count (const rb_tree *tree) +{ + assert (tree != NULL); + return tree->count; +} + +/* Copy the contents of TREE to a new tree in arena OWNER. If COPY is + non-NULL, then each data item is passed to function COPY, and the + return values are inserted into the new tree; otherwise, the items + are copied verbatim from the old tree to the new tree. Returns the + new tree. */ +rb_tree * +rb_copy (MAYBE_ARENA const rb_tree *tree, avl_copy_func copy) +{ + /* This is a combination of Knuth's Algorithm 2.3.1C (copying a + binary tree) and Algorithm 2.3.1T as modified by exercise 12 + (preorder traversal). */ + + rb_tree *new_tree; + + /* PT1. */ + const rb_node *pa[RB_MAX_HEIGHT]; /* Stack PA: nodes. */ + const rb_node **pp = pa; /* Stack PA: stack pointer. */ + const rb_node *p = &tree->root; + + /* QT1. */ + rb_node *qa[RB_MAX_HEIGHT]; /* Stack QA: nodes. */ + rb_node **qp = qa; /* Stack QA: stack pointer. */ + rb_node *q; + + assert (tree != NULL); + new_tree = rb_create (tree->cmp, tree->param); + new_tree->count = tree->count; + q = &new_tree->root; + + for (;;) + { + /* C4. */ + if (p->link[0] != NULL) + { + rb_node *r = xmalloc (sizeof (rb_node)); + r->link[0] = r->link[1] = NULL; + q->link[0] = r; + } + + /* C5: Find preorder successors of P and Q. */ + goto start; + for (;;) + { + /* PT2. */ + while (p != NULL) + { + goto escape; + start: + /* PT3. */ + *pp++ = p; + *qp++ = q; + p = p->link[0]; + q = q->link[0]; + } + + /* PT4. */ + if (pp == pa) + { + assert (qp == qa); + return new_tree; + } + + p = *--pp; + q = *--qp; + + /* PT5. */ + p = p->link[1]; + q = q->link[1]; + } + escape: + + /* C2. */ + if (p->link[1]) + { + rb_node *r = xmalloc (sizeof (rb_node)); + r->link[0] = r->link[1] = NULL; + q->link[1] = r; + } + + /* C3. */ + q->color = p->color; + if (copy == NULL) + q->data = p->data; + else + q->data = copy (p->data, tree->param); + } +} + +/* Walk tree TREE in inorder, calling WALK_FUNC at each node. Passes + PARAM to WALK_FUNC. */ +void +rb_walk (const rb_tree *tree, avl_node_func walk_func, void *param) +{ + /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ + assert (tree && walk_func); + + { + /* T1. */ + const rb_node *an[RB_MAX_HEIGHT]; /* Stack A: nodes. */ + const rb_node **ap = an; /* Stack A: stack pointer. */ + const rb_node *p = tree->root.link[0]; + + for (;;) + { + /* T2. */ + while (p != NULL) + { + /* T3. */ + *ap++ = p; + p = p->link[0]; + } + + /* T4. */ + if (ap == an) + return; + p = *--ap; + + /* T5. */ + walk_func (p->data, param); + p = p->link[1]; + } + } +} + +/* Each call to this function for a given TREE and TRAV return the + next item in the tree in inorder. Initialize the first element of + TRAV (init) to 0 before calling the first time. Returns NULL when + out of elements. */ +void * +rb_traverse (const rb_tree *tree, rb_traverser *trav) +{ + assert (tree && trav); + + /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ + if (trav->init == 0) + { + /* T1. */ + trav->init = 1; + trav->nstack = 0; + trav->p = tree->root.link[0]; + } + else + /* T5. */ + trav->p = trav->p->link[1]; + + for (;;) + { + /* T2. */ + while (trav->p != NULL) + { + /* T3. */ + trav->stack[trav->nstack++] = trav->p; + trav->p = trav->p->link[0]; + } + + /* T4. */ + if (trav->nstack == 0) + { + trav->init = 0; + return NULL; + } + trav->p = trav->stack[--trav->nstack]; + + /* T5. */ + return trav->p->data; + } +} + +/* Search TREE for an item matching ITEM. If found, returns a pointer + to the address of the item. If none is found, ITEM is inserted + into the tree, and a pointer to the address of ITEM is returned. + In either case, the pointer returned can be changed by the caller, + or the returned data item can be directly edited, but the key data + in the item must not be changed. */ +void ** +rb_probe (rb_tree *tree, void *item) +{ + /* Algorithm based on RB-Insert from section 14.3 of _Introduction + to Algorithms_, Cormen et al., MIT Press 1990, ISBN + 0-262-03141-8. */ + + rb_node *ap[RB_MAX_HEIGHT]; /* Stack A: Nodes. */ + char ad[RB_MAX_HEIGHT]; /* Stack A: Directions. */ + int ak = 1; /* Stack A: Pointer. */ + + rb_node *t, *x, *y, *n; + + assert (tree != NULL); + t = &tree->root; + x = t->link[0]; + + if (x == NULL) + { + tree->count++; + assert (tree->count == 1); + x = t->link[0] = xmalloc (sizeof (rb_node)); + x->data = item; + x->link[0] = x->link[1] = NULL; + x->color = RB_BLACK; + return &x->data; + } + + ad[0] = 0; + ap[0] = &tree->root; + + for (;;) + { + int diff = tree->cmp (item, x->data, tree->param); + + if (diff < 0) + { + ap[ak] = x; + ad[ak++] = 0; + y = x->link[0]; + if (y == NULL) + { + n = x = x->link[0] = xmalloc (sizeof (rb_node)); + break; + } + } + else if (diff > 0) + { + ap[ak] = x; + ad[ak++] = 1; + y = x->link[1]; + if (y == NULL) + { + n = x = x->link[1] = xmalloc (sizeof (rb_node)); + break; + } + } + else + return &x->data; + + x = y; + } + + tree->count++; + x->data = item; + x->link[0] = x->link[1] = NULL; + x->color = RB_RED; + + for (;;) + { + if (ak < 3 || ap[ak - 1]->color != RB_RED) + break; + + if (ad[ak - 2] == 0) + { + y = ap[ak - 2]->link[1]; + if (y != NULL && y->color == RB_RED) + { + /* Case 1. */ + ap[ak - 1]->color = y->color = RB_BLACK; + ap[ak - 2]->color = RB_RED; + ak -= 2; + } + else + { + if (ad[ak - 1] == 1) + { + /* Case 2. */ + x = ap[ak - 1]; + y = x->link[1]; + x->link[1] = y->link[0]; + y->link[0] = x; + ap[ak - 2]->link[0] = y; + } + else + y = ap[ak - 1]; + + /* Case 3. */ + x = ap[ak - 2]; + x->color = RB_RED; + y->color = RB_BLACK; + + x->link[0] = y->link[1]; + y->link[1] = x; + ap[ak - 3]->link[(int) ad[ak - 3]] = y; + + break; + } + } + else + { + y = ap[ak - 2]->link[0]; + if (y != NULL && y->color == RB_RED) + { + /* Case 1. */ + ap[ak - 1]->color = y->color = RB_BLACK; + ap[ak - 2]->color = RB_RED; + ak -= 2; + } + else + { + if (ad[ak - 1] == 0) + { + /* Case 2. */ + x = ap[ak - 1]; + y = x->link[0]; + x->link[0] = y->link[1]; + y->link[1] = x; + ap[ak - 2]->link[1] = y; + } + else + y = ap[ak - 1]; + + /* Case 3. */ + x = ap[ak - 2]; + x->color = RB_RED; + y->color = RB_BLACK; + + x->link[1] = y->link[0]; + y->link[0] = x; + ap[ak - 3]->link[(int) ad[ak - 3]] = y; + break; + } + } + } + + tree->root.link[0]->color = RB_BLACK; + + return &n->data; +} + +/* Search TREE for an item matching ITEM, and return it if found. */ +void * +rb_find (const rb_tree *tree, const void *item) +{ + const rb_node *p; + + assert (tree != NULL); + for (p = tree->root.link[0]; p; ) + { + int diff = tree->cmp (item, p->data, tree->param); + + if (diff < 0) + p = p->link[0]; + else if (diff > 0) + p = p->link[1]; + else + return p->data; + } + + return NULL; +} + +/* Search TREE for an item close to the value of ITEM, and return it. + This function will return a null pointer only if TREE is empty. */ +void * +rb_find_close (const rb_tree *tree, const void *item) +{ + const rb_node *p; + + assert (tree != NULL); + p = tree->root.link[0]; + if (p == NULL) + return NULL; + + for (;;) + { + int diff = tree->cmp (item, p->data, tree->param); + int t; + + if (diff < 0) + t = 0; + else if (diff > 0) + t = 1; + else + return p->data; + + if (p->link[t]) + p = p->link[t]; + else + return p->data; + } +} + +/* Searches red-black tree TREE for an item matching ITEM. If found, + the item is removed from the tree and the actual item found is + returned to the caller. If no item matching ITEM exists in the + tree, returns NULL. */ +void * +rb_delete (rb_tree *tree, const void *item) +{ + /* Algorithm based on RB-Delete and RB-Delete-Fixup from section + 14.4 of _Introduction to Algorithms_, Cormen et al., MIT Press + 1990, ISBN 0-262-03141-8. */ + + rb_node *pa[RB_MAX_HEIGHT]; /* Stack P: Nodes. */ + char a[RB_MAX_HEIGHT]; /* Stack P: Bits. */ + int k = 1; /* Stack P: Pointer. */ + + rb_node *w, *x, *y, *z; + + assert (tree != NULL); + + a[0] = 0; + pa[0] = &tree->root; + z = tree->root.link[0]; + for (;;) + { + int diff; + + if (z == NULL) + return NULL; + + diff = tree->cmp (item, z->data, tree->param); + if (diff == 0) + break; + + pa[k] = z; + if (diff < 0) + { + z = z->link[0]; + a[k] = 0; + } + else if (diff > 0) + { + z = z->link[1]; + a[k] = 1; + } + k++; + } + tree->count--; + + item = z->data; + + /* RB-Delete: Line 1. */ + if (z->link[0] == NULL || z->link[1] == NULL) + { + /* Line 2. */ + y = z; + + /* Lines 4-6. */ + if (y->link[0] != NULL) + x = y->link[0]; + else + x = y->link[1]; + + pa[k - 1]->link[(int) a[k - 1]] = x; + } + else + { + pa[k] = z; + a[k++] = 1; + + /* Line 3. */ + y = z->link[1]; + while (y->link[0]) + { + pa[k] = y; + a[k++] = 0; + y = y->link[0]; + } + + /* Lines 4-6. */ + x = y->link[1]; + + /* Lines 13-15. */ + z->data = y->data; + pa[k - 1]->link[(int) a[k - 1]] = x; + } + + /* Line 16. */ + if (y->color == RB_RED) + { + free (y); + return (void *) item; + } + + free (y); + + /* Numbers below are line numbers from RB-Delete-Fixup. */ + while (k > 1 && (x == NULL || x->color == RB_BLACK)) /* 1 */ + { + if (a[k - 1] == 0) /* 2 */ + { + w = pa[k - 1]->link[1]; /* 3 */ + + if (w->color == RB_RED) /* 4 */ + { + /* Case 1. */ + w->color = RB_BLACK; /* 5 */ + pa[k - 1]->color = RB_RED; /* 6 */ + + pa[k - 1]->link[1] = w->link[0]; /* 7 */ + w->link[0] = pa[k - 1]; + pa[k - 2]->link[(int) a[k - 2]] = w; + + pa[k] = pa[k - 1]; + a[k] = 0; + pa[k - 1] = w; + k++; + + w = pa[k - 1]->link[1]; /* 8 */ + } + + if ((w->link[0] == NULL || w->link[0]->color == RB_BLACK) /* 9 */ + && (w->link[1] == NULL || w->link[1]->color == RB_BLACK)) + { + /* Case 2. */ + w->color = RB_RED; /* 10 */ + + x = pa[k - 1]; /* 11 */ + k--; + } + else + { + if (w->link[1] == NULL || w->link[1]->color == RB_BLACK) /* 12 */ + { + /* Case 3. */ + w->link[0]->color = RB_BLACK; /* 13 */ + w->color = RB_RED; /* 14 */ + + y = w->link[0]; /* 15 */ + w->link[0] = y->link[1]; + y->link[1] = w; + + w = pa[k - 1]->link[1] = y; /* 16 */ + } + + /* Case 4. */ + w->color = pa[k - 1]->color; /* 17 */ + pa[k - 1]->color = RB_BLACK; /* 18 */ + w->link[1]->color = RB_BLACK; /* 19 */ + + pa[k - 1]->link[1] = w->link[0]; /* 20 */ + w->link[0] = pa[k - 1]; + pa[k - 2]->link[(int) a[k - 2]] = w; + + x = tree->root.link[0]; /* 21 */ + break; + } + } + else + { + w = pa[k - 1]->link[0]; + if (w->color == RB_RED) + { + /* Case 1. */ + w->color = RB_BLACK; + pa[k - 1]->color = RB_RED; + + pa[k - 1]->link[0] = w->link[1]; + w->link[1] = pa[k - 1]; + pa[k - 2]->link[(int) a[k - 2]] = w; + + pa[k] = pa[k - 1]; + a[k] = 1; + pa[k - 1] = w; + k++; + + w = pa[k - 1]->link[0]; + } + + if ((w->link[0] == NULL || w->link[0]->color == RB_BLACK) + && (w->link[1] == NULL || w->link[1]->color == RB_BLACK)) + { + /* Case 2. */ + w->color = RB_RED; + x = pa[k - 1]; + k--; + } + else + { + if (w->link[0] == NULL || w->link[0]->color == RB_BLACK) + { + /* Case 3. */ + w->link[1]->color = RB_BLACK; + w->color = RB_RED; + + y = w->link[1]; + w->link[1] = y->link[0]; + y->link[0] = w; + + w = pa[k - 1]->link[0] = y; + } + + /* Case 4. */ + w->color = pa[k - 1]->color; + pa[k - 1]->color = RB_BLACK; + w->link[0]->color = RB_BLACK; + + pa[k - 1]->link[0] = w->link[1]; + w->link[1] = pa[k - 1]; + pa[k - 2]->link[(int) a[k - 2]] = w; + + x = tree->root.link[0]; + break; + } + } + } + + if (x != NULL) + x->color = RB_BLACK; /* 23 */ + + return (void *) item; +} + +/* Inserts ITEM into TREE. Returns NULL if the item was inserted, + otherwise a pointer to the duplicate item. */ +void * +rb_insert (rb_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = rb_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +/* If ITEM does not exist in TREE, inserts it and returns NULL. If a + matching item does exist, it is replaced by ITEM and the item + replaced is returned. The caller is responsible for freeing the + item returned. */ +void * +rb_replace (rb_tree *tree, void *item) +{ + void **p; + + assert (tree != NULL); + + p = rb_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} + +/* Delete ITEM from TREE when you know that ITEM must be in TREE. For + debugging purposes. */ +void * +(rb_force_delete) (rb_tree *tree, void *item) +{ + void *found = rb_delete (tree, item); + assert (found != NULL); + return found; +} + +#if SELF_TEST + +/* Used to flag delayed aborting. */ +int done = 0; + +/* Print the structure of node NODE of a red-black tree, which is + LEVEL levels from the top of the tree. Uses different delimiters + to visually distinguish levels. */ +void +print_structure (rb_node *node, int level) +{ + char lc[] = "([{<`/"; + char rc[] = ")]}>'\\"; + + assert (level <= 10); + + if (node == NULL) + { + printf (" nil"); + fflush (stdout); + return; + } + printf (" %c%d%c", + lc[level % 6], (int) node->data, + node->color == RB_BLACK ? 'b' : 'r'); + fflush (stdout); + if (node->link[0] || node->link[1]) + print_structure (node->link[0], level + 1); + if (node->link[1]) + print_structure (node->link[1], level + 1); + printf ("%c", rc[level % 6]); + fflush (stdout); +} + +/* Compare two integers A and B and return a strcmp()-type result. */ +int +compare_ints (const void *a, const void *b, void *param unused) +{ + return ((int) a) - ((int) b); +} + +/* Print the value of integer A. */ +void +print_int (void *a, void *param unused) +{ + printf (" %d", (int) a); +} + +/* Linearly print contents of TREE. */ +void +print_contents (rb_tree *tree) +{ + rb_walk (tree, print_int, NULL); + printf ("\n"); +} + +/* Examine NODE in a red-black tree. *COUNT is increased by the + number of nodes in the tree, including the current one. Returns + the number of black nodes (including this node) in a path from this + node to any leaf. */ +int +recurse_tree (rb_node *node, int *count, int ge, int le) +{ + if (node) + { + const int d = (int) node->data; + int nl = 1; + int nr = 1; + + (*count)++; + + if (!(d >= ge) || !(d <= le)) + { + printf (" Node %d is out of order in the tree.\n", d); + done = 1; + } + + if (node->link[0]) + nl = recurse_tree (node->link[0], count, ge, d - 1); + if (node->link[1]) + nr = recurse_tree (node->link[1], count, d + 1, le); + + if (node->color != RB_RED && node->color != RB_BLACK) + { + printf (" Node %d is neither red nor black (%d).\n", d, node->color); + done = 1; + } + + if (node->color == RB_RED + && node->link[0] && node->link[0]->color == RB_RED) + { + printf (" Red node %d has red left child %d\n", + d, (int) node->link[0]->data); + done = 1; + } + + if (node->color == RB_RED + && node->link[1] && node->link[1]->color == RB_RED) + { + printf (" Red node %d has red right child %d\n", + d, (int) node->link[1]->data); + done = 1; + } + + if (nl != nr) + { + printf (" Node %d has two different black-heights: left bh=%d, " + "right bh=%d\n", d, nl, nr); + done = 1; + } + + return (node->color == RB_BLACK) + nl; + } + else return 1; +} + +/* Check that everything about TREE is kosher. */ +void +verify_tree (rb_tree *tree) +{ + int count = 0; + recurse_tree (tree->root.link[0], &count, INT_MIN, INT_MAX); + if (count != tree->count) + { + printf (" Tree has %d nodes, but tree count is %d.\n", + count, tree->count); + done = 1; + } + if (done) + abort (); +} + +/* Arrange the N elements of ARRAY in random order. */ +void +shuffle (int *array, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + int j = i + rand () % (n - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + +/* Compares red-black trees rooted at A and B, making sure that they + are identical. */ +void +compare_trees (rb_node *a, rb_node *b) +{ + if (a == NULL || b == NULL) + { + assert (a == NULL && b == NULL); + return; + } + if (a->data != b->data || a->color != b->color + || ((a->link[0] != NULL) ^ (b->link[0] != NULL)) + || ((a->link[1] != NULL) ^ (b->link[1] != NULL))) + { + printf (" Copied nodes differ: %d b=%d a->color=%d b->color=%d a:", + (int) a->data, (int) b->data, a->color, b->color); + if (a->link[0]) + printf ("l"); + if (a->link[1]) + printf ("r"); + printf (" b:"); + if (b->link[0]) + printf ("l"); + if (b->link[1]) + printf ("r"); + printf ("\n"); + abort (); + } + if (a->link[0] != NULL) + compare_trees (a->link[0], b->link[0]); + if (a->link[1] != NULL) + compare_trees (a->link[1], b->link[1]); +} + +/* Simple stress test procedure for the red-black tree routines. Does + the following: + + * Generate a random number seed. By default this is generated from + the current time. You can also pass a seed value on the command + line if you want to test the same case. The seed value is + displayed. + + * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 + into it, in random order. Verify the tree structure after each + insertion. + + * Remove each integer from the tree, in a different random order. + After each deletion, verify the tree structure; also, make a copy + of the tree into a new tree, verify the copy and compare it to the + original, then destroy the copy. + + * Destroy the tree, increment the random seed value, and start over. + + If you make any modifications to the red-black tree routines, then + you might want to insert some calls to print_structure() at + strategic places in order to be able to see what's really going on. + Also, memory debuggers like Checker or Purify are very handy. */ +#define TREE_SIZE 16 +#define N_ITERATIONS 1024 +int +main (int argc, char **argv) +{ + int array[TREE_SIZE]; + int seed; + int iteration; + + if (argc == 2) + seed = atoi (argv[1]); + else + seed = time (0) * 257 % 32768; + + fputs ("Testing rb...\n", stdout); + + for (iteration = 1; iteration <= N_ITERATIONS; iteration++) + { + rb_tree *tree; + int i; + + printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); + fflush (stdout); + + srand (seed++); + + for (i = 0; i < TREE_SIZE; i++) + array[i] = i; + shuffle (array, TREE_SIZE); + + tree = rb_create (compare_ints, NULL); + for (i = 0; i < TREE_SIZE; i++) + rb_force_insert (tree, (void *) (array[i])); + verify_tree (tree); + + shuffle (array, TREE_SIZE); + for (i = 0; i < TREE_SIZE; i++) + { + rb_tree *copy; + + rb_delete (tree, (void *) (array[i])); + verify_tree (tree); + + copy = rb_copy (tree, NULL); + verify_tree (copy); + compare_trees (tree->root.link[0], copy->root.link[0]); + rb_destroy (copy, NULL); + + if (i % 128 == 0) + { + putchar ('.'); + fflush (stdout); + } + } + fputs (" good.\n", stdout); + + rb_destroy (tree, NULL); + } + + return 0; +} +#endif /* SELF_TEST */ + +/* + Local variables: + compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./rb-test rb.c" + End: +*/ diff --git a/avl-1.4.0/rb.h b/avl-1.4.0/rb.h new file mode 100644 index 0000000..26a9f49 --- /dev/null +++ b/avl-1.4.0/rb.h @@ -0,0 +1,155 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file rb.h in libavl. */ + +#if !rb_h +#define rb_h 1 + +/* The default maximum height of 32 allows for red-black trees having + between 65,535 and 4,294,967,295 nodes, depending on order of + insertion. You may change this compile-time constant as you + wish. */ +#ifndef RB_MAX_HEIGHT +#define RB_MAX_HEIGHT 32 +#endif + +/* Node colors. */ +enum + { + RB_BLACK, + RB_RED, + }; + +/* Structure for a node in a red-black tree. */ +typedef struct rb_node + { + void *data; /* Pointer to data. */ + struct rb_node *link[2]; /* Subtrees. */ + signed char color; /* Color. */ + char cache; /* Used during insertion. */ + signed char pad[2]; /* Unused. Reserved for threaded trees. */ + } +rb_node; + +/* Used for traversing a red-black tree. */ +typedef struct rb_traverser + { + int init; /* Initialized? */ + int nstack; /* Top of stack. */ + const rb_node *p; /* Used for traversal. */ + const rb_node *stack[RB_MAX_HEIGHT];/* Descended trees. */ + } +rb_traverser; + +/* Initializer for rb_traverser. */ +#define RB_TRAVERSER_INIT {0} + +/* Function types. */ +#if !AVL_FUNC_TYPES +#define AVL_FUNC_TYPES 1 +typedef int (*avl_comparison_func) (const void *a, const void *b, void *param); +typedef void (*avl_node_func) (void *data, void *param); +typedef void *(*avl_copy_func) (void *data, void *param); +#endif + +/* Structure which holds information about a red-black tree. */ +typedef struct rb_tree + { +#if PSPP + struct arena **owner; /* Arena to store nodes. */ +#endif + rb_node root; /* Tree root node. */ + avl_comparison_func cmp; /* Used to compare keys. */ + int count; /* Number of nodes in the tree. */ + void *param; /* Arbitary user data. */ + } +rb_tree; + +#if PSPP +#define MAYBE_ARENA struct arena **owner, +#else +#define MAYBE_ARENA /* nothing */ +#endif + +/* General functions. */ +rb_tree *rb_create (MAYBE_ARENA avl_comparison_func, void *param); +void rb_destroy (rb_tree *, avl_node_func); +void rb_free (rb_tree *); +int rb_count (const rb_tree *); +rb_tree *rb_copy (MAYBE_ARENA const rb_tree *, avl_copy_func); + +/* Walk the tree. */ +void rb_walk (const rb_tree *, avl_node_func, void *param); +void *rb_traverse (const rb_tree *, rb_traverser *); +#define rb_init_traverser(TRAVERSER) ((TRAVERSER)->init = 0) + +/* Search for a given item. */ +void **rb_probe (rb_tree *, void *); +void *rb_delete (rb_tree *, const void *); +void *rb_find (const rb_tree *, const void *); +void *rb_find_close (const rb_tree *, const void *); + +#if __GCC__ >= 2 +extern inline void * +rb_insert (rb_tree *tree, void *item) +{ + void **p = rb_probe (tree, item); + return (*p == item) ? NULL : *p; +} + +extern inline void * +rb_replace (rb_tree *tree, void *item) +{ + void **p = rb_probe (tree, item); + if (*p == item) + return NULL; + else + { + void *r = *p; + *p = item; + return r; + } +} +#else /* not gcc */ +void *rb_insert (rb_tree *tree, void *item); +void *rb_replace (rb_tree *tree, void *item); +#endif /* not gcc */ + +/* Easy assertions on insertion & deletion. */ +#ifndef NDEBUG +#define rb_force_insert(A, B) \ + do \ + { \ + void *r = rb_insert (A, B); \ + assert (r == NULL); \ + } \ + while (0) +void *rb_force_delete (rb_tree *, void *); +#else +#define rb_force_insert(A, B) \ + rb_insert (A, B) +#define rb_force_delete(A, B) \ + rb_delete (A, B) +#endif + +#endif /* rb_h */ diff --git a/avl-1.4.0/texinfo.tex b/avl-1.4.0/texinfo.tex new file mode 100644 index 0000000..aa52853 --- /dev/null +++ b/avl-1.4.0/texinfo.tex @@ -0,0 +1,5484 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{1999-01-05}% +% +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.gnu.org/pub/gnu/texinfo.tex +% /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) +% ftp://tug.org/tex/texinfo.tex +% ftp://ctan.org/macros/texinfo/texinfo.tex +% (and all CTAN mirrors, finger ctan@ctan.org for a list). +% The texinfo.tex in the texinfo distribution itself could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. +% Please include a precise test case in each bug report, +% including a complete document with which we can reproduce the problem. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For simple +% manuals, however, you can get away with: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever, to process the dvi file. +% The extra runs of TeX get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% Save some parts of plain tex whose names we will redefine. + +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexi=\i +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexstar=\* +\let\ptext=\t + +% We never want plain's outer \+ definition in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + + +\message{Basics,} +\chardef\other=12 + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortContents\undefined \gdef\putwordShortContents{Short Contents}\fi +\ifx\putwordTableofContents\undefined\gdef\putwordTableofContents{Table of Contents}\fi + +% Ignore a token. +% +\def\gobble#1{} + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset +\newdimen \normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\ifx\eTeXversion\undefined +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\else +\def\loggingall{\tracingcommands3 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \tracingscantokens1 \tracingassigns1 \tracingifs1 + \tracinggroups1 \tracingnesting2 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\fi + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \turnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt +\def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce actual \{ & \} command in an index. + \catcode`\{ = 12 \catcode`\} = 12 + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\@ = 0 \catcode`\\ = 12 + @gdef@lbracecmd[\{]% + @gdef@rbracecmd[\}]% +@endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Go into vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % Don't add any leading before our big empty box, but allow a page + % break, since the best break might be right here. + \allowbreak + \nointerlineskip + \vtop to #1\mil{\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + + +% @page forces the start of a new page +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + +%\hbox{{\rm#1}}\hfil\break}} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent is defined for the Info formatting commands only. +\let\paragraphindent=\comment + +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% +\let\chapter=\relax +\let\unnumbered=\relax +\let\top=\relax +\let\unnumberedsec=\relax +\let\unnumberedsection=\relax +\let\unnumberedsubsec=\relax +\let\unnumberedsubsection=\relax +\let\unnumberedsubsubsec=\relax +\let\unnumberedsubsubsection=\relax +\let\section=\relax +\let\subsec=\relax +\let\subsubsec=\relax +\let\subsection=\relax +\let\subsubsection=\relax +\let\appendix=\relax +\let\appendixsec=\relax +\let\appendixsection=\relax +\let\appendixsubsec=\relax +\let\appendixsubsection=\relax +\let\appendixsubsubsec=\relax +\let\appendixsubsubsection=\relax +\let\contents=\relax +\let\smallbook=\relax +\let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifnottex{\doignore{ifnottex}} +\def\html{\doignore{html}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + % This @ is a catcode 12 token (that is the normal catcode of @ in + % this texinfo.tex file). We change the catcode of @ below to match. + \long\def\doignoretext##1@end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % We must not have @c interpreted as a control sequence. + \catcode`\@ = 12 + % + % Make the letter c a comment character so that the rest of the line + % will be ignored. This way, the document can have (for example) + % @c @end ifinfo + % and the @end ifinfo will be properly ignored. + % (We've just changed @ to catcode 12.) + \catcode`\c = 14 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont + \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont + \let\tensf = \nullfont + % Similarly for index fonts (mostly for their use in + % smallexample) + \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont + \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont + \let\indsf = \nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}}% + % Do not execute macro definitions. + % `c' is a comment character, so the word `macro' will get cut off. + \def\macro{\doignore{ma}}% +} + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +% +{ + \catcode`\_ = \active + % + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup + \catcode`\-=12 \catcode`\_=12 + \indexbreaks \let_\normalunderscore + \valuexxx} +} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable, since the result +% winds up in the index file. This means that if the variable's value +% contains other Texinfo commands, it's almost certain it will fail +% (although perhaps we could fix that with sufficient work to do a +% one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text +% following, through the first @end iftex (etc.). Make `@end iftex' +% (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} + +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} + +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math means output in math mode. +% We don't use $'s directly in the definition of \math because control +% sequences like \math are expanded when the toc file is written. Then, +% we read the toc file back, the $'s will be normal characters (as they +% should be, according to the definition of Texinfo). So we must use a +% control sequence to switch into and out of math mode. +% +% This isn't quite enough for @math to work properly in indices, but it +% seems unlikely it will ever be needed there. +% +\let\implicitmath = $ +\def\math#1{\implicitmath #1\implicitmath} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \iflinks + \readauxfile + \fi % \openindices needs to do some work in any case. + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{fonts,} +% Font-change commands. + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Use Computer Modern fonts at \magstephalf (11pt). +\newcount\mainmagstep +\mainmagstep=\magstephalf + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\ifx\bigger\relax +\let\mainmagstep=\magstep1 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} +\else +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices and small examples (9pt). +% We actually use the slanted font rather than the italic, +% because texinfo normally uses the slanted fonts for that. +% Do not make many font distinctions in general in the index, since they +% aren't very useful. +\setfont\ninett\ttshape{9}{1000} +\setfont\ninettsl\ttslshape{10}{900} +\setfont\indrm\rmshape{9}{1000} +\setfont\indit\itshape{9}{1000} +\setfont\indsl\slshape{9}{1000} +\let\indtt=\ninett +\let\indttsl=\ninettsl +\let\indsf=\indrm +\let\indbf=\indrm +\setfont\indsc\scshape{10}{900} +\font\indi=cmmi9 +\font\indsy=cmsy9 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} + +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} + +%\let\ssecbf=\ssecrm + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts, we +% don't bother to reset \scriptfont and \scriptscriptfont (which would +% also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf +} + + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\indexfonts{% + \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl + \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc + \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl + \resetmathfonts \setleading{12pt}} + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} +\def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic +\let\cite=\smartslanted + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp#1{`\tclose{#1}'\null} +\setfont\smallrm\rmshape{8}{1000} +\font\smallsy=cmsy9 +\def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active + \catcode`\_=\active + % + \global\def\code{\begingroup + \catcode`\-=\active \let-\codedash + \catcode`\_=\active \let_\codeunder + \codex + } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} +\def\codex #1{\tclose{#1}\endgroup} + +%\let\exp=\tclose %Was temporary + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is kbdinputdistinct. (Too much of a hassle to call the macro, +% the catcodes are wrong for parsearg to work.) +\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional second argument +% specifying the text to display. First (mandatory) arg is the url. +% Perhaps eventually put in a hypertex \special here. +% +\def\uref#1{\urefxxx #1,,\finish} +\def\urefxxx#1,#2,#3\finish{% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \unhbox0\ (\code{#1})% + \else + \code{#1}% + \fi +} + +% rms does not like the angle brackets --karl, 17may97. +% So now @email is just like @uref. +%\def\email#1{\angleleft{\tt #1}\angleright} +\let\email=\uref + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi + % + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% Produces Day Month Year style of output. +\def\today{\number\day\space +\ifcase\month\or +January\or February\or March\or April\or May\or June\or +July\or August\or September\or October\or November\or December\fi +\space\number\year} + +% Use this if you want the Month Day, Year style of output. +%\def\today{\ifcase\month\or +%January\or February\or March\or April\or May\or June\or +%July\or August\or September\or October\or November\or December\fi +%\space\number\day, \number\year} + +% @settitle line... specifies the title of the document, for headings +% It generates no output of its own + +\def\thistitle{No Title} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +% @table, @ftable, @vtable. +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey #1#2{% +\aboveenvbreak % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\afterenvbreak\endgroup}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +% Set sfcode to normal for the chars that usually have another value. +% These are `.?!:;,' +\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; + % typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable syntax +\def\tab{&\hskip1sp\relax} % 2/2/96 + % tiny skip here makes sure this column space is + % maintained, even if it is never used. + +% @multitable ... @end multitable definitions: +% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup + \vskip\parskip + \let\item\crcr + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\else +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% The \closeout helps reduce unnecessary open files; the limit on the +% Acorn RISC OS is a mere 16 files. +\def\synindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\doindex{#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\docodeindex{#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +\def\ { }% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. +% (Must be a way to avoid doing expansion at all, and thus not have to +% laboriously list every single command here.) +\def\@{@}% will be @@ when we switch to @ as escape char. +% Need these in case \tex is in effect and \{ is a \delimiter again. +% But can't use \lbracecmd and \rbracecmd because texindex assumes +% braces and backslashes are used only as delimiters. +\let\{ = \mylbrace +\let\} = \myrbrace +\def\_{{\realbackslash _}}% +\def\w{\realbackslash w }% +\def\bf{\realbackslash bf }% +%\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\sf{\realbackslash sf}% +\def\tt{\realbackslash tt}% +\def\gtr{\realbackslash gtr}% +\def\less{\realbackslash less}% +\def\hat{\realbackslash hat}% +\def\TeX{\realbackslash TeX}% +\def\dots{\realbackslash dots }% +\def\result{\realbackslash result}% +\def\equiv{\realbackslash equiv}% +\def\expansion{\realbackslash expansion}% +\def\print{\realbackslash print}% +\def\error{\realbackslash error}% +\def\point{\realbackslash point}% +\def\copyright{\realbackslash copyright}% +\def\tclose##1{\realbackslash tclose {##1}}% +\def\code##1{\realbackslash code {##1}}% +\def\uref##1{\realbackslash uref {##1}}% +\def\url##1{\realbackslash url {##1}}% +\def\env##1{\realbackslash env {##1}}% +\def\command##1{\realbackslash command {##1}}% +\def\option##1{\realbackslash option {##1}}% +\def\dotless##1{\realbackslash dotless {##1}}% +\def\samp##1{\realbackslash samp {##1}}% +\def\,##1{\realbackslash ,{##1}}% +\def\t##1{\realbackslash t {##1}}% +\def\r##1{\realbackslash r {##1}}% +\def\i##1{\realbackslash i {##1}}% +\def\b##1{\realbackslash b {##1}}% +\def\sc##1{\realbackslash sc {##1}}% +\def\cite##1{\realbackslash cite {##1}}% +\def\key##1{\realbackslash key {##1}}% +\def\file##1{\realbackslash file {##1}}% +\def\var##1{\realbackslash var {##1}}% +\def\kbd##1{\realbackslash kbd {##1}}% +\def\dfn##1{\realbackslash dfn {##1}}% +\def\emph##1{\realbackslash emph {##1}}% +\def\acronym##1{\realbackslash acronym {##1}}% +% +% Handle some cases of @value -- where the variable name does not +% contain - or _, and the value does not contain any +% (non-fully-expandable) commands. +\let\value = \expandablevalue +% +\unsepspaces +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexdummytex{TeX} +\def\indexdummydots{...} + +\def\indexnofonts{% +% Just ignore accents. +\let\,=\indexdummyfont +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +\let\dotless=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% +\let\w=\indexdummyfont +\let\t=\indexdummyfont +\let\r=\indexdummyfont +\let\i=\indexdummyfont +\let\b=\indexdummyfont +\let\emph=\indexdummyfont +\let\strong=\indexdummyfont +\let\cite=\indexdummyfont +\let\sc=\indexdummyfont +%Don't no-op \tt, since it isn't a user-level command +% and is used in the definitions of the active chars like <, >, |... +%\let\tt=\indexdummyfont +\let\tclose=\indexdummyfont +\let\code=\indexdummyfont +\let\url=\indexdummyfont +\let\uref=\indexdummyfont +\let\env=\indexdummyfont +\let\command=\indexdummyfont +\let\option=\indexdummyfont +\let\file=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +\let\TeX=\indexdummytex +\let\dots=\indexdummydots +\def\@{@}% +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other + @gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% For \ifx comparisons. +\def\emptymacro{\empty} + +% Most index entries go through here, but \dosubind is the general case. +% +\def\doind#1#2{\dosubind{#1}{#2}\empty} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. +% +\def\dosubind#1#2#3{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% + \fi + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio = 0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + \def\thirdarg{#3}% + % + % If third arg is present, precede it with space in sort key. + \ifx\thirdarg\emptymacro + \let\subentry = \empty + \else + \def\subentry{ #3}% + \fi + % + % First process the index-string with all font commands turned off + % to get the string to sort by. + {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% + % + % Now produce the complete index entry, with both the sort key and the + % original text, including any font commands. + \toks0 = {#2}% + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + % + % If third (subentry) arg is present, add it to the index string. + \ifx\thirdarg\emptymacro \else + \toks0 = {#3}% + \edef\temp{\temp{\the\toks0}}% + \fi + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write will make \lastskip zero. The result is that sequences + % like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + \iflinks + \ifvmode + \skip0 = \lastskip + \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi + \fi + % + \temp % do the write + % + % + \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi + \fi + }% + }% + \penalty\count255 + }% +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \indexfonts \rm + \tolerance = 9500 + \indexbreaks + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + (Index is nonexistent) + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + (Index is empty) + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \penalty -300 + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % + % Do our best not to break after the initial. + \nobreak +}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ #2% The page number ends the paragraph. + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {\global\setbox\partialpage = \vbox{% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case, we must prevent the second \partialpage from + % simply overwriting the first, causing us to lose the page. + % This will preserve it until a real output routine can ship it + % out. Generally, \partialpage will be empty when this runs and + % this will be a no-op. + \unvbox\partialpage + % + % Unvbox the main output page. + \unvbox255 + \kern-\topskip \kern\baselineskip + }}% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +\def\pagesofar{% + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split, in box0 and box2. + \advance\vsize by \ht\partialpage + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +\def\enddoublecolumns{% + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +\def\balancecolumns{% + % Called at the end of the double column material. + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Define chapters, sections, etc. + +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +\def\appendixletter{\char\the\appendixno} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise. +\def\thischapter{} +\def\thissection{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raise/lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi +\fi +} + +% @chapter, @appendix, @unnumbered. +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +% We don't substitute the actual chapter name into \thischapter +% because we don't want its macros evaluated now. +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\the\chapno}}}% +\temp +\donoderef +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec +} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \appendixno by 1 +\message{\putwordAppendix\space \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\putwordAppendix{} \appendixletter}}}% +\temp +\appendixnoderef +\global\let\section = \appendixsec +\global\let\subsection = \appendixsubsec +\global\let\subsubsection = \appendixsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the to achieve this: TeX expands \the only once, +% simply yielding the contents of . (We also do this for +% the toc entries.) +\toks0 = {#1}\message{(\the\toks0)}% +% +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% +\temp +\unnumbnoderef +\global\let\section = \unnumberedsec +\global\let\subsection = \unnumberedsubsec +\global\let\subsubsection = \unnumberedsubsubsec +} + +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\the\chapno}{\the\secno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\appendixletter}{\the\secno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{% +\plainsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsections. +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{% +\plainsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsubsections. +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{% +\plainsubsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% + \pchapsepmacro + {% + \chapfonts \rm + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} + +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} + +% Subsection titles. +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} + +% Subsubsection titles. +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} + + +% Print any size section title. +% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% + {% + % Switch to the right set of fonts. + \csname #1fonts\endcsname \rm + % + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% + % + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% + }% + \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak +} + + +\message{toc,} +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. We supply {\folio} at the end of the +% argument, which will end up as the last argument to the \...entry macro. +% +% We open the .toc file here instead of at @setfilename or any other +% given time so that @contents can be put in the document anywhere. +% +\newif\iftocfileopened +\def\writetocentry#1{% + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + \iflinks \write\tocfile{#1{\folio}}\fi +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Finish up the main text and prepare to read what we've written +% to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \pageno = \lastnegativepageno \fi +} + + +% Normal (long) toc. +\def\contents{% + \startcontents{\putwordTableofContents}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortContents}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + +% See comments in \dochapentry re vbox and related settings +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% +} + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +\setbox0 = \hbox{\shortcontrm \putwordAppendix } +\newdimen\shortappendixwidth \shortappendixwidth = \wd0 + +\def\shortchaplabel#1{% + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno{#2}}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno{#2}}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, so characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} + +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% Furthermore, these definitions must come after we define our fonts. +\newbox\dblarrowbox \newbox\longdblarrowbox +\newbox\pushcharbox \newbox\bullbox +\newbox\equivbox \newbox\errorbox + +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +% Adapted from the manmac format (p.420 of TeXbook) +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% Adapted from the TeXbook's \boxit. +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + +% The @error{} command. +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 % plus + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\long\def\cartouche{% +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. +% +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} + +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} + +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + +% @small... is usually equivalent to the non-small (@smallbook +% redefines). We must call \example (or whatever) last in the +% definition, since it reads the return following the @example (or +% whatever) command. +% +% This actually allows (for example) @end display inside an +% @smalldisplay. Too bad, but makeinfo will catch the error anyway. +% +\def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} +\def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} +\def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + +% Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. +% Originally contributed by Pavel@xerox. +\def\smalllispx{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \indexfonts + \lisp +} + +% @display: same as @lisp except keep current font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} + +% @smalldisplay (when @smallbook): @display plus smaller fonts. +% +\def\smalldisplayx{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \indexfonts \rm + \display +} + +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} + +% @smallformat (when @smallbook): @format plus smaller fonts. +% +\def\smallformatx{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \indexfonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} + +% @flushright. +% +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble +} + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + + +\message{defuns,} +% Define formatter for defuns +% First, allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\def\ampnr{\&} +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +% Get the values of \leftskip and \rightskip as they were +% outside the @def... +\dimen2=\leftskip +\advance\dimen2 by -\defbodyindent +\noindent +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +{% Adjust \hsize to exclude the ambient margins, +% so that \rightline will obey them. +\advance \hsize by -\dimen2 +\rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% +% Make all lines underfull and no complaints: +\tolerance=10000 \hbadness=10000 +\advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % 61 is `=' +\obeylines\activeparens\spacesplit#3} + +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by the space, is the class name. +% +\def\defmethparsebody#1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +% @deftypemethod has an extra argument that nothing else does. Sigh. +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by the space, is the class name. +% #5 is the method's return type. +% +\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. + +\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % +\obeylines\spacesplit#3} + +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs #1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +\hyphenchar\tensl=0 +#1% +\hyphenchar\tensl=45 +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Function}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% +\deftypefunargs {#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Macro}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{Special Form}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% This definition is run if you use @defunx +% anywhere other than immediately after a @defun or @defunx. + +\def\deffnx #1 {\errmessage{@deffnx in invalid context}} +\def\defunx #1 {\errmessage{@defunx in invalid context}} +\def\defmacx #1 {\errmessage{@defmacx in invalid context}} +\def\defspecx #1 {\errmessage{@defspecx in invalid context}} +\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypefunx #1 {\errmessage{@deftypefunx in invalid context}} + +% @defmethod, and so on + +% @defop CATEGORY CLASS OPERATION ARG... + +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} + +\def\defopheader #1#2#3{% +\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype{} on #1}% +\defunargs {#3}\endgroup % +} + +% @deftypemethod CLASS RETURN-TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype{} of #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar == @defcv {Instance Variable} + +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} + +\def\defivarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index +\begingroup\defname {#2}{Instance Variable of #1}% +\defvarargs {#3}\endgroup % +} + +% These definitions are run if you use @defmethodx, etc., +% anywhere other than immediately after a @defmethod, etc. + +\def\defopx #1 {\errmessage{@defopx in invalid context}} +\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} +\def\defcvx #1 {\errmessage{@defcvx in invalid context}} +\def\defivarx #1 {\errmessage{@defivarx in invalid context}} + +% Now @defvar + +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{Variable}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{User Option}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} + +% This definition is run if you use @defvarx +% anywhere other than immediately after a @defvar or @defvarx. + +\def\defvrx #1 {\errmessage{@defvrx in invalid context}} +\def\defvarx #1 {\errmessage{@defvarx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% This definition is run if you use @deftpx, etc +% anywhere other than immediately after a @deftp, etc. + +\def\deftpx #1 {\errmessage{@deftpx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{#1}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup +} +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +\let\xeatspaces\eatspaces\scantokens{#1}\endgroup} +\fi + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% Utility routines. +% Thisdoes \let #1 = #2, except with \csnames. +\def\cslet#1#2{% +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=12\catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\macrobodyctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\{=12 + \catcode`\}=12 + \catcode`\@=12 + \catcode`\^^M=12 + \usembodybackslash} + +\def\macroargctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\@=12 + \catcode`\\=12} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \expandafter\ifx \csname macsave.\the\macname\endcsname \relax + \cslet{macsave.\the\macname}{\the\macname}% + \else + \message{Warning: redefining \the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\def\unmacro{\parsearg\unmacroxxx} +\def\unmacroxxx#1{% + \expandafter\ifx \csname macsave.\the\macname\endcsname \relax + \errmessage{Macro \the\macname\ not defined.}% + \else + \cslet{#1}{macsave.#1}% + \expandafter\let \csname macsave.\the\macname\endcsname \undefined + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname} + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname} + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \next} + + +\message{cross references,} +\newwrite\auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's job is to define \lastnode. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\relax + +% The sectioning commands (@chapter, etc.) call these. +\def\donoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Ysectionnumberandtype}% + \global\let\lastnode=\relax + \fi +} +\def\unnumbnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% + \global\let\lastnode=\relax + \fi +} +\def\appendixnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Yappendixletterandtype}% + \global\let\lastnode=\relax + \fi +} + + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\def\anchor#1{\setref{#1}{Ynothing}} + + +% \setref{NAME}{SNT} defines a cross-reference point NAME, namely +% NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have +% to set \indexdummies so commands such as @code in a section title +% aren't expanded. It would be nicer not to expand the titles in the +% first place, but there's so many layers that that is hard to do. +% +\def\setref#1#2{{% + \indexdummies + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2} +}} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\normalturnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % [mynode], + [\printednodename],\space + % page 3 + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi +\endgroup} + +% \dosetq is the interface for calls from other macros + +% Use \normalturnoffactive so that punctuation chars such as underscore +% and backslash work in node names. (\turnoffactive doesn't do \.) +\def\dosetq#1#2{% + {\let\folio=0 + \normalturnoffactive + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \iflinks + \next + \fi + }% +} + +% \internalsetq {foo}{page} expands into +% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ytitle{\thissection} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\def\Yappendixletterandtype{% +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. + +\def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +% +\def\xrdef#1{\begingroup + % Reenable \ as an escape while reading the second argument. + \catcode`\\ = 0 + \afterassignment\endgroup + \expandafter\gdef\csname X#1\endcsname +} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + \catcode`\@=\other + \catcode`\^=\other + % It was suggested to define this as 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % The aux file uses ' as the escape (for now). + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\%=\other + \catcode`\'=0 + \catcode`\\=\other + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\long\gdef\footnotezzz{\insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t + \else\let\next\f@t\fi \next} +\def\f@@t{\bgroup\aftergroup\@foot\let\next} +\def\f@t#1{#1\@foot} +\def\@foot{\strut\egroup} + +}%end \catcode `\@=11 + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + \closein 1 + % Do not bother showing banner with post-v2.7 epsf.tex (available in + % doc/epsf.tex until it shows up on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +% +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://ftp.tug.org/tex/epsf.tex.} +% +% Only complain once about lack of epsf.tex. +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is just the usual extra ignored arg for parsing this stuff. +\def\imagexxx#1,#2,#3,#4\finish{% + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + % If the image is by itself, center it. + \ifvmode + \nobreak\medskip + \nobreak + \centerline{\epsfbox{#1.eps}}% + \bigbreak + \else + \epsfbox{#1.eps}% + \fi +} + + +\message{paper sizes,} +% And other related parameters. + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. This makes it come to about 9pt for the 8.5x11 format. We +% call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = \hsize + \divide\emergencystretch by 45 + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; +% 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can +% set \parskip and call \setleading for \baselineskip. +% +\def\internalpagesizes#1#2#3#4#5#6{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + % If page is nothing but text, make it come out even. + \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% +}} + +% Use @smallbook to reset parameters for 7x9.5 (or so) format. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \setleading{12pt}% + % + \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \deftypemargin = 0pt + \defbodyindent = .5cm + % + \let\smalldisplay = \smalldisplayx + \let\smallexample = \smalllispx + \let\smallformat = \smallformatx + \let\smalllisp = \smalllispx +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \setleading{12pt}% + \parskip = 3pt plus 2pt minus 1pt + % + \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% + % + \tolerance = 700 + \hfuzz = 1pt +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex{{\globaldefs = 1 + \setleading{13.6pt}% + % + \afourpaper + \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% + % + \globaldefs = 0 +}} + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{% + \afourpaper + \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% + % + \globaldefs = 0 +} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% +}} + +% Set default to letter. +% +\letterpaper + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +%\catcode 27=\active +%\def^^[{$\diamondsuit$} + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +\global\chardef\rawbackslashxx=`\\ +%{\catcode`\\=\other +%@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% Say @foo, not \foo, in error messages. +\escapechar=`\@ + +% \catcode 17=0 % Define control-q +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active @catcode`@_=@active} + +% These look ok in all fonts, so just make them not special. The @rm below +% makes sure that the current font starts out as the newly loaded cmr10 +@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other + +@textfonts +@rm + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d" +@c time-stamp-end: "}" +@c End: diff --git a/avl-1.4.0/thread-test.c b/avl-1.4.0/thread-test.c new file mode 100644 index 0000000..20eead4 --- /dev/null +++ b/avl-1.4.0/thread-test.c @@ -0,0 +1,142 @@ +/* libavl - manipulates AVL trees. + Copyright (C) 1998, 1999 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 author may be contacted at on the + Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA + through more mundane means. */ + +/* This is file thread-test.c in libavl. */ + +#if HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include "avl.h" +#include "avlt.h" +#include "avltr.h" + +#if __GNUC__ >= 2 +#define unused __attribute__ ((unused)) +#else +#define unused +#endif + +/* Compare two integers A and B and return a strcmp()-type result. */ +int +compare_ints (const void *a, const void *b, void unused *param) +{ + return ((int) a) - ((int) b); +} + +/* Arrange the N elements of ARRAY in random order. */ +void +shuffle (int *array, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + int j = i + rand () % (n - i); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } +} + + +/* Simple stress test procedure for the AVL tree threading/unthreading + routines. */ +#define TREE_SIZE 1024 +#define N_ITERATIONS 16 +int +main (int argc, char **argv) +{ + int array[TREE_SIZE]; + int seed; + int iteration; + + if (argc == 2) + seed = atoi (argv[1]); + else + seed = time (0) * 257 % 32768; + + fputs ("Testing threading and unthreading...\n", stdout); + for (iteration = 1; iteration <= N_ITERATIONS; iteration++) + { + avl_tree *tree; + avl_traverser trav = AVL_TRAVERSER_INIT; + void **nodep = NULL; + void *node; + int i; + + printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); + fflush (stdout); + + srand (seed++); + + for (i = 0; i < TREE_SIZE; i++) + array[i] = i + 1; + shuffle (array, TREE_SIZE); + + tree = avl_create (compare_ints, NULL); + for (i = 0; i < TREE_SIZE; i++) + avl_force_insert (tree, (void *) (array[i])); + + shuffle (array, TREE_SIZE); + for (i = 0; i < TREE_SIZE; i++) + { + avlt_tree *t; + avltr_tree *tr; + + avl_delete (tree, (void *) (array[i])); + + while ((node = avl_traverse (tree, &trav)) != NULL); + + t = avlt_thread (tree); + while ((nodep = avlt_next (t, nodep)) != NULL); + while ((nodep = avlt_prev (t, nodep)) != NULL); + avlt_unthread (t); + + tr = avltr_thread (tree); + while ((nodep = avltr_next (tr, nodep)) != NULL); + avltr_unthread (tr); + + while ((node = avl_traverse (tree, &trav)) != NULL); + + if (i % 128 == 0) + { + putchar ('.'); + fflush (stdout); + } + } + fputs (" good.\n", stdout); + + avl_destroy (tree, NULL); + } + + return 0; +} + +/* + Local variables: + compile-command: "gcc -W -Wall -I. -o ./thread-test thread-test.c avl.c avlt.c avltr.c" + End: +*/ diff --git a/bit b/bit new file mode 100755 index 0000000..772994a --- /dev/null +++ b/bit @@ -0,0 +1,36 @@ +#!/bin/sh + +# +# $Id$ +# + +# +# Build all add-on packages for the current RTEMS_MAKEFILE_PATH architecture. +# +set -ex + +# rtemsNfs is version 1.2 +PACKAGES="rtemsNfs avl-1.4.0 ncurses-5.3 readline-4.3 libtecla-1.4.1 zlib-1.1.4" + +for p in $PACKAGES +do + cd $p + makefile="../RTEMS_Makefiles/Makefile.$p" + if [ \! -r "$makefile" ] + then + makefile="`echo $makefile | sed -e '/-.*/s///'`" + fi + if [ -r "$makefile" ] + then + make -w -f "$makefile" + else + make -w + make -w install + fi + cd .. +done + +for p in $PACKAGES +do + (cd $p ; make clean distclean || true) +done diff --git a/bit_bfd b/bit_bfd new file mode 100644 index 0000000..a6568f6 --- /dev/null +++ b/bit_bfd @@ -0,0 +1,18 @@ +#!/bin/sh + +# +# $Id$ +# + +# +# Where to find the binutils source +# +BINUTILS_SRC_DIR=~/src/RTEMS/bt/binutils-2.13.1 +set -ex + +rm -rf build +mkdir build +cd build +make -w BINUTILS_SRC_DIR="$BINUTILS_SRC_DIR" -f ../RTEMS_Makefiles/Makefile.bfd +cd .. +rm -rf build diff --git a/examples/avl/BuildTests.sh b/examples/avl/BuildTests.sh new file mode 100644 index 0000000..b0cc752 --- /dev/null +++ b/examples/avl/BuildTests.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -x + +SRCDIR=../../avl-1.4.0 + +for TEST in avl avlt avltr rb +do + rm -f $TEST.c + ln -s $SRCDIR/$TEST.c . + make TEST=$TEST SRCDIR=$SRCDIR + rm -f $TEST.c +done diff --git a/examples/avl/Makefile b/examples/avl/Makefile new file mode 100644 index 0000000..0cbf425 --- /dev/null +++ b/examples/avl/Makefile @@ -0,0 +1,70 @@ +# +# $Id$ +# +# Templates/Makefile.leaf +# Template leaf node Makefile +# + +# C source names, if any, go here -- minus the .c +C_PIECES= init $(TEST) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +# C++ source names, if any, go here -- minus the .cc +CC_PIECES= +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES= +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +PGMS=${ARCH}/$(TEST) + +# +# RTEMS managers go here +# +MANAGERS=io event message semaphore + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += -I$(SRCDIR) -DSELF_TEST=1 -Dmain=ncchk +CFLAGS += + +LD_PATHS += +LD_LIBS += +CFLAGS_LD += -Wl,--defsym -Wl,HeapSize=0x200000 # network needs more space +CFLAGS_DEBUG_V += -DSTACK_CHECKER_ON + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(PGMS) + +${ARCH}/$(TEST): ${OBJS} ${LINK_FILES} + $(make-exe) + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) +install: all + $(INSTALL_VARIANT) -m 555 ${PGMS} /usr/local/tftpboot/bootfiles/m68360/ diff --git a/examples/avl/README b/examples/avl/README new file mode 100644 index 0000000..72cab38 --- /dev/null +++ b/examples/avl/README @@ -0,0 +1,4 @@ +This directory contains a script and a makefile to build RTEMS +executable images of the avl test programs. To build all +the tests: + sh BuildTests.sh diff --git a/examples/avl/init.c b/examples/avl/init.c new file mode 100644 index 0000000..eb33c84 --- /dev/null +++ b/examples/avl/init.c @@ -0,0 +1,51 @@ +/* + * Root task + * + * $Revision$ $Date$ $Author$ + */ +#include +#include +#include + +/* + *********************************************************************** + * RTEMS CONFIGURATION * + *********************************************************************** + */ +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_SEMAPHORES 10 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 + +#define CONFIGURE_MICROSECONDS_PER_TICK 52489 + +#define CONFIGURE_INIT +#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ + RTEMS_NO_TIMESLICE | \ + RTEMS_NO_ASR | \ + RTEMS_INTERRUPT_LEVEL(0)) +#define CONFIGURE_INIT_TASK_STACK_SIZE (40*1024) +#define CONFIGURE_INIT_TASK_PRIORITY 100 +rtems_task Init (rtems_task_argument argument); + +#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE +rtems_driver_address_table Device_drivers[] = { + CONSOLE_DRIVER_TABLE_ENTRY, + CLOCK_DRIVER_TABLE_ENTRY, +}; + +#include + +extern int main (int argc, char **argv); + +/* + * RTEMS Startup Task + */ +rtems_task +Init (rtems_task_argument ignored) +{ + putenv ("TERM=xterm"); + main (0, NULL); + rtems_task_suspend (RTEMS_SELF); +} diff --git a/examples/ncurses/BuildTests.sh b/examples/ncurses/BuildTests.sh new file mode 100644 index 0000000..f8c2f68 --- /dev/null +++ b/examples/ncurses/BuildTests.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -x + +SRCDIR=../../ncurses-5.2/test + +for TEST in \ + blue \ + bs \ + cardfile \ + ditto \ + filter \ + firework \ + firstlast \ + gdc \ + hanoi \ + hashtest \ + keynames \ + knight \ + lrtest \ + ncurses \ + newdemo \ + rain \ + tclock \ + testaddch \ + testcurs \ + testscanw \ + view \ + worm \ + xmas +do + rm -f $TEST.c + ln -s $SRCDIR/$TEST.c . + make TEST=$TEST SRCDIR=$SRCDIR + rm -f $TEST.c +done diff --git a/examples/ncurses/Makefile b/examples/ncurses/Makefile new file mode 100644 index 0000000..ecdc006 --- /dev/null +++ b/examples/ncurses/Makefile @@ -0,0 +1,70 @@ +# +# $Id$ +# +# Templates/Makefile.leaf +# Template leaf node Makefile +# + +# C source names, if any, go here -- minus the .c +C_PIECES= init $(TEST) +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +# C++ source names, if any, go here -- minus the .cc +CC_PIECES= +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES= +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +PGMS=${ARCH}/$(TEST) + +# +# RTEMS managers go here +# +MANAGERS=io event message semaphore + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += -I$(SRCDIR) -Dmain=ncchk -DRETSIGTYPE=void +CFLAGS += + +LD_PATHS += +LD_LIBS += -lm -lpanel -lform -lmenu -lncurses +CFLAGS_LD += -Wl,--defsym -Wl,HeapSize=0x200000 # network needs more space +CFLAGS_DEBUG_V += -DSTACK_CHECKER_ON + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(PGMS) + +${ARCH}/$(TEST): ${OBJS} ${LINK_FILES} + $(make-exe) + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) +install: all + $(INSTALL_VARIANT) -m 555 ${PGMS} /usr/local/tftpboot/bootfiles/m68360/ diff --git a/examples/ncurses/README b/examples/ncurses/README new file mode 100644 index 0000000..beb3c32 --- /dev/null +++ b/examples/ncurses/README @@ -0,0 +1,4 @@ +This directory contains a script and a makefile to build RTEMS +executable images of the ncurses test programs. To build all +the tests: + sh BuildTests.sh diff --git a/examples/ncurses/init.c b/examples/ncurses/init.c new file mode 100644 index 0000000..8a81a1a --- /dev/null +++ b/examples/ncurses/init.c @@ -0,0 +1,52 @@ +/* + * Root task + * + * $Revision$ $Date$ $Author$ + */ +#include +#include +#include + +/* + *********************************************************************** + * RTEMS CONFIGURATION * + *********************************************************************** + */ +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_SEMAPHORES 10 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 + +#define CONFIGURE_MICROSECONDS_PER_TICK 52489 + +#define CONFIGURE_INIT +#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ + RTEMS_NO_TIMESLICE | \ + RTEMS_NO_ASR | \ + RTEMS_INTERRUPT_LEVEL(0)) +#define CONFIGURE_INIT_TASK_STACK_SIZE (40*1024) +#define CONFIGURE_INIT_TASK_PRIORITY 100 +rtems_task Init (rtems_task_argument argument); + +#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE +rtems_driver_address_table Device_drivers[] = { + CONSOLE_DRIVER_TABLE_ENTRY, + CLOCK_DRIVER_TABLE_ENTRY, +}; + +#include + +extern int main (int argc, char **argv); + +/* + * RTEMS Startup Task + */ +rtems_task +Init (rtems_task_argument ignored) +{ + putenv ("TERM=xterm"); + putenv ("NCURSES_TRACE=20"); + main (0, NULL); + rtems_task_suspend (RTEMS_SELF); +} diff --git a/examples/readline/.gdbinit b/examples/readline/.gdbinit new file mode 100644 index 0000000..f198616 --- /dev/null +++ b/examples/readline/.gdbinit @@ -0,0 +1 @@ +directory ../../readline diff --git a/examples/readline/Makefile b/examples/readline/Makefile new file mode 100644 index 0000000..0b67968 --- /dev/null +++ b/examples/readline/Makefile @@ -0,0 +1,70 @@ +# +# $Id$ +# +# Templates/Makefile.leaf +# Template leaf node Makefile +# + +# C source names, if any, go here -- minus the .c +C_PIECES= init rlgeneric +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +# C++ source names, if any, go here -- minus the .cc +CC_PIECES= +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES= +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +PGMS=${ARCH}/rlchk + +# +# RTEMS managers go here +# +MANAGERS=io event message semaphore + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += -Dmain=rlchk +CFLAGS += + +LD_PATHS += +LD_LIBS += -lreadline -lncurses +CFLAGS_LD += -Wl,--defsym -Wl,HeapSize=0x200000 # network needs more space +CFLAGS_DEBUG_V += -DSTACK_CHECKER_ON + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: ${ARCH} $(SRCS) $(PGMS) + +${ARCH}/rlchk: ${OBJS} ${LINK_FILES} + $(make-exe) + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) +install: all + $(INSTALL_VARIANT) -m 555 ${PGMS} /usr/local/tftpboot/bootfiles/m68360/ diff --git a/examples/readline/init.c b/examples/readline/init.c new file mode 100644 index 0000000..1336cfe --- /dev/null +++ b/examples/readline/init.c @@ -0,0 +1,51 @@ +/* + * Root task + * + * $Revision$ $Date$ $Author$ + */ +#include +#include +#include + +/* + *********************************************************************** + * RTEMS CONFIGURATION * + *********************************************************************** + */ +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_SEMAPHORES 10 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 + +#define CONFIGURE_MICROSECONDS_PER_TICK 52489 + +#define CONFIGURE_INIT +#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ + RTEMS_NO_TIMESLICE | \ + RTEMS_NO_ASR | \ + RTEMS_INTERRUPT_LEVEL(0)) +#define CONFIGURE_INIT_TASK_STACK_SIZE (10*1024) +#define CONFIGURE_INIT_TASK_PRIORITY 100 +rtems_task Init (rtems_task_argument argument); + +#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE +rtems_driver_address_table Device_drivers[] = { + CONSOLE_DRIVER_TABLE_ENTRY, + CLOCK_DRIVER_TABLE_ENTRY, +}; + +#include + +extern int main (int argc, char **argv); + +/* + * RTEMS Startup Task + */ +rtems_task +Init (rtems_task_argument ignored) +{ + putenv ("TERM=xterm"); + main (0, NULL); + rtems_task_suspend (RTEMS_SELF); +} diff --git a/examples/readline/rlgeneric.c b/examples/readline/rlgeneric.c new file mode 100644 index 0000000..2bb5da4 --- /dev/null +++ b/examples/readline/rlgeneric.c @@ -0,0 +1,30 @@ +/* + * Host version of readline test program. + * Works as RTEMS version when included in rlchk.c + */ +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + char *line; + + rl_bind_key ('\t', rl_insert); + stifle_history (10); + for (;;) { + line = readline ("Enter a line: "); + if (line && *line) + add_history (line); + printf ("Line: `%s'\n", line); + if (line && !strcmp (line, "dump")) { + rl_dump_variables (0,0); + rl_dump_functions (0,0); + } + free (line); + } + return 0; +} diff --git a/libtecla-1.4.1/CHANGES b/libtecla-1.4.1/CHANGES new file mode 100644 index 0000000..45073e0 --- /dev/null +++ b/libtecla-1.4.1/CHANGES @@ -0,0 +1,1492 @@ +In the following log, modification dates are listed using the European +convention in which the day comes before the month (ie. DD/MM/YYYY). +The most recent modifications are listed first. + +25/05/2002 mcs@astro.caltech.edu (based on suggestions by Paul Smith) + pathutil.c + Apparently, under QNX pathconf("/",_PC_PATH_MAX) returns + EINVAL. At Paul's suggestion I have modified the code to + silently substitute the existing MAX_PATHLEN_FALLBACK + value if pathconf() returns an error of any kind. + homedir.c + Under QNX, sysconf(_SC_GETPW_R_SIZE_MAX) also apparently + returns EINVAL, so as with pathconf() I modified the code + to substitute a fallback default, rather than + complaining and failing. + enhance.c + Paul told me that the inclusion of sys/termios.h was + causing compilation of enhance.c to fail under QNX. This + line is a bug. The correct thing to do is include + termios.h without a sub-directory prefix, as I was + already doing futher up in the file, so I have just + removed the errant include line. + +12/02/2002 mcs@astro.caltech.edu + getline.c configure.in configure + Mac OS X doesn't have a term.h or termcap.h, but it does + define prototypes for tputs() and setupterm(), so the + default prototypes that I was including if no headers + where available, upset it. I've removed these prototypes. + I also now conditionally include whichever is found of + curses.h and ncurses/curses.h for both termcap and + terminfo (before I wasn't including curses.h when + termcap was selected). + +12/02/2002 mcs@astro.caltech.edu + Updated version number to 1.4.1, ready for a micro + release. + +12/02/2002 mcs@astro.caltech.edu + html/index.html + Added Mac OS X and Cygwin to the list of systems that + can compile libtecla. + +12/02/2002 mcs@astro.caltech.edu + getline.c + Under Mac OS X, the tputs() callback function returns + void, instead of the int return value used by other + systems. This declaration is now used if both __MACH__ + and __APPLE__ are defined. Hopefully these are the + correct system macros to check. Thanks for Stephan + Fiedler for providing information on Mac OS X. + +11/02/2002 mcs@astro.caltech.edu + configure.in configure getline.c + Some systems don't have term.h, and others have it hidden + in an ncurses sub-directory of the standard system include + directory. If term.h can't be found, simply don't include + it. If it is in an ncurses sub-directory, include + ncurses/term.h instead of term.h. + +04/02/2002 mcs@astro.caltech.edu + configure.in configure Makefile.in Makefile.rules + Use ranlib on systems that need it (Mac OS X). Also, + make all components of the installation directories where + needed, instead of assuming that they exist. + +04/02/2002 mcs@astro.caltech.edu + getline.c + When the tab completion binding was unbound from the tab + key, hitting the tab key caused gl_get_line() to ring the + bell instead of inserting a tab character. This is + problematic when using the 'enhance' program with + Jython, since tabs are important in Python. I have + corrected this. + +10/12/2001 Version 1.4.0 released. + +10/12/2001 mcs@astro.caltech.edu + getline.c + If the TIOCGWINSZ ioctl doesn't work, as is the case when + running in an emacs shell, leave the size unchanged, rather + than returning a fatal error. + +07/12/2001 mcs@astro.caltech.edu + configure.in configure + Now that the configure version of CFLAGS is included in + the makefile, I noticed that the optimization flags -g + and -O2 had been added. It turns out that if CFLAGS isn't + already set, the autoconf AC_PROG_CC macro initializes it + with these two optimization flags. Since this would break + backwards compatibility in embedded distributions that + already use the OPT= makefile argument, and because + turning debugging on needlessly bloats the library, I now + make sure that CFLAGS is set before calling this macro. + +07/12/2001 mcs@astro.caltech.edu + enhance.c + Use argv[0] in error reports instead of using a + hardcoded macro. + +07/12/2001 mcs@astro.caltech.edu + getline.c + The cut buffer wasn't being cleared after being + used as a work buffer by gl_load_history(). + +06/12/2001 mcs@astro.caltech.edu + configure.in configure + I removed my now redundant definition of SUN_TPUTS from + CFLAGS. I also added "-I/usr/include" to CFLAGS under + Solaris to prevent gcc from seeing conflicting versions + of system header files in /usr/local/include. + +06/12/2001 Markus Gyger (logged here by mcs) + Lots of files. + Lots of corrections to misspellings and typos in the + comments. + getline.c + Markus reverted a supposed fix that I added a day or two + ago. I had incorrectly thought that in Solaris 8, Sun had + finally brought their declaration of the callback + function of tputs() into line with other systems, but it + turned out that gcc was pulling in a GNU version of + term.h from /usr/local/include, and this was what + confused me. + +05/12/2001 mcs@astro.caltech.edu + Makefile.in + I added @CFLAGS@ to the CFLAGS assignment, so that + if CFLAGS is set as an environment variable when + configure is run, the corresponding make variable + includes its values in the output makefile. + +05/12/2001 mcs@astro.caltech.edu + getline.c libtecla.h libtecla.map man3/gl_get_line.3 + man3/gl_last_signal.3 + I added a function that programs can use to find out + which signal caused gl_get_line() to return EINTR. + +05/12/2001 mcs@astro.caltech.edu + getline.c + When the newline action was triggered by a printable + character, it failed to display that character. It now + does. Also, extra control codes that I had added, to + clear to the end of the display after the carriage return, + but before displaying the prompt, were confusing expect + scripts, so I have removed them. This step is now done + instead in gl_redisplay() after displaying the full input + line. + +05/12/2001 mcs@astro.caltech.edu + getline.c man3/gl_get_line.3 + A user convinced me that continuing to invoke meta + keybindings for meta characters that are printable is a + bad idea, as is allowing users to ask to have setlocale() + called behind the application's back. I have thus changed + this. The setlocale configuration option has gone, and + gl_get_line() is now completely 8-bit clean, by default. + This means that if a meta character is printable, it is + treated as a literal character, rather than a potential + M-c binding. Meta bindings can still be invoked via + their Esc-c equivalents, and indeed most terminal + emulators either output such escape pairs by default when + the meta character is pressed, or can be configured to do + so. I have documented how to configure xterm to do this, + in the man page. + +03/12/2001 mcs@astro.caltech.edu + getline.c man3/gl_get_line.3 + gl_get_line() by default now prints any 8-bit printable + characters that don't match keybindings. Previously + characters > 127 were only printed if preceded by the + literal-next action. Alternatively, by placing the + command literal_if_printable in the tecla configuration + file, all printable characters are treated as literal + characters, even if they are bound to action functions. + + For international users of programs written by + programmers that weren't aware of the need to call + setlocale() to support alternate character sets, the + configuration file can now also contain the single-word + command "setlocale", which tells gl_get_line() to remedy + this. + +27/11/2001 mcs@astro.caltech.edu + demo.c demo2.c enhance man3/gl_get_line.3 + All demos and programs now call setlocale(LC_CTYPE,""). + This makes them support character sets of different + locales, where specified with the LC_CTYPE, LC_ALL, or + LANG environment variables. I also added this to the demo + in the man page, and documented its effect. + +27/11/2001 mcs@astro.caltech.edu + getline.c + When displaying unsigned characters with values over + 127 literally, previously it was assumed that they would + all be displayable. Now isprint() is consulted, and if it + says that a character isn't printable, the character code + is displayed in octal like \307. In non-C locales, some + characters with values > 127 are displayable, and + isprint() tells gl_get_line() which are and which aren't. + +27/11/2001 mcs@astro.caltech.edu + getline.c pathutil.c history.c enhance.c demo2.c + All arguments of the ctype.h character class functions + are now cast to (int)(unsigned char). Previously they + were cast to (int), which doesn't correctly conform to + the requirements of the C standard, and could cause + problems for characters with values > 127 on systems + with signed char's. + +26/11/2001 mcs@astro.caltech.edu + man3/enhance.3 man3/libtecla.3 + I started writing a man page for the enhance program. + +26/11/2001 mcs@astro.caltech.edu + Makefile.in Makefile.rules INSTALL + It is now possible to specify whether the demos and other + programs are to be built, by overriding the default + values of the DEMOS, PROGRAMS and PROGRAMS_R variables. + I have also documented the BINDIR variable and the + install_bin makefile target. + +22/11/2001 mcs@astro.caltech.edu + getline.c libtecla.h libtecla.map man3/gl_get_line.3 + man3/gl_ignore_signal.3 man3/gl_trap_signal.3 + Signal handling has now been modified to be customizable. + Signals that are trapped by default can be removed from + the list of trapped signals, and signals that aren't + currently trapped, can be added to the list. Applications + can also specify the signal and terminal environments in + which an application's signal handler is invoked, and + what gl_get_line() does after the signal handler returns. + +13/11/2001 mcs@astro.caltech.edu + getline.c man3/gl_get_line.3 + Added half-bright, reverse-video and blinking text to the + available prompt formatting options. + getline.c + Removed ^O from the default VT100 sgr0 capability + string. Apparently it can cause problems with some + terminal emulators, and we don't need it, since it turns + off the alternative character set mode, which we don't + use. + getline.c + gl_tigetstr() and gl_tgetstr() didn't guard against the + error returns of tigetstr() and tgetstr() respectively. + They now do. + +11/11/2001 mcs@astro.caltech.edu + getline.c libtecla.h libtecla.map man3/gl_get_line.3 + man3/gl_prompt_style.3 + Although the default remains to display the prompt string + literally, the new gl_prompt_style() function can be used + to enable text attribute formatting directives in prompt + strings, such as underlining, bold font, and highlighting + directives. + +09/11/2001 mcs@astro.caltech.edu + enhance.c Makefile.rules configure.in configure + I added a new program to the distribution that allows one + to run most third party programs with the tecla library + providing command-line editing. + +08/11/2001 mcs@astro.caltech.edu + libtecla.h getline.c man3/gl_get_line.3 history.c history.h + I added a max_lines argument to gl_show_history() and + _glh_show_history(). This can optionally be used to + set a limit on the number of history lines displayed. + libtecla.h getline.c man3/gl_get_line.3 + I added a new function called gl_replace_prompt(). This + can be used by gl_get_line() callback functions to + request that a new prompt be use when they return. + +06/11/2001 mcs@astro.caltech.edu + getline.c man3/gl_get_line.3 + I implemented, bound and documented the list-history + action, used for listing historical lines of the current + history group. + getline.c man3/gl_get_line.3 man3/gl_echo_mode.3 + I wrote functions to specify and query whether subsequent + lines will be visible as they are being typed. + +28/10/2001 mcs@astro.caltech.edu + getline.c man3/gl_get_line.3 + For those cases where a terminal provides its own + high-level terminal editing facilities, you can now + specify an edit-mode argument of 'none'. This disables + all tecla key bindings, and by using canonical terminal + input mode instead of raw input mode, editing is left up + to the terminal driver. + +21/10/2001 mcs@astro.caltech.edu + libtecla.h getline.c history.c history.h + man3/gl_get_line.3 man3/gl_history_info.3 + I added the new gl_state_of_history(), + gl_range_of_history() and gl_size_of_history() + functions for querying information about the + history list. + history.c + While testing the new gl_size_of_history() + function, I noticed that when the history buffer + wrapped, any location nodes of old lines between + the most recent line and the end of the buffer + weren't being removed. This could result in bogus + entries appearing at the start of the history list. + Now fixed. + +20/10/2001 mcs@astro.caltech.edu + + libtecla.h getline.c history.c history.h + man3/gl_get_line.3 man3/gl_lookup_history.3 + I added a function called gl_lookup_history(), that + the application can use to lookup lines in the history + list. + libtecla.h getline.c history.c history.h man3/gl_get_line.3 + gl_show_history() now takes a format string argument + to control how the line is displayed, and with what + information. It also now provides the option of either + displaying all history lines or just those of the + current history group. + getline.c man3/gl_get_line.3 + gl_get_line() only archives lines in the history buffer + if the newline action was invoked by a newline or + carriage return character. + +16/10/2001 mcs@astro.caltech.edu + + history.c history.h getline.c libtecla.h libtecla.map + man3/gl_get_line.3 man3/gl_resize_history.3 + man3/gl_limit_history.3 man3/gl_clear_history.3 + man3/gl_toggle_history.3 + I added a number of miscellaneous history configuration + functions. You can now resize or delete the history + buffer, limit the number of lines that are allowed in the + buffer, clear either all history or just the history of + the current history group, and temporarily enable and + disable the history mechanism. + +13/10/2001 mcs@astro.caltech.edu + + getline.c + tputs_fp is now only declared if using termcap or + terminfo. + getline.c libtecla.map man3/gl_get_line.3 + man3/gl_terminal_size.3 + I added a public gl_terminal_size() function for + updating and querying the current size of the terminal. + update_version configure.in libtecla.h + A user noted that on systems where the configure script + couldn't be used, it was inconvenient to have the version + number macros set by the configure script, so they are + now specified in libtecla.h. To reduce the likelihood + that the various files where the version number now + appears might get out of sync, I have written the + update_version script, which changes the version number + in all of these files to a given value. + +01/10/2001 mcs@astro.caltech.edu + + getline.c history.c history.h man3/gl_get_line.3 + I added a max_lines argument to gl_save_history(), to + allow people to optionally place a ceiling on the number + of history lines saved. Specifying this as -1 sets the + ceiling to infinity. + +01/10/2001 mcs@astro.caltech.edu + + configure.in configure + Under digital unix, getline wouldn't compile with + _POSIX_C_SOURCE set, due to type definitions needed by + select being excluded by this flag. Defining the + _OSF_SOURCE macro as well on this system, resolved this. + +30/09/2001 mcs@astro.caltech.edu + + getline.c libtecla.h history.c history.h man3/gl_get_line.3 + man3/gl_group_history.3 + I implemented history streams. History streams + effectively allow multiple history lists to be stored in + a single history buffer. Lines in the buffer are tagged + with the current stream identification number, and + lookups only consider lines that are marked with the + current stream identifier. + getline.c libtecla.h history.c history.h man3/gl_get_line.3 + man3/gl_show_history.3 + The new gl_show_history function displays the current + history to a given stdio output stream. + +29/09/2001 mcs@astro.caltech.edu + + getline.c + Previously new_GetLine() installed a persistent signal + handler to be sure to catch the SIGWINCH (terminal size + change) signal between calls to gl_get_line(). This had + the drawback that if multiple GetLine objects were + created, only the first GetLine object used after the + signal was received, would see the signal and adapt to + the new terminal size. Instead of this, a signal handler + for sigwinch is only installed while gl_get_line() is + running, and just after installing this handler, + gl_get_line() checks for terminal size changes that + might have occurred while the signal handler wasn't + installed. + getline.c + Dynamically allocated copies of capability strings looked + up in the terminfo or termcap databases are now made, so + that calls to setupterm() etc for one GetLine object + don't get trashed when another GetLine object calls + setupterm() etc. It is now safe to allocate and use + multiple GetLine objects, albeit only within a single + thread. + +28/09/2001 mcs@astro.caltech.edu + + version.c Makefile.rules + I added a function for querying the version number of + the library. + +26/09/2001 mcs@astro.caltech.edu + + getline.c man3/gl_get_line.3 + I added the new gl_watch_fd() function, which allows + applications to register callback functions to be invoked + when activity is seen on arbitrary file descriptors while + gl_get_line() is awaiting keyboard input from the user. + + keytab.c + If a request is received to delete a non-existent + binding, which happens to be an ambiguous prefix of other + bindings no complaint is now generated about it being + ambiguous. + +23/09/2001 mcs@astro.caltech.edu + + getline.c history.c history.h man3/gl_get_line.3 + libtecla.map demo.c + I added new public functions for saving and restoring the + contents of the history list. The demo program now uses + these functions to load and save history in ~/.demo_history. + +23/09/2001 mcs@astro.caltech.edu + + getline.c + On trying the demo for the first time on a KDE konsole + terminal, I discovered that the default M-O binding + to repeat history was hiding the arrow keys, which are + M-OA etc. I have removed this binding. The M-o (ie the + lower case version of this), is still bound. + +18/09/2001 mcs@astro.caltech.edu + + getline.c man3/gl_get_line.3 libtecla.map + Automatic reading of ~/.teclarc is now postponed until + the first call to gl_get_line(), to give the application + the chance to specify alternative configuration sources + with the new function gl_configure_getline(). The latter + function allows configuration to be done with a string, a + specified application-specific file, and/or a specified + user-specific file. I also added a read-init-files action + function, for re-reading the configuration files, if any. + This is by default bound to ^X^R. This is all documented + in gl_get_line.3. + +08/09/2001 mcs@astro.caltech.edu + + getline.c man3/gl_get_line.3 + It is now possible to bind actions to key-sequences + that start with printable characters. Previously + keysequences were required to start with meta or control + characters. This is documented in gl_get_line.3. + + getline.c man3/gl_get_line.3 + A customized completion function can now arrange for + gl_get_line() to return the current input line whenever a + successful completion has been made. This is signalled by + setting the last character of the optional continuation + suffix to a newline character. This is documented in + gl_get_line.3. + +05/07/2001 Bug reported by Mike MacFaden, fixed by mcs + + configure.in + There was a bug in the configure script that only + revealed itself on systems without termcap but not + terminfo (eg. NetBSD). I traced the bug back to a lack of + sufficient quoting of multi-line m4 macro arguments in + configure.in, and have now fixed this and recreated the + configure script. + +05/07/2001 Bug reported and patched by Mike MacFaden (patch modified + by mcs to match original intentions). + + getline.c + getline.c wouldn't compile when termcap was selected as + the terminal information database. setupterm() was being + passed a non-existent variable, in place of the term[] + argument of gl_control_strings(). Also if + gl_change_terminal() is called with term==NULL, "ansi" + is now substituted. + +02/07/2001 Version 1.3.3 released. + +27/06/2001 mcs@astro.caltech.edu + + getline.c expand.c cplmatch.c + Added checks to fprintf() statements that write to the + terminal. + getline.c + Move the cursor to the end of the line before suspending, + so that the cursor doesn't get left in the middle of the + input line. + Makefile.in + On systems that don't support shared libraries, the + distclean target of make deleted libtecla.h. This has + now been fixed. + getline.c + gl_change_terminal() was being called by gl_change_editor(), + with the unwanted side effect that raw terminal modes were + stored as those to be restored later, if called by an + action function. gl_change_terminal() was being called in + this case to re-establish terminal-specific key bindings, + so I have just split this part of the function out into + a separate function for both gl_change_editor() and + gl_change_terminal() to call. + +12/06/2001 mcs@astro.caltech.edu + + getline.c + Signal handling has been improved. Many more signals are + now trapped, and instead of using a simple flag set by a + signal handler, race conditions are avoided by blocking + signals during most of the gl_get_line() code, and + unblocking them via calls to sigsetjmp(), just before + attempting to read each new character from the user. + The matching use of siglongjmp() in the signal + handlers ensures that signals are reblocked correctly + before they are handled. In most cases, signals cause + gl_get_line() to restore the terminal modes and signal + handlers of the calling application, then resend the + signal to the application. In the case of SIGINT, SIGHUP, + SIGPIPE, and SIGQUIT, if the process still exists after + the signals are resent, gl_get_line() immediately returns + with appropriate values assigned to errno. If SIGTSTP, + SIGTTIN or SIGTTOU signals are received, the process is + suspended. If any other signal is received, and the + process continues to exist after the signal is resent to + the calling application, line input is resumed after the + terminal is put back into raw mode, the gl_get_line() + signal handling is restored, and the input line redrawn. + man/gl_get_line(3) + I added a SIGNAL HANDLING section to the gl_get_line() + man page, describing the new signal handling features. + +21/05/2001 Version 1.3.2 released. + +21/05/2001 mcs@astro.caltech.edu + + getline.c + When vi-replace-char was used to replace the character at + the end of the line, it left the cursor one character to + its right instead of on top of it. Now rememdied. + getline.c + When undoing, to properly emulate vi, the cursor is now + left at the leftmost of the saved and current cursor + positions. + getline.c man3/gl_get_line.3 + Implemented find-parenthesis (%), delete-to-paren (M-d%), + vi-change-to-paren (M-c%), copy-to-paren (M-y%). + cplfile.c pcache.c + In three places I was comparing the last argument of + strncmp() to zero instead of the return value of + strncmp(). + +20/05/2001 mcs@astro.caltech.edu + + getline.c man3/gl_get_line.3 + Implemented and documented the vi-repeat-change action, + bound to the period key. This repeats the last action + that modified the input line. + +19/05/2001 mcs@astro.caltech.edu + + man3/gl_get_line.3 + I documented the new action functions and bindings + provided by Tim Eliseo, plus the ring-bell action and + the new "nobeep" configuration option. + getline.c + I modified gl_change_editor() to remove and reinstate the + terminal settings as well as the default bindings, since + these have editor-specific differences. I also modified + it to not abort if a key-sequence can't be bound for some + reason. This allows the new vi-mode and emacs-mode + bindings to be used safely. + getline.c + When the line was re-displayed on receipt of a SIGWINCH + signal, the result wasn't visible until the next + character was typed, since a call to fflush() was needed. + gl_redisplay_line() now calls gl_flush_output() to remedy + this. + +17/05/2001 mcs@astro.catlech.edu + + getline.c + Under Linux, calling fflush(gl->output_fd) hangs if + terminal output has been suspended with ^S. With the + tecla library taking responsability for reading the stop + and start characters this was a problem, because once + hung in fflush(), the keyboard input loop wasn't entered, + so the user couldn't type the start character to resume + output. To remedy this, I now have the terminal process + these characters, rather than the library. + +12/05/2001 mcs@astro.caltech.edu + + getline.c + The literal-next action is now implemented as a single + function which reads the next character itself. + Previously it just set a flag which effected the + interpretation of the next character read by the input + loop. + getline.c + Added a ring-bell action function. This is currently + unbound to any key by default, but it is used internally, + and can be used by users that want to disable any of the + default key-bindings. + +12/05/2001 Tim Eliseo (logged here by mcs) + + getline.c + Don't reset gl->number until after calling an action + function. By looking at whether gl->number is <0 or + not, action functions can then tell whether the count + that they were passed was explicitly specified by the + user, as opposed to being defaulted to 1. + getline.c + In vi, the position at which input mode is entered + acts as a barrier to backward motion for the few + backward moving actions that are enabled in input mode. + Tim added this barrier to getline. + getline.c + In gl_get_line() after reading an input line, or + having the read aborted by a signal, the sig_atomic_t + gl_pending_signal was being compared to zero instead + of -1 to see if no signals had been received. + gl_get_line() will thus have been calling raise(-1), + which luckily didn't seem to do anything. Tim also + arranged for errno to be set to EINTR when a signal + aborts gl_get_line(). + getline.c + The test in gl_add_char_to_line() for detecting + when overwriting a character with a wider character, + had a < where it needed a >. Overwriting with a wider + character thus overwrote trailing characters. Tim also + removed a redundant copy of the character into the + line buffer. + getline.c + gl_cursor_left() and gl->cursor_right() were executing + a lot of redundant code, when the existing call to the + recently added gl_place_cursor() function, does all that + is necessary. + getline.c + Remove redundant code from backward_kill_line() by + re-implimenting in terms of gl_place_cursor() and + gl_delete_chars(). + getline.c + gl_forward_delete_char() now records characters in cut + buffer when in vi command mode. + getline.c + In vi mode gl_backward_delete_char() now only deletes + up to the point at which input mode was entered. Also + gl_delete_chars() restores from the undo buffer when + deleting in vi insert mode. + getline.c + Added action functions, vi-delete-goto-column, + vi-change-to-bol, vi-change-line, emacs-mode, vi-mode, + vi-forward-change-find, vi-backward-change-find, + vi-forward-change-to, vi-backward-change-to, + vi-change-goto-col, forward-delete-find, backward-delete-find, + forward-delete-to, backward-delete-to, + delete-refind, delete-invert-refind, forward-copy-find, + backward-copy-find, forward-copy-to, backward-copy-to + copy-goto-column, copy-rest-of-line, copy-to-bol, copy-line, + history-re-search-forward, history-re-search-backward. + +06/05/2001 Version 1.3.1 released. + +03/05/2001 mcs@astro.caltech.edu + + configure.in + Old versions of GNU ld don't accept version scripts. + Under Linux I thus added a test to try out ld with + the --version-script argument to see if it works. + If not, version scripts aren't used. + configure.in + My test for versions of Solaris earlier than 7 + failed when confronted by a three figure version + number (2.5.1). Fixed. + +30/04/2001 mcs@astro.caltech.edu + + getline.c + In vi mode, history-search-backward and + history-search-forward weren't doing anything when + invoked at the start of an empty line, whereas + they should have acted like up-history and down-history. + Makefile.in Makefile.rules + When shared libraries are being created, the build + procedure now arranges for any alternate library + links to be created as well, before linking the + demos. Without this the demos always linked to the + static libraries (which was perfectly ok, but wasn't a + good example). + Makefile.in Makefile.rules + On systems on which shared libraries were being created, + if there were no alternate list of names, make would + abort due to a Bourne shell 'for' statement that didn't + have any arguments. Currently there are no systems who's + shared library configurations would trigger this + problem. + Makefile.rules + The demos now relink to take account of changes to the + library. + configure.in configure + When determining whether the reentrant version of the + library should be compiled by default, the configure + script now attempts to compile a dummy program that + includes all of the appropriate system headers and + defines _POSIX_C_SOURCE. This should now be a robust test + on systems which use C macros to alias these function + names to other internal functions. + configure.in + Under Solaris 2.6 and earlier, the curses library is in + /usr/ccs/lib. Gcc wasn't finding this. In addition to + remedying this, I had to remove "-z text" from + LINK_SHARED under Solaris to get it to successfully + compile the shared library against the static curses + library. + configure.in + Under Linux the -soname directive was being used + incorrectly, citing the fully qualified name of the + library instead of its major version alias. This will + unfortunately mean that binaries linked with the 1.2.3 + and 1.2.4 versions of the shared library won't use + later versions of the library unless relinked. + +30/04/2001 mcs@astro.caltech.edu + + getline.c + In gl_get_input_line(), don't redundantly copy the + start_line if start_line == gl->line. + +30/04/2001 Version 1.3.0 released. + +28/04/2001 mcs@astro.caltech.edu + + configure.in + I removed the --no-undefined directive from the Linux + LINK_SHARED command. After recent patches to our RedHat + 7.0 systems ld started reporting some internal symbols of + libc as being undefined. Using nm on libc indicated that + the offending symbols are indeed defined, albeit as + "common" symbols, so there appears to be a bug in + RedHat's ld. Removing this flag allows the tecla shared + library to compile, and programs appear to function fine. + man3/gl_get_line.3 + The default key-sequence used to invoke the + read-from-file action was incorrectly cited as ^Xi + instead of ^X^F. + +26/04/2001 mcs@astro.caltech.edu + + getline.c man3/gl_get_line.3 + A new vi-style editing mode was added. This involved + adding many new action functions, adding support for + specifying editing modes in users' ~/.teclarc files, + writing a higher level cursor motion function to support + the different line-end bounds required in vi command + mode, and a few small changes to support the fact that vi + has two modes, input mode and command mode with different + bindings. + + When vi editing mode is enabled, any binding that starts + with an escape or a meta character, is interpreted as a + command-mode binding, and switches the library to vi + command mode if not already in that mode. Once in command + mode the first character of all keysequences entered + until input mode is re-enabled, are quietly coerced to + meta characters before being looked up in the key-binding + table. So, for example, in the key-binding table, the + standard vi command-mode 'w' key, which moves the cursor + one word to the right, is represented by M-w. This + emulates vi's dual sets of bindings in a natural way + without needing large changes to the library, or new + binding syntaxes. Since cursor keys normally emit + keysequences which start with escape, it also does + something sensible when a cursor key is pressed during + input mode (unlike true vi, which gets upset). + + I also added a ^Xg binding for the new list-glob action + to both the emacs and vi key-binding tables. This lists + the files that match the wild-card expression that + precedes it on the command line. + + The function that reads in ~/.teclarc used to tell + new_GetLine() to abort if it encountered anything that it + didn't understand in this file. It now just reports an + error and continues onto the next line. + Makefile.in: + When passing LIBS=$(LIBS) to recursive invokations of + make, quotes weren't included around the $(LIBS) part. + This would cause problems if LIBS ever contained more + than one word (with the supplied configure script this + doesn't happen currently). I added these quotes. + expand.c man3/ef_expand_file.3: + I wrote a new public function called ef_list_expansions(), + to list the matching filenames returned by + ef_expand_file(). + + I also fixed the example in the man page, which cited + exp->file instead of exp->files, and changed the + dangerous name 'exp' with 'expn'. + keytab.c: + Key-binding tables start with 100 elements, and are + supposedly incremented in size by 100 elements whenever + the a table runs out of space. The realloc arguments to + do this were wrong. This would have caused problems if + anybody added a lot of personal bindings in their + ~/.teclarc file. I only noticed it because the number of + key bindings needed by the new vi mode exceeded this + number. + libtecla.map + ef_expand_file() is now reported as having been added in + the upcoming 1.3.0 release. + +25/03/2001 Markus Gyger (logged here by mcs) + + Makefile.in: + Make symbolic links to alternative shared library names + relative instead of absolute. + Makefile.rules: + The HP-UX libtecla.map.opt file should be made in the + compilation directory, to allow the source code directory + to be on a readonly filesystem. + cplmatch.c demo2.c history.c pcache.c + To allow the library to be compiled with a C++ compiler, + without generating warnings, a few casts were added where + void* return values were being assigned directly to + none void* pointer variables. + +25/03/2001 mcs@astro.caltech.edu + + libtecla.map: + Added comment header to explain the purpose of the file. + Also added cpl_init_FileArgs to the list of exported + symbols. This symbol is deprecated, and no longer + documented, but for backwards compatibility, it should + still be exported. + configure: + I had forgotten to run autoconf before releasing version + 1.2.4, so I have just belatedly done so. This enables + Markus' changes to "configure.in" documented previously, + (see 17/03/2001). + +20/03/2001 John Levon (logged here by mcs) + + libtecla.h + A couple of the function prototypes in libtecla.h have + (FILE *) argument declarations, which means that stdio.h + needs to be included. The header file should be self + contained, so libtecla.h now includes stdio.h. + +18/03/2001 Version 1.2.4 released. + + README html/index.html configure.in + Incremented minor version from 3 to 4. + +18/03/2001 mcs@astro.caltech.edu + + getline.c + The fix for the end-of-line problem that I released a + couple of weeks ago, only worked for the first line, + because I was handling this case when the cursor position + was equal to the last column, rather than when the cursor + position modulo ncolumn was zero. + Makefile.in Makefile.rules + The demos are now made by default, their rules now being + int Makefile.rules instead of Makefile.in. + INSTALL + I documented how to compile the library in a different + directory than the distribution directory. + I also documented features designed to facilitate + configuring and building the library as part of another + package. + +17/03/2001 Markus Gyger (logged here by mcs) + + getline.c + Until now cursor motions were done one at a time. Markus + has added code to make use the of the terminfo capability + that moves the cursor by more than one position at a + time. This greatly improves performance when editing near + the start of long lines. + getline.c + To further improve performance, Markus switched from + writing one character at a time to the terminal, using + the write() system call, to using C buffered output + streams. The output buffer is only flushed when + necessary. + Makefile.rules Makefile.in configure.in + Added support for compiling for different architectures + in different directories. Simply create another directory + and run the configure script located in the original + directory. + Makefile.in configure.in libtecla.map + Under Solaris, Linux and HP-UX, symbols that are to be + exported by tecla shared libraries are explicitly specified + via symbol map files. Only publicly documented functions + are thus visible to applications. + configure.in + When linking shared libraries under Solaris SPARC, + registers that are reserved for applications are marked + as off limits to the library, using -xregs=no%appl when + compiling with Sun cc, or -mno-app-regs when compiling + with gcc. Also removed -z redlocsym for Solaris, which + caused problems under some releases of ld. + homedir.c (after minor changes by mcs) + Under ksh, ~+ expands to the current value of the ksh + PWD environment variable, which contains the path of + the current working directory, including any symbolic + links that were traversed to get there. The special + username "+" is now treated equally by tecla, except + that it substitutes the return value of getcwd() if PWD + either isn't set, or if it points at a different + directory than that reported by getcwd(). + +08/03/2001 Version 1.2.3 released. + +08/03/2001 mcs@astro.caltech.edu + + getline.c + On compiling the library under HP-UX for the first time + I encountered and fixed a couple of bugs: + + 1. On all systems except Solaris, the callback function + required by tputs() takes an int argument for the + character that is to be printed. Under Solaris it + takes a char argument. The callback function was + passing this argument, regardless of type, to write(), + which wrote the first byte of the argument. This was + fine under Solaris and under little-endian systems, + because the first byte contained the character to be + written, but on big-endian systems, it always wrote + the zero byte at the other end of the word. As a + result, no control characters were being written to + the terminal. + 2. While attempting to start a newline after the user hit + enter, the library was outputting the control sequence + for moving the cursor down, instead of the newline + character. On many systems the control sequence for + moving the cursor down happends to be a newline + character, but under HP-UX it isn't. The result was + that no new line was being started under HP-UX. + +04/03/2001 mcs@astro.caltech.edu + + configure.in Makefile.in Makefile.stub configure config.guess + config.sub Makefile.rules install-sh PORTING README INSTALL + Configuration and compilation of the library is now + performed with the help of an autoconf configure + script. In addition to relieving the user of the need to + edit the Makefile, this also allows automatic compilation + of the reentrant version of the library on platforms that + can handle it, along with the creation of shared + libraries where configured. On systems that aren't known + to the configure script, just the static tecla library is + compiled. This is currently the case on all systems + except Linux, Solaris and HP-UX. In the hope that + installers will provide specific conigurations for other + systems, the configure.in script is heavily commented, + and instructions on how to use are included in a new + PORTING file. + +24/02/2001 Version 1.2b released. + +22/02/2001 mcs@astro.caltech.edu + + getline.c + It turns out that most terminals, but not all, on writing + a character in the rightmost column, don't wrap the + cursor onto the next line until the next character is + output. This library wasn't aware of this and thus if one + tried to reposition the cursor from the last column, + gl_get_line() thought that it was moving relative to a + point on the next line, and thus moved the cursor up a + line. The fix was to write one extra character when in + the last column to force the cursor onto the next line, + then backup the cursor to the start of the new line. + getline.c + On terminal initialization, the dynamic LINES and COLUMNS + environment variables were ignored unless + terminfo/termcap didn't return sensible dimensions. In + practice, when present they should override the static + versions in the terminfo/termcap databases. This is the + new behavior. In reality this probably won't have caused + many problems, because a SIGWINCH signal which informs of + terminal size changes is sent when the terminal is + opened, so the dimensions established during + initialization quickly get updated on most systems. + +18/02/2001 Version 1.2a released. + +18/02/2001 mcs@astro.caltech.edu + + getline.c + Three months ago I moved the point at which termios.h + was included in getline.c. Unfortunately, I didn't notice + that this moved it to after the test for TIOCGWINSZ being + defined. This resulted in SIGWINCH signals not being + trapped for, and thus terminal size changes went + unnoticed. I have now moved the test to after the + inclusion of termios.h. + +12/02/2001 Markus Gyger (described here by mcs) + + man3/pca_lookup_file.3 man3/gl_get_line.3 + man3/ef_expand_file.3 man3/cpl_complete_word.3 + In the 1.2 release of the library, all functions in the + library were given man pages. Most of these simply + include one of the above 4 man pages, which describe the + functions while describing the modules that they are in. + Markus added all of these function names to the lists in + the "NAME" headers of the respective man pages. + Previously only the primary function of each module was + named there. + +11/02/2001 mcs@astro.caltech.edu + + getline.c + On entering a line that wrapped over two or more + terminal, if the user pressed enter when the cursor + wasn't on the last of the wrapped lines, the text of the + wrapped lines that followed it got mixed up with the next + line written by the application, or the next input + line. Somehow this slipped through the cracks and wasn't + noticed until now. Anyway, it is fixed now. + +09/02/2001 Version 1.2 released. + +04/02/2001 mcs@astro.caltech.edu + + pcache.c libtecla.h + With all filesystems local, demo2 was very fast to start + up, but on a Sun system with one of the target + directories being on a remote nfs mounted filesystem, the + startup time was many seconds. This was due to the + executable selection callback being applied to all files + in the path at startup. To avoid this, all files are now + included in the cache, and the application specified + file-selection callback is only called on files as they + are matched. Whether the callback rejected or accepted + them is then cached so that the next time an already + checked file is looked at, the callback doesn't have to + be called. As a result, startup is now fast on all + systems, and since usually there are only a few matching + file completions at a time, the delay during completion + is also usually small. The only exception is if the user + tries to complete an empty string, at which point all + files have to be checked. Having done this once, however, + doing it again is fast. + man3/pca_lookup_file.3 + I added a man page documenting the new PathCache module. + man3/.3 + I have added man pages for all of the functions in each + of the modules. These 1-line pages use the .so directive + to redirect nroff to the man page of the parent module. + man Makefile update_html + I renamed man to man3 to make it easier to test man page + rediction, and updated Makefile and update_html + accordingly. I also instructed update_html to ignore + 1-line man pages when making html equivalents of the man + pages. + cplmatch.c + In cpl_list_completions() the size_t return value of + strlen() was being used as the length argument of a "%*s" + printf directive. This ought to be an int, so the return + value of strlen() is now cast to int. This would have + caused problems on architectures where the size of a + size_t is not equal to the size of an int. + +02/02/2001 mcs@astro.caltech.edu + + getline.c + Under UNIX, certain terminal bindings are set using the + stty command. This, for example, specifies which control + key generates a user-interrupt (usually ^C or ^Y). What I + hadn't realized was that ASCII NUL is used as the way to + specify that one of these bindings is unset. I have now + modified the code to skip unset bindings, leaving the + corresponding action bound to the built-in default, or a + user provided binding. + +28/01/2001 mcs@astro.caltech.edu + + pcache.c libtecla.h + A new module was added which supports searching for files + in any colon separated list of directories, such as the + unix execution PATH environment variable. Files in these + directories, after being individually okayed for + inclusion via an application provided callback, are + cached in a PathCache object. You can then look up the + full pathname of a given filename, or you can use the + provided completion callback to list possible completions + in the path-list. The contents of relative directories, + such as ".", obviously can't be cached, so these + directories are read on the fly during lookups and + completions. The obvious application of this facility is + to provide Tab-completion of commands, and thus a + callback to place executable files in the cache, is + provided. + demo2.c + This new program demonstrates the new PathCache + module. It reads and processes lines of input until the + word 'exit' is entered, or C-d is pressed. The default + tab-completion callback is replaced with one which at the + start of a line, looks up completions of commands in the + user's execution path, and when invoked in other parts of + the line, reverts to normal filename completion. Whenever + a new line is entered, it extracts the first word on the + line, looks it up in the user's execution path to see if + it corresponds to a known command file, and if so, + displays the full pathname of the file, along with the + remaining arguments. + cplfile.c + I added an optional pair of callback function/data + members to the new cpl_file_completions() configuration + structure. Where provided, this callback is asked + on a file-by-file basis, which files should be included + in the list of file completions. For example, a callback + is provided for listing only completions of executable + files. + cplmatch.c + When listing completions, the length of the type suffix + of each completion wasn't being taken into account + correctly when computing the column widths. Thus the + listing appeared ragged sometimes. This is now fixed. + pathutil.c + I added a function for prepending a string to a path, + and another for testing whether a pathname referred to + an executable file. + +28/01/2001 mcs@astro.caltech.edu + + libtecla.h cplmatch.c man/cpl_complete_word.3 + The use of a publically defined structure to configure + the cpl_file_completions() callback was flawed, so a new + approach has been designed, and the old method, albeit + still supported, is no longer documented in the man + pages. The definition of the CplFileArgs structure in + libtecla.h is now accompanied by comments warning people + not to modify it, since modifications could break + applications linked to shared versions of the tecla + library. The new method involves an opaque CplFileConf + object, instances of which are returned by a provided + constructor function, configured with provided accessor + functions, and when no longer needed, deleted with a + provided destructor function. This is documented in the + cpl_complete_word man page. The cpl_file_completions() + callback distinguishes what type of configuration + structure it has been sent by virtue of a code placed at + the beginning of the CplFileConf argument by its + constructor. + +04/01/2001 mcs@astro.caltech.edu (Release of version 1.1j) + + getline.c + I added upper-case bindings for the default meta-letter + keysequences such as M-b. They thus continue to work + when the user has caps-lock on. + Makefile + I re-implemented the "install" target in terms of new + install_lib, install_inc and install_man targets. When + distributing the library with other packages, these new + targets allows for finer grained control of the + installation process. + +30/12/2000 mcs@astro.caltech.edu + + getline.c man/gl_get_line.3 + I realized that the recall-history action that I + implemented wasn't what Markus had asked me for. What he + actually wanted was for down-history to continue going + forwards through a previous history recall session if no + history recall session had been started while entering + the current line. I have thus removed the recall-history + action and modified the down-history action function + accordingly. + +24/12/2000 mcs@astro.caltech.edu + + getline.c + I modified gl_get_line() to allow the previously returned + line to be passed in the start_line argument. + getline.c man/gl_get_line.3 + I added a recall-history action function, bound to M^P. + This recalls the last recalled history line, regardless + of whether it was from the current or previous line. + +13/12/2000 mcs@astro.caltech.edu (Release of version 1.1i) + + getline.c history.h history.c man/gl_get_line.3 + I implemented the equivalent of the ksh Operate action. I + have named the tecla equivalent "repeat-history". This + causes the line that is to be edited to returned, and + arranges for the next most recent history line to be + preloaded on the next call to gl_get_line(). Repeated + invocations of this action thus result in successive + history lines being repeated - hence the + name. Implementing the ksh Operate action was suggested + by Markus Gyger. In ksh it is bound to ^O, but since ^O + is traditionally bound by the default terminal settings, + to stop-output, I have bound the tecla equivalent to M-o. + +01/12/2000 mcs@astro.caltech.edu (Release of version 1.1h) + + getline.c keytab.c keytab.h man/gl_get_line.3 + I added a digit-argument action, to allow repeat + counts for actions to be entered. As in both tcsh + and readline, this is bound by default to each of + M-0, M-1 through to M-9, the number being appended + to the current repeat count. Once one of these has been + pressed, the subsequent digits of the repeat count can be + typed with or without the meta key pressed. It is also + possible to bind digit-argument to other keys, with or + without a numeric final keystroke. See man page for + details. + + getline.c man/gl_get_line.3 + Markus noted that my choice of M-< for the default + binding of read-from-file, could be confusing, since + readline binds this to beginning-of-history. I have + thus rebound it to ^X^F (ie. like find-file in emacs). + + getline.c history.c history.h man/gl_get_line.3 + I have now implemented equivalents of the readline + beginning-of-history and end-of-history actions. + These are bound to M-< and M-> respectively. + + history.c history.h + I Moved the definition of the GlHistory type, and + its subordinate types from history.h to history.c. + There is no good reason for any other module to + have access to the innards of this structure. + +27/11/2000 mcs@astro.caltech.edu (Release of version 1.1g) + + getline.c man/gl_get_line.3 + I added a "read-from-file" action function and bound it + by default to M-<. This causes gl_get_line() to + temporarily return input from the file who's name + precedes the cursor. + +26/11/2000 mcs@astro.caltech.edu + + getline.c keytab.c keytab.h man/gl_get_line.3 + I have reworked some of the keybinding code again. + + Now, within key binding strings, in addition to the + previously existing notation, you can now use M-a to + denote meta-a, and C-a to denote control-a. For example, + a key binding which triggers when the user presses the + meta key, the control key and the letter [ + simultaneously, can now be denoted by M-C-[, or M-^[ or + \EC-[ or \E^[. + + I also updated the man page to use M- instead of \E in + the list of default bindings, since this looks cleaner. + + getline.c man/gl_get_line.3 + I added a copy-region-as-kill action function and + gave it a default binding to M-w. + +22/11/2000 mcs@astro.caltech.edu + + *.c + Markus Gyger sent me a copy of a previous version of + the library, with const qualifiers added in appropriate + places. I have done the same for the latest version. + Among other things, this gets rid of the warnings + that are generated if one tells the compiler to + const qualify literal strings. + + getline.c getline.h glconf.c + I have moved the contents of glconf.c and the declaration + of the GetLine structure into getline.c. This is cleaner, + since now only functions in getline.c can mess with the + innards of GetLine objects. It also clears up some problems + with system header inclusion order under Solaris, and also + the possibility that this might result in inconsistent + system macro definitions, which in turn could cause different + declarations of the structure to be seen in different files. + + hash.c + I wrote a wrapper function to go around strcmp(), such that + when hash.c is compiled with a C++ compiler, the pointer + to the wrapper function is a C++ function pointer. + This makes it compatible with comparison function pointer + recorded in the hash table. + + cplmatch.c getline.c libtecla.h + Markus noted that the Sun C++ compiler wasn't able to + match up the declaration of cpl_complete_word() in + libtecla.h, where it is surrounded by a extern "C" {} + wrapper, with the definition of this function in + cplmatch.c. My suspicion is that the compiler looks not + only at the function name, but also at the function + arguments to see if two functions match, and that the + match_fn() argument, being a fully blown function pointer + declaration, got interpetted as that of a C function in + one case, and a C++ function in the other, thus + preventing a match. + + To fix this I now define a CplMatchFn typedef in libtecla.h, + and use this to declare the match_fn callback. + +20/11/2000 (Changes suggested by Markus Gyger to support C++ compilers): + expand.c + Renamed a variable called "explicit" to "xplicit", to + avoid conflicts when compiling with C++ compilers. + *.c + Added explicit casts when converting from (void *) to + other pointer types. This isn't needed in C but it is + in C++. + getline.c + tputs() has a strange declaration under Solaris. I was + enabling this declaration when the SPARC feature-test + macro was set. Markus changed the test to hinge on the + __sun and __SVR4 macros. + direader.c glconf.c stringrp.c + I had omitted to include string.h in these two files. + + Markus also suggested some other changes, which are still + under discussion. With the just above changes however, the + library compiles without complaint using g++. + +19/11/2000 mcs@astro.caltech.edu + getline.h getline.c keytab.c keytab.h glconf.c + man/gl_get_line.3 + I added support for backslash escapes (include \e + for the keyboard escape key) and literal binary + characters to the characters allowed within key sequences + of key bindings. + + getline.h getline.c keytab.c keytab.h glconf.c + man/gl_get_line.3 + I introduced symbolic names for the arrow keys, and + modified the library to use the cursor key sequences + reported by terminfo/termcap in addition to the default + ANSI ones. Anything bound to the symbolically named arrow + keys also gets bound to the default and terminfo/termcap + cursor key sequences. Note that under Solaris + terminfo/termcap report the properties of hardware X + terminals when TERM is xterm instead of the terminal + emulator properties, and the cursor keys on these two + systems generate different key sequences. This is an + example of why extra default sequences are needed. + + getline.h getline.c keytab.c + For some reason I was using \e to represent the escape + character. This is supported by gcc, which thus doesn't + emit a warning except with the -pedantic flag, but isn't + part of standard C. I now use a macro to define escape + as \033 in getline.h, and this is now used wherever the + escape character is needed. + +17/11/2000 mcs@astro.caltech.edu (Release of version 1.1d) + + getline.c, man/gl_get_line(3), html/gl_get_line.html + In tcsh ^D is bound to a function which does different + things depending on where the cursor is within the input + line. I have implemented its equivalent in the tecla + library. When invoked at the end of the line this action + function displays possible completions. When invoked on + an empty line it causes gl_get_line() to return NULL, + thus signalling end of input. When invoked within a line + it invokes forward-delete-char, as before. The new action + function is called del-char-or-list-or-eof. + + getline.c, man/gl_get_line(3), html/gl_get_line.html + I found that the complete-word and expand-file actions + had underscores in their names instead of hyphens. This + made them different from all other action functions, so I + have changed the underscores to hyphens. + + homedir.c + On SCO UnixWare while getpwuid_r() is available, the + associated _SC_GETPW_R_SIZE_MAX macro used by sysconf() + to find out how big to make the buffer to pass to this + function to cater for any password entry, doesn't + exist. I also hadn't catered for the case where sysconf() + reports that this limit is indeterminate. I have thus + change the code to substitute a default limit of 1024 if + either the above macro isn't defined or if sysconf() says + that the associated limit is indeterminate. + +17/11/2000 mcs@astro.caltech.edu (Release of version 1.1c) + + getline.c, getline.h, history.c, history.h + I have modified the way that the history recall functions + operate, to make them better emulate the behavior of + tcsh. Previously the history search bindings always + searched for the prefix that preceded the cursor, then + left the cursor at the same point in the line, so that a + following search would search using the same prefix. This + isn't how tcsh operates. On finding a matching line, tcsh + puts the cursor at the end of the line, but arranges for + the followup search to continue with the same prefix, + unless the user does any cursor motion or character + insertion operations in between, in which case it changes + the search prefix to the new set of characters that are + before the cursor. There are other complications as well, + which I have attempted to emulate. As far as I can + tell, the tecla history recall facilities now fully + emulate those of tcsh. + +16/11/2000 mcs@astro.caltech.edu (Release of version 1.1b) + + demo.c: + One can now quit from the demo by typing exit. + + keytab.c: + The first entry of the table was getting deleted + by _kt_clear_bindings() regardless of the source + of the binding. This deleted the up-arrow binding. + Symptoms noted by gazelle@yin.interaccess.com. + + getline.h: + Depending on which system include files were include + before the inclusion of getline.h, SIGWINCH and + TIOCGWINSZ might or might not be defined. This resulted + in different definitions of the GetLine object in + different files, and thus some very strange bugs! I have + now added #includes for the necessary system header files + in getline.h itself. The symptom was that on creating a + ~/.teclarc file, the demo program complained of a NULL + argument to kt_set_keybinding() for the first line of the + file. + +15/11/2000 mcs@astro.caltech.edu (Release of version 1.1a) + + demo.c: + I had neglected to check the return value of + new_GetLine() in the demo program. Oops. + + getline.c libtecla.h: + I wrote gl_change_terminal(). This allows one to change to + a different terminal or I/O stream, by specifying the + stdio streams to use for input and output, along with the + type of terminal that they are connected to. + + getline.c libtecla.h: + Renamed GetLine::isterm to GetLine::is_term. Standard + C reserves names that start with "is" followed by + alphanumeric characters, so this avoids potential + clashes in the future. + + keytab.c keytab.h + Each key-sequence can now have different binding + functions from different sources, with the user provided + binding having the highest precedence, followed by the + default binding, followed by any terminal specific + binding. This allows gl_change_terminal() to redefine the + terminal-specific bindings each time that + gl_change_terminal() is called, without overwriting the + user specified or default bindings. In the future, it will + also allow for reconfiguration of user specified + bindings after the call to new_GetLine(). Ie. deleting a + user specified binding should reinstate any default or + terminal specific binding. + + man/cpl_complete_word.3 html/cpl_complete_word.html + man/ef_expand_file.3 html/ef_expand_file.html + man/gl_get_line.3 html/gl_get_line.html + I added sections on thread safety to the man pages of the + individual modules. + + man/gl_get_line.3 html/gl_get_line.html + I documented the new gl_change_terminal() function. + + man/gl_get_line.3 html/gl_get_line.html + In the description of the ~/.teclarc configuration file, + I had omitted the 'bind' command word in the example + entry. I have now remedied this. diff --git a/libtecla-1.4.1/INSTALL b/libtecla-1.4.1/INSTALL new file mode 100644 index 0000000..1a1b036 --- /dev/null +++ b/libtecla-1.4.1/INSTALL @@ -0,0 +1,168 @@ +To compile and optionally install the library, it is first necessary +to create a makefile for your system, by typing: + + ./configure + +The Makefile that this generates is designed to install the files of +the library in subdirectories of /usr/local/. If you would prefer to +install them under a different directory, you can type: + + ./configure --prefix /wherever + +Where you would replace /wherever with your chosen directory. Other +command-line options are available, and can be listed by typing: + + ./configure --help + +Having run the configure script, you are then ready to make the +library. To do this, just type: + + make + +What 'make' does depends on whether the configure script knows about +your system. If the configure script doesn't know anything specific +about your system, it will arrange for 'make' to produce the static +tecla library, called libtecla.a, and if possible, the reentrant +version of this called libtecla_r.a. If it does know about your +system, it will also create shared libraries if possible. If you are +on a system that isn't known, and you would like shared libraries to +be compiled, please read the file called PORTING to see how this can +be achieved. + +To install the library, its include file and it manual pages, type: + + make install + +Note that this will also compile the library if you haven't already +done so. + +Having compiled the library, if you wish, you can test it by running +the demo programs. After building the library, you should find two +programs, called demo and demo2, in the current directory. + +The first of the demos programs reads input lines from the user, and +writes what was typed back to the screen. While typing a line of +input, you can experiment with line editing, tab completion, history +recall etc.. For details about these line editing features, see the +man page gl_get_line(3). If you haven't installed this yet, you can +see it anyway by typing: + + nroff -man man3/gl_get_line.3 | more + +The second demo program, called demo2, demonstrates command-completion +with the UNIX PATH. If you type in a partial command name, and press +TAB, the command name will be completed if possible, and possible +completions will be listed if it is ambiguous. When you then enter the +line, the demo program then prints out the full pathname of the +command that you typed. If you type anything after the command name, +filename completion with the tab key reverts to its default behavior +of completing filenames in the current directory. + +COMPILING IN A DIFFERENT DIRECTORY +---------------------------------- +If you unpack the distribution in a directory which is visible from +multiple hosts which have different architectures, you have the option +of compiling the library for the different architectures in different +directories. You might for example create a sub-directory for each +architecture, under the top level directory of the distribution. You +would then log in to a host of one of these architectures, cd to the +sub-directory that you created for it, and type: + + ../configure + +The configure script then creates a makefile in the current directory +which is designed to build the library, object files, demos etc for +the architecture of the current host, in the current directory, using +the original source code in ../. You then repeat this procedure on +hosts of other architectures. + +The compilation directories don't have to be sub-directories of the +top level directory of the distribution. That was just described as an +example. They can be anywhere you like. + +Every rule in the makefiles that are generated by the configure +script, cites the paths of the target and source files explicitly, so +this procedure should work on any system, without the need for vpath +makefile support. + +EMBEDDING IN OTHER PACKAGE DISTRIBUTIONS +---------------------------------------- + +If you distribute the library with another package, which has its own +heirarchy and configuration procedures, the following installation +options may be of interest to you. At first glance, the use of a GNU +configure script by the tecla library, may appear to reduce your +options for controlling what gets made, and where it gets installed, +but this isn't the case, because many of the parameters configured by +the configure script are assigned to make variables which can be +overriden when you run make. + +For example, lets say that you have your own configuration script in +the parent directory of the libtecla top-level directory. In your +configuration script, you would first need to have the following line: + + (cd libtecla; ./configure) + +Now, from your makefile or whatever script you use to build your +application, you would need to make the library. Assuming that your +makefile or build script is in the parent directory of the libtecla +distribution, the following line tells make to just make the +non-reentrant, static version of the tecla library, and to install it +and the tecla include file in sub-directories called lib and include +in your current directory. + + (cd libtecla; make LIBDIR=../lib INCDIR=../include TARGETS=normal TARGET_LIBS="static" install_lib install_inc) + +First, the LIBDIR=../lib means that on installing the library, it +should be placed in the directory libtecla/../lib. Similarly INCDIR +tells make where to place the include files. The install_lib and +install_inc targets tell make to install the libraries and the include +file. Because the install_man and install_bin targets have been +omitted in this example, the man pages and programs aren't installed. +If you were to include these additional targets then you could use the +MANDIR and BINDIR variables, respectively to control where they were +installed. + +The TARGETS variable is used to specify which of the normal and +reentrant versions of the library are compiled. This can contain one +or both of the words "normal" and "reentrant". If you don't specify +this when you invoke make, the default value generated by the +configure script will be used. Depending on whether reentrant POSIX +functions are available for compilation of the reentrant version, this +will be either "normal" or "normal reentrant". + +The TARGET_LIBS variable is used to specify which of the static and +shared libraries are to be built. This can contain one or both of the +words "static" and "shared". If you don't specify this when you invoke +make, the default value generated by the configure script will be +used. Depending on whether the configure script knows how to create +shared libraries on the target system, this will be either "static" or +"static shared". Beware that shared libraries aren't supported on many +systems, so requiring "shared" will limit which systems you can +compile your package on. Also note that unless your package installs +the tecla library in a directory which all users of your program will +have access to, you should only compile the static version. +Instructions for adding shared-library creation rules for new systems +are included in the PORTING file. + +The OPT variable can be used to change the default optimization from +the default of "-O" to something else. + +The DEMOS variable controls whether the demo programs are built. +Normally this has the value "demos", which tells the makefile to build +the demo programs. Setting it to an empty string stops the demos from +being built. + +The PROGRAMS variable is used to specify which programs are to be +built and subsequently installed. All available programs are built by +default. Currently there is only one such program, selected by +specifying the word "enhance". This program uses tecla-enhanced +pseudo-terminals to layer command line editing on top of third party +programs. + +The PROGRAMS_R variable serves the same purpose as the PROGRAMS +variable, except that programs listed here are linked with the +reentrant version of the library, and should be specified with a _r +suffix. Currently this variable is empty by default. + +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.4.1/LICENSE.TERMS b/libtecla-1.4.1/LICENSE.TERMS new file mode 100644 index 0000000..275eef5 --- /dev/null +++ b/libtecla-1.4.1/LICENSE.TERMS @@ -0,0 +1,28 @@ +Copyright (c) 2000, 2001 by Martin C. Shepherd. + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. diff --git a/libtecla-1.4.1/Makefile b/libtecla-1.4.1/Makefile new file mode 100644 index 0000000..15116b5 --- /dev/null +++ b/libtecla-1.4.1/Makefile @@ -0,0 +1,3 @@ +default: + ./configure + make diff --git a/libtecla-1.4.1/Makefile.in b/libtecla-1.4.1/Makefile.in new file mode 100644 index 0000000..f691375 --- /dev/null +++ b/libtecla-1.4.1/Makefile.in @@ -0,0 +1,225 @@ +#----------------------------------------------------------------------- +# This is the template that the libtecla configure script uses to create +# the libtecla Makefile. It does this by replacing all instances of +# @name@ with the value of the correspondingly named configuration +# variable. You should find another file in the same directory as this +# one, called "configure.in". The latter file contains extensive comments +# explaining how this all works. +#----------------------------------------------------------------------- + +# Where is the source code? + +srcdir = @srcdir@ + +# Where do you want to install the library, its header file, and the man pages? + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +LIBDIR=@libdir@ +INCDIR=@includedir@ +MANDIR=@mandir@ +BINDIR=@bindir@ + +# Which C compiler do you want to use? + +CC = @CC@ + +# If 'make' doesn't define the MAKE variable, define it here. + +@SET_MAKE@ + +# To use RANLIB set the RANLIB variable to ranlib. Otherwise set it to +# :, which is the bourne shell do-nothing command. + +RANLIB = @RANLIB@ + +# The following optional defines change the characteristics of the library. +# +# USE_TERMINFO +# Use the terminfo terminal information database when looking up +# terminal characteristics. Most modern UNIX and UNIX-like operating +# systems support terminfo, so this define should normally be included. +# If in doubt leave it in, and see if the library compiles. +# USE_TERMCAP +# If you don't have terminfo but do have the termcap database, replace +# the -DUSE_TERMINFO with -DUSE_TERMCAP. If there is a termcap.h in +# /usr/include/, also add -DHAVE_TERMCAP_H. +# +# If neither USE_TERMINFO nor USE_TERMCAP are included, ANSI VT100 control +# sequences will be used to control all terminal types. +# +# For Solaris and Linux, use: +# +# DEFINES = -DUSE_TERMINFO +# + +DEFINES = @DEFS@ + +# +# The following defines are used in addition to the above when compiling +# the reentrant version of the library. Note that the definition of +# _POSIX_C_SOURCE to request reentrant functions, has the unfortunate +# side-effect on some systems of stopping the TIOCGWINSZ ioctl macro from +# getting defined. This in turn stops the library from being +# able to respond to terminal size changes. Under Solaris this can be +# remedied by adding -D__EXTENSIONS__. On linux this isn't necessary. +# If you don't get this right, the library will still work, but +# it will get confused if the terminal size gets changed and you try to +# edit a line that exceeds the terminal width. +# +# Thus on Solaris you should use: +# +# DEFINES_R = -D_POSIX_C_SOURCE=199506L -D__EXTENSIONS__ +# +# and on linux you should use: +# +# DEFINES_R = -D_POSIX_C_SOURCE=199506L +# + +DEFINES_R = -D_POSIX_C_SOURCE=199506L + +# +# The compiler optimization flags. I like to keep this separate so +# that I can set it to -g from the 'make' command line without having +# to edit this file when debugging the library. If you aren't working +# on modifying the library, leave this set to -O. +# + +OPT = -O + +# +# These are paranoid gcc warning flags to use when compiling new code. +# Simply invoke make with WARNING_FLAGS='$(PEDANTIC_FLAGS)'. +# +PEDANTIC_FLAGS=-Wall -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls + +# +# Specify any extra compiler warning options that you want to use. +# Leave this blank unless you are porting the library to a new system, +# or modifying the library. +# + +WARNING_FLAGS= + +# +# If you want to compile the demo program, specify any system +# libraries that are needed for the terminal I/O functions. +# +# If you are using terminfo, you will probably only need -lcurses. +# For termcap you may need -ltermcap or -ltermlib. +# +# For Solaris, use: +# +# LIBS = -lcurses +# +# For linux, use: +# +# LIBS = -lncurses +# + +LIBS = @LIBS@ + +# +# List the default target libraries. This should be one or +# both of the words "normal" and "reentrant". +# +TARGETS = @TARGETS@ + +# +# List which types of the above libraries are required. +# This should be one or both of the words "static" and "shared". +# +TARGET_LIBS = @TARGET_LIBS@ + +# +# If you want the demo programs to be built, the following variable +# should be assigned the single word: demos. If it isn't assigned +# anything, the demo programs won't be built. +# +DEMOS = demos + +# +# List the programs that are to be made by default. +# +PROGRAMS = enhance + +# +# List programs for which reentrant versions are to be built by default. +# +PROGRAMS_R = + +#----------------------------------------------------------------------- +# You shouldn't need to change anything below this line. +#----------------------------------------------------------------------- + +CFLAGS = $(OPT) $(WARNING_FLAGS) $(DEFINES) @CFLAGS@ @SHARED_CFLAGS@ + +default: $(TARGETS) + +normal: + @$(MAKE) -f $(srcdir)/Makefile.rules TARGETS="$(TARGET_LIBS)" SUFFIX="" CFLAGS="$(CFLAGS)" CC="$(CC)" OBJDIR=normal_obj LINK_SHARED='@LINK_SHARED@' SHARED_EXT='@SHARED_EXT@' SHARED_ALT='@SHARED_ALT@' LIBS='$(LIBS)' srcdir='$(srcdir)' LIBDIR='$(LIBDIR)' LN_S='@LN_S@' DEMOS="$(DEMOS)" PROGRAMS='$(PROGRAMS)' RANLIB='$(RANLIB)' + +reentrant: + @$(MAKE) -f $(srcdir)/Makefile.rules TARGETS="$(TARGET_LIBS)" SUFFIX="_r" CFLAGS="$(CFLAGS) $(DEFINES_R)" CC="$(CC)" OBJDIR=reentrant_obj LINK_SHARED='@LINK_SHARED@' SHARED_EXT='@SHARED_EXT@' SHARED_ALT='@SHARED_ALT@' LIBS='$(LIBS)' srcdir='$(srcdir)' LIBDIR='$(LIBDIR)' LN_S='@LN_S@' DEMOS="$(DEMOS)" PROGRAMS='$(PROGRAMS_R)' RANLIB='$(RANLIB)' + +demos: normal + +demos_r: reentrant + +clean: + rm -rf *.o normal_obj reentrant_obj libtecla*.a demo demo2 demo_r demo2_r enhance *~ man3/*~ html/*~ compile_reentrant compile_normal + @endings="@SHARED_EXT@ @SHARED_ALT@" ; \ + for alt in $$endings ; do \ + lib="libtecla*$$alt" ; \ + rm -f $$lib; echo rm -f $$lib ; \ + done + +distclean: clean + rm -f config.cache config.status config.log Makefile libtecla.map.opt + cp $(srcdir)/Makefile.stub Makefile + +install_lib: $(TARGETS) $(LIBDIR) + @for lib in libtecla.a libtecla_r.a ; do \ + if [ -f $$lib ] ; then \ + cp $$lib $(LIBDIR)/ ; chmod ugo+r $(LIBDIR)/$$lib; \ + echo "cp $$lib $(LIBDIR)/ ; chmod ugo+r $(LIBDIR)/$$lib"; \ + fi ; \ + done + @for lib in libtecla libtecla_r ; do \ + src="$$lib@SHARED_EXT@"; \ + if [ -f $$src ] ; then \ + dst="$(LIBDIR)/$$src"; \ + cp -f $$src $$dst; chmod a=rX $$dst; \ + echo "cp -f $$src $$dst ; chmod a=rX $$dst"; \ + endings="@SHARED_ALT@" ; \ + for alt in $$endings ; do \ + lnk="$$lib$$alt"; \ + (cd $(LIBDIR); rm -f $$lnk; @LN_S@ $$src $$lnk); \ + echo "(cd $(LIBDIR); rm -f $$lnk; @LN_S@ $$src $$lnk)"; \ + done ; \ + fi ; \ + done + +install_inc: $(INCDIR) + @if [ -f $(srcdir)/libtecla.h ]; then \ + cp $(srcdir)/libtecla.h $(INCDIR)/ ; chmod ugo+r $(INCDIR)/libtecla.h; \ + echo "cp $(srcdir)/libtecla.h $(INCDIR)/ ; chmod ugo+r $(INCDIR)/libtecla.h"; \ + fi + +install_man: $(MANDIR) $(MANDIR)/man3 + cd $(srcdir)/man3 && for page in *.3; do cp $$page $(MANDIR)/man3; chmod ugo+r $(MANDIR)/man3/$$page; done + +install_bin: $(BINDIR) $(PROGRAMS) $(PROGRAMS_R) + progs="$(PROGRAMS) $(PROGRAMS_R)"; \ + for prog in $$progs; do \ + cp $$prog $(BINDIR)/; \ + chmod ugo+rx $(BINDIR)/$$prog; \ + done + +install: install_lib install_inc install_man install_bin + +# Make any missing installation directories. + +$(MANDIR) $(MANDIR)/man3 $(LIBDIR) $(INCDIR) $(BINDIR): + $(srcdir)/install-sh -d $@ + chmod ugo+rx $@ diff --git a/libtecla-1.4.1/Makefile.rules b/libtecla-1.4.1/Makefile.rules new file mode 100644 index 0000000..6552057 --- /dev/null +++ b/libtecla-1.4.1/Makefile.rules @@ -0,0 +1,142 @@ +default: $(OBJDIR) $(TARGETS) $(DEMOS) $(PROGRAMS) + +#----------------------------------------------------------------------- +# You shouldn't need to change anything in this file. +#----------------------------------------------------------------------- + +# Create the directory in which the object files will be created. + +$(OBJDIR): + mkdir $(OBJDIR) + +# Construct the compilation command. + +COMPILE = $(CC) -c $(CFLAGS) -o $@ + +LIB_OBJECTS = $(OBJDIR)/getline.o $(OBJDIR)/keytab.o $(OBJDIR)/freelist.o \ + $(OBJDIR)/strngmem.o $(OBJDIR)/hash.o $(OBJDIR)/history.o \ + $(OBJDIR)/direader.o $(OBJDIR)/homedir.o $(OBJDIR)/pathutil.o \ + $(OBJDIR)/expand.o $(OBJDIR)/stringrp.o $(OBJDIR)/cplfile.o \ + $(OBJDIR)/cplmatch.o $(OBJDIR)/pcache.o $(OBJDIR)/version.o + +# List all of the programs that this makefile can build. + +PROGS = demo$(SUFFIX) demo2$(SUFFIX) enhance$(SUFFIX) + +static: libtecla$(SUFFIX).a + +libtecla$(SUFFIX).a: $(LIB_OBJECTS) + ar -ru $@ $(LIB_OBJECTS); \ + $(RANLIB) $@; \ + rm -f $(PROGS) + +shared: libtecla$(SUFFIX)$(SHARED_EXT) + +libtecla$(SUFFIX)$(SHARED_EXT): $(LIB_OBJECTS) $(srcdir)/libtecla.map \ + libtecla.map.opt + $(LINK_SHARED) + @endings="$(SHARED_ALT)" ; \ + for alt in $$endings ; do \ + lnk="libtecla$(SUFFIX)$$alt"; \ + echo "rm -f $$lnk; $(LN_S) $@ $$lnk"; \ + rm -f $$lnk; $(LN_S) $@ $$lnk; \ + done; \ + rm -f $(PROGS) + +libtecla.map.opt: $(srcdir)/libtecla.map + sed -n 's/^[ ]*\([_a-zA-Z0-9]*\)[ ]*;.*/+e \1/p' $? >$@ + +demos: demo$(SUFFIX) demo2$(SUFFIX) + +demo$(SUFFIX): $(OBJDIR)/demo.o + LD_RUN_PATH="$(LIBDIR):$$LD_RUN_PATH:`pwd`" $(CC) $(CFLAGS) -o $@ \ + $(OBJDIR)/demo.o -L. -ltecla$(SUFFIX) $(LIBS) + +demo2$(SUFFIX): $(OBJDIR)/demo2.o + LD_RUN_PATH="$(LIBDIR):$$LD_RUN_PATH:`pwd`" $(CC) $(CFLAGS) -o $@ \ + $(OBJDIR)/demo2.o -L. -ltecla$(SUFFIX) $(LIBS) + +enhance$(SUFFIX): $(OBJDIR)/enhance.o + LD_RUN_PATH="$(LIBDIR):$$LD_RUN_PATH:`pwd`" $(CC) $(CFLAGS) -o $@ \ + $(OBJDIR)/enhance.o -L. -ltecla$(SUFFIX) $(LIBS) + +#----------------------------------------------------------------------- +# Object file dependencies. +#----------------------------------------------------------------------- + +$(OBJDIR)/getline.o: $(srcdir)/getline.c $(srcdir)/pathutil.h \ + $(srcdir)/libtecla.h $(OBJDIR)/keytab.h $(srcdir)/history.h \ + $(srcdir)/freelist.h $(srcdir)/stringrp.h $(srcdir)/getline.h + $(COMPILE) $(srcdir)/getline.c + +$(OBJDIR)/keytab.o: $(srcdir)/keytab.c $(OBJDIR)/keytab.h \ + $(srcdir)/strngmem.h $(srcdir)/getline.h + $(COMPILE) $(srcdir)/keytab.c + +$(OBJDIR)/strngmem.o: $(srcdir)/strngmem.c $(srcdir)/strngmem.h \ + $(srcdir)/freelist.h + $(COMPILE) $(srcdir)/strngmem.c + +$(OBJDIR)/freelist.o: $(srcdir)/freelist.c $(srcdir)/freelist.h + $(COMPILE) $(srcdir)/freelist.c + +$(OBJDIR)/hash.o: $(srcdir)/hash.c $(srcdir)/hash.h $(srcdir)/strngmem.h \ + $(srcdir)/freelist.h + $(COMPILE) $(srcdir)/hash.c + +$(OBJDIR)/history.o: $(srcdir)/history.c $(srcdir)/history.h \ + $(srcdir)/freelist.h + $(COMPILE) $(srcdir)/history.c + +$(OBJDIR)/expand.o: $(srcdir)/expand.c $(srcdir)/freelist.h \ + $(srcdir)/direader.h $(srcdir)/pathutil.h $(srcdir)/homedir.h \ + $(srcdir)/stringrp.h $(srcdir)/libtecla.h + $(COMPILE) $(srcdir)/expand.c + +$(OBJDIR)/direader.o: $(srcdir)/direader.c $(srcdir)/direader.h + $(COMPILE) $(srcdir)/direader.c + +$(OBJDIR)/homedir.o: $(srcdir)/homedir.c $(srcdir)/pathutil.h \ + $(srcdir)/homedir.h + $(COMPILE) $(srcdir)/homedir.c + +$(OBJDIR)/pathutil.o: $(srcdir)/pathutil.c $(srcdir)/pathutil.h + $(COMPILE) $(srcdir)/pathutil.c + +$(OBJDIR)/stringrp.o: $(srcdir)/stringrp.c $(srcdir)/freelist.h \ + $(srcdir)/stringrp.h + $(COMPILE) $(srcdir)/stringrp.c + +$(OBJDIR)/cplfile.o: $(srcdir)/cplfile.c $(srcdir)/libtecla.h \ + $(srcdir)/direader.h $(srcdir)/homedir.h $(srcdir)/pathutil.h \ + $(srcdir)/cplfile.h + $(COMPILE) $(srcdir)/cplfile.c + +$(OBJDIR)/cplmatch.o: $(srcdir)/cplmatch.c $(srcdir)/libtecla.h \ + $(srcdir)/stringrp.h $(srcdir)/pathutil.h $(srcdir)/cplfile.h + $(COMPILE) $(srcdir)/cplmatch.c + +$(OBJDIR)/pcache.o: $(srcdir)/pcache.c $(srcdir)/libtecla.h \ + $(srcdir)/pathutil.h $(srcdir)/homedir.h $(srcdir)/freelist.h \ + $(srcdir)/direader.h $(srcdir)/stringrp.h + $(COMPILE) $(srcdir)/pcache.c + +$(OBJDIR)/demo.o: $(srcdir)/demo.c $(srcdir)/libtecla.h + $(COMPILE) $(srcdir)/demo.c + +$(OBJDIR)/demo2.o: $(srcdir)/demo2.c $(srcdir)/libtecla.h + $(COMPILE) $(srcdir)/demo2.c + +$(OBJDIR)/version.o: $(srcdir)/version.c $(srcdir)/libtecla.h + $(COMPILE) $(srcdir)/version.c + +$(OBJDIR)/enhance.o: $(srcdir)/enhance.c $(srcdir)/libtecla.h + $(COMPILE) $(srcdir)/enhance.c + +#----------------------------------------------------------------------- +# Include file dependencies. +#----------------------------------------------------------------------- + +$(OBJDIR)/keytab.h: $(srcdir)/keytab.h $(srcdir)/libtecla.h \ + $(srcdir)/hash.h $(srcdir)/strngmem.h + cp $(srcdir)/keytab.h $@ diff --git a/libtecla-1.4.1/Makefile.stub b/libtecla-1.4.1/Makefile.stub new file mode 100644 index 0000000..15116b5 --- /dev/null +++ b/libtecla-1.4.1/Makefile.stub @@ -0,0 +1,3 @@ +default: + ./configure + make diff --git a/libtecla-1.4.1/PORTING b/libtecla-1.4.1/PORTING new file mode 100644 index 0000000..db39818 --- /dev/null +++ b/libtecla-1.4.1/PORTING @@ -0,0 +1,38 @@ +The Tecla library was written with portability in mind, so no +modifications to the source code should be needed on UNIX or LINUX +platforms. The default compilation and linking arrangements should +also work unchanged on these systems, but if no specific configuration +has been provided for your system, shared libraries won't be compiled. +Configuring these requires modifications to be made to the file: + + configure.in + +This file is heavily commented (comments start with the word dnl) and +is relatively simple, so the instructions and suggestions that you +find in this file should be sufficient to help you figure out how to +add a configuration for your system. This file is an input file to the +GNU autoconf program, which uses it as a template for generating the +distributed configure script. If autoconf is installed on your system, +creating a new configure script is a simple matter of typing. + + autoconf + +To avoid confusion with the leftovers of the previous configuration, +you should then do the following: + + rm -f config.cache + ./configure + make clean + ./configure + make + +The first ./configure creates a new makefile for your system, allowing +you to type 'make clean' to discard any files that were compiled with +the previous configuration. Since 'make clean' also deletes the new +makefile, a second invokation of the configure script is then +performed to re-create the makefile. The final make then creates the +tecla library from scratch. + +Once you have confirmed that the new configuration works, please send +the modified "configure.in" template to mcs@astro.caltech.edu, so that +your changes can be included in subsequent releases. diff --git a/libtecla-1.4.1/README b/libtecla-1.4.1/README new file mode 100644 index 0000000..894819d --- /dev/null +++ b/libtecla-1.4.1/README @@ -0,0 +1,53 @@ +This is version 1.4.1 of the tecla command-line editing library. + +For the current official release, please direct your browser to: + + http://www.astro.caltech.edu/~mcs/tecla/index.html + +The tecla library provides UNIX and LINUX programs with interactive +command line editing facilities, similar to those of the unix tcsh +shell. In addition to simple command-line editing, it supports recall +of previously entered command lines, TAB completion of file names, and +in-line wild-card expansion of filenames. The internal functions +which perform file-name completion and wild-card expansion are also +available externally for optional use by programs, along with a module +for tab-completion and lookup of filenames in a list of directories. + +Note that special care has been taken to allow the use of this library +in threaded programs. The option to enable this is discussed in the +Makefile, and specific discussions of thread safety are presented in +the included man pages. + +For instructions on how to compile and install the library, please see +the INSTALL file, which should be in the same directory as this file. + +Copyright and Disclaimer +------------------------ +Copyright (c) 2000, 2001 by Martin C. Shepherd. + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. diff --git a/libtecla-1.4.1/RELEASE.NOTES b/libtecla-1.4.1/RELEASE.NOTES new file mode 100644 index 0000000..1b18a4a --- /dev/null +++ b/libtecla-1.4.1/RELEASE.NOTES @@ -0,0 +1,357 @@ +This file lists major changes which accompany each new release. + +Version 1.4.1: + + This is a maintenance release. It includes minor changes to support + Mac OS X (Darwin), the QNX real-time operating system, and Cygwin + under Windows. It also fixes an oversight that was preventing the + tab key from inserting tab characters when users unbound the + complete-word action from it. + +Version 1.4.0: + + The contents of the history list can now be saved and restored with + the new gl_save_history() and gl_load_history() functions. + + Event handlers can now be registered to watch for and respond to I/O + on arbitrary file descriptors while gl_get_line() is waiting for + terminal input from the user. See the gl_get_line(3) man page + for details on gl_watch_fd(). + + As an optional alternative to getting configuration information only + from ~/.teclarc, the new gl_configure_getline() function allows + configuration commands to be taken from any of, a string, a + specified application-specific file, and/or a specified + user-specific file. See the gl_get_line(3) man page for details. + + The version number of the library can now be queried using the + libtecla_version() function. See the libtecla(3) man page. + + The new gl_group_history() function allows applications to group + different types of input line in the history buffer, and arrange for + only members of the appropriate group to be recalled on a given call + to gl_get_line(). See the gl_get_line(3) man page. + + The new gl_show_history() function displays the current history list + to a given stdio output stream. See the gl_get_line(3) man page. + + new_GetLine() now allows you to specify a history buffer size of + zero, thus requesting that no history buffer be allocated. You can + subsequently resize or delete the history buffer at any time, by + calling gl_resize_history(), limit the number of lines that are + allowed in the buffer by calling gl_limit_history(), clear either + all history lines from the history list, or just the history lines + that are associated with the current history group, by calling + gl_clear_history, and toggle the history mechanism on and off by + calling gl_toggle_history(). + + The new gl_terminal_size() function can be used to query the + current terminal size. It can also be used to supply a default + terminal size on systems where no mechanism is available for + looking up the size. + + The contents and configuration of the history list can now be + obtained by the calling application, by calling the new + gl_lookup_history(), gl_state_of_history(), gl_range_of_history() + and gl_size_of_history() functions. See the gl_get_line(3) man page. + + Echoing of the input line as it is typed, can now be turned on and + off via the new gl_echo_mode() function. While echoing is disabled, + newly entered input lines are omitted from the history list. See + the gl_get_line(3) man page. + + While the default remains to display the prompt string literally, + the new gl_prompt_style() function can be used to enable text + attribute formatting directives in prompt strings, such as + underlining, bold font, and highlighting directives. + + Signal handling in gl_get_line() is now customizable. The default + signal handling behavior remains essentially the same, except that + the SIGTSTP, SIGTTIN and SIGTTOU are now forwarded to the + corresponding signal handler of the calling program, instead of + causing a SIGSTOP to be sent to the application. It is now possible + to remove signals from the list that are trapped by gl_get_line(), + as well as add new signals to this list. The signal and terminal + environments in which the signal handler of the calling program is + invoked, and what gl_get_line() does after the signal handler + returns, is now customizable on a per signal basis. You can now also + query the last signal that was caught by gl_get_line(). This is + useful when gl_get_line() aborts with errno=EINTR, and you need to + know which signal caused it to abort. + + Key-sequences bound to action functions can now start with printable + characters. Previously only keysequences starting with control or + meta characters were permitted. + + gl_get_line() is now 8-bit clean. If the calling program has + correctly called setlocale(LC_CTYPE,""), then the user can select an + alternate locale by setting the standard LC_CTYPE, LC_ALL, or LANG + environment variables, and international characters can then be + entered directly, either by using a non-US keyboard, or by using a + compose key on a standard US keyboard. Note that in locales in which + meta characters become printable, meta characters no longer match + M-c bindings, which then have to be entered using their escape-c + equivalents. Fortunately most modern terminal emulators either + output the escape-c version by default when the meta key is used, or + can be configured to do so (see the gl_get_line(3) man page), so in + most cases you can continue to use the meta key. + + Completion callback functions can now tell gl_get_line() to return + the input line immediately after a successful tab completion, simply + by setting the last character of the optional continuation suffix to + a newline character (ie. in the call to cpl_add_completion()). + + It is now safe to create and use multiple GetLine objects, albeit + still only from a single thread. In conjunction with the new + gl_configure_getline() function, this optionally allows multiple + GetLine objects with different bindings to be used to implement + different input modes. + + The edit-mode configuration command now accepts the argument, + none. This tells gl_get_line() to revert to using just the native + line editing facilities provided by the terminal driver. This could + be used if the termcap or terminfo entry of the host terminal were + badly corrupted. + + Application callback functions invoked by gl_get_line() can now + change the displayed prompt using the gl_replace_prompt() function. + + Their is now an optional program distributed with the library. This + is a beta release of a program which adds tecla command-line editing + to virtually any third party application without the application + needing to be linked to the library. See the enhance(3) man page for + further details. Although built and installed by default, the + INSTALL document explains how to prevent this. + + The INSTALL document now explains how you can stop the demo programs + from being built and installed. + + NetBSD/termcap fixes. Mike MacFaden reported two problems that he + saw when compiling libtecla under NetBSD. Both cases were related to + the use of termcap. Most systems use terminfo, so this problem has + gone unnoticed until now, and won't have affected the grand majority + of users. The configure script had a bug which prevented the check + for CPP working properly, and getline.c wouldn't compile due to an + undeclared variable when USE_TERMCAP was defined. Both problems have + now been fixed. Note that if you successfully compiled version + 1.3.3, this problem didn't affect you. + + An unfortunate and undocumented binding of the key-sequence M-O was + shadowing the arrow-key bindings on systems that use ^[OA etc. I + have removed this binding (the documented lower case M-o binding + remains bound). Under the KDE konsole terminal this was causing the + arrow keys to do something other than expected. + + There was a bug in the history list code which could result in + strange entries appearing at the start of the history list once + enough history lines had been added to the list to cause the + circular history buffer to wrap. This is now fixed. + +Version 1.3.3: + + Signal handling has been re-written, and documentation of its + behaviour has been added to the gl_get_line(3) man page. In addition + to eliminating race conditions, and appropriately setting errno for + those signals that abort gl_get_line(), many more signals are now + intercepted, making it less likely that the terminal will be left in + raw mode by a signal that isn't trapped by gl_get_line(). + + A bug was also fixed that was leaving the terminal in raw mode if + the editing mode was changed interactively between vi and emacs. + This was only noticeable when running programs from old shells that + don't reset terminal modes. + +Version 1.3.2: + + Tim Eliseo contributed a number of improvements to vi mode, + including a fuller set of vi key-bindings, implementation of the vi + constraint that the cursor can't backup past the point at which + input mode was entered, and restoration of overwritten characters + when backspacing in overwrite mode. There are also now new bindings + to allow users to toggle between vi and emacs modes interactively. + The terminal bell is now used in some circumstances, such as when an + unrecognized key sequence is entered. This can be turned off by the + new nobeep option in the tecla configuration file. + + Unrelated to the above, a problem under Linux which prevented ^Q + from being used to resume terminal output after the user had pressed + ^S, has been fixed. + +Version 1.3.1: + + In vi mode a bug was preventing the history-search-backward and + history-search-forward actions from doing anything when invoked on + empty lines. On empty lines they now act like up-history and + down-history respectively, as in emacs mode. + + When creating shared libraries under Linux, the -soname directive + was being used incorrectly. The result is that Linux binaries linked + with the 1.2.3, 1.2.4 and 1.3.0 versions of the tecla shared + libraries, will refuse to see other versions of the shared library + until relinked with version 1.3.1 or higher. + + The configure script can now handle the fact that under Solaris-2.6 + and earlier, the only curses library is a static one that hides in + /usr/ccs/lib. Under Linux it now also caters for old versions of GNU + ld which don't accept version scripts. + + The demos are now linked against the shared version of the library + if possible. Previously they were always linked with the static + version. + +Version 1.3.0: + + The major change in this release is the addition of an optional vi + command-line editing mode in gl_get_line(), along with lots of new + action functions to support its bindings. To enable this, first + create a ~/.teclarc file if you don't already have one, then add the + following line to it. + + edit-mode vi + + The default vi bindings, which are designed to mimic those of the vi + editor as closely as possible, are described in the gl_get_line(3) + man page. + + A new convenience function called ef_list_expansions() has been + added for listing filename expansions. See the ef_list_expansions(3) + man page for details. This is used in a new list-glob binding, bound + to ^Xg in emacs mode, and ^G in vi input mode. + + A bug has been fixed in the key-binding table expansion code. This + bug would have caused problems to anybody who defined more than + about 18 personalized key-bindings in their ~/.teclarc file. + +Version 1.2.4: + + Buffered I/O is now used for writing to terminals, and where + supported, cursor motion is done with move-n-positions terminfo + capabilities instead of doing lots of move-1-position requests. This + greatly improves how the library feels over slow links. + + You can now optionally compile different architectures in different + directories, without having to make multiple copies of the + distribution. This is documented in the INSTALL file. + + The ksh ~+ directive is now supported. + + Thanks to Markus Gyger for the above improvements. + + Documentation has been added to the INSTALL file describing features + designed to facilitate configuration and installation of the library + as part of larger packages. These features are intended to remove + the need to modify the tecla distribution's configuration and build + procedures when embedding the libtecla distribution in other package + distributions. + + A previous fix to stop the cursor from warping when the last + character of the input line was in the last column of the terminal, + was only being used for the first terminal line of the input line. + It is now used for all subsequent lines as well, as originally + intended. + +Version 1.2.3: + + The installation procedure has been better automated with the + addition of an autoconf configure script. This means that installers + can now compile and install the library by typing: + + ./configure + make + make install + + On all systems this makes at least the normal static version of the + tecla library. It also makes the reentrant version if reentrant + POSIX functions are detected. Under Solaris, Linux and HP-UX the + configuration script arranges for shared libraries to be compiled in + addition to the static libraries. It is hoped that installers will + return information about how to compile shared libraries on other + systems, for inclusion in future releases, and to this end, a new + PORTING guide has been provided. + + The versioning number scheme has been changed. This release would + have been 1.2c, but instead will be refered to as 1.2.3. The + versioning scheme, based on conventions used by Sun Microsystems, is + described in configure.in. + + The library was also tested under HP-UX, and this revealed two + serious bugs, both of which have now been fixed. + + The first bug prevented the library from writing control codes to + terminals on big-endian machines, with the exception of those + running under Solaris. This was due to an int variable being used + where a char was needed. + + The second bug had the symptom that on systems that don't use the + newline character as the control code for moving the cursor down a + line, a newline wasn't started when the user hit enter. + +Version 1.2b: + + Two more minor bug fixes: + + Many terminals don't wrap the cursor to the next line when a + character is written to the rightmost terminal column. Instead, they + delay starting a new line until one more character is written, at + which point they move the cursor two positions. gl_get_line() + wasn't aware of this, so cursor repositionings just after writing + the last character of a column, caused it to erroneously go up a + line. This has now been remedied, using a method that should work + regardless of whether a terminal exhibits this behavior or not. + + Some systems dynamically record the current terminal dimensions in + environment variables called LINES and COLUMNS. On such systems, + during the initial terminal setup, these values should override the + static values read from the terminal information databases, and now + do. Previously they were only used if the dimensions returned by + terminfo/termcap looked bogus. + +Version 1.2a: + + This minor release fixes the following two bugs: + + The initial terminal size and subsequent changes thereto, weren't + being noticed by gl_get_line(). This was because the test for the + existence of TIOCWINSZ was erroneously placed before the inclusion + of termios.h. One of the results was that on input lines that + spanned more than one terminal line, the cursor occasionally jumped + unexpectedly to the previous terminal line. + + On entering a line that wrapped over multiple terminal lines, + gl_get_line() simply output a carriage-return line-feed at the point + at which the user pressed return. Thus if one typed in such a line, + then moved back onto one of the earlier terminal lines before + hitting return, the cursor was left on a line containing part of the + line that had just been entered. This didn't do any harm, but it + looked a mess. + +Version 1.2: + + A new facility for looking up and completing filenames in UNIX-style + paths has now been added (eg. you can search for, or complete + commands using the UNIX PATH environment variable). See the + pca_lookup_file(3) man page. + + The already existing filename completion callback can now be made + selective in what types of files it lists. See the + cpl_complete_word(3) man page. + + Due to its potential to break applications when changed, the use of + the publically defined CplFileArgs structure to configure the + cpl_file_completions() callback is now deprecated. The definition + of this structure has been frozen, and its documentation has been + removed from the man pages. It will remain supported, but if you + have used it, you are recommended to switch to the new method, which + involves a new opaque configuration object, allocated via a provided + constructor function, configured via accessor functions, and + eventually deleted with a provided destructor function. The + cpl_file_completions() callback distinguishes which structure type + it has been sent by virtue of a code placed at the start of the new + structure by the constructor. It is assumed that no existing + applications set the boolean 'escaped' member of the CplFileArgs + structure to 4568. The new method is documented in the + cpl_complete_word(3) man page. + +Version 1.1j + + This was the initial public release on freshmeat.org. diff --git a/libtecla-1.4.1/config.guess b/libtecla-1.4.1/config.guess new file mode 100644 index 0000000..0ce538b --- /dev/null +++ b/libtecla-1.4.1/config.guess @@ -0,0 +1,1183 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. +# +# 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 +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + exit 0 + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c < /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/libtecla-1.4.1/config.sub b/libtecla-1.4.1/config.sub new file mode 100644 index 0000000..c8e7785 --- /dev/null +++ b/libtecla-1.4.1/config.sub @@ -0,0 +1,1268 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. +# +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | fr30 | avr) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/libtecla-1.4.1/configure b/libtecla-1.4.1/configure new file mode 100755 index 0000000..feaa587 --- /dev/null +++ b/libtecla-1.4.1/configure @@ -0,0 +1,1939 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # 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 << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=getline.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + +MAJOR_VER="1" + + + +MINOR_VER="4" + + + +MICRO_VER="1" + + +CFLAGS="$CFLAGS" +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:543: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:573: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:624: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:656: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 667 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:698: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:703: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:731: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:765: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:794: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +for ac_prog in gawk mawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:821: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + + + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:855: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:931: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:952: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:970: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + +case $target in +*-sun-solaris2.[0-6]|*-sun-solaris2.[0-6].*) + LIBS="$LIBS -L/usr/ccs/lib" + ;; +esac + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1002: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1023: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1040: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for tigetstr in -lcurses""... $ac_c" 1>&6 +echo "configure:1082: checking for tigetstr in -lcurses" >&5 +ac_lib_var=`echo curses'_'tigetstr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcurses $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <<\EOF +#define USE_TERMINFO 1 +EOF + + LIBS="$LIBS -lcurses" + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for tigetstr in -lncurses""... $ac_c" 1>&6 +echo "configure:1126: checking for tigetstr in -lncurses" >&5 +ac_lib_var=`echo ncurses'_'tigetstr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lncurses $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <<\EOF +#define USE_TERMINFO 1 +EOF + + LIBS="$LIBS -lncurses" + +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for tgetstr in -lcurses""... $ac_c" 1>&6 +echo "configure:1170: checking for tgetstr in -lcurses" >&5 +ac_lib_var=`echo curses'_'tgetstr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcurses $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + cat >> confdefs.h <<\EOF +#define USE_TERMCAP 1 +EOF + + LIBS="$LIBS -lcurses" + ac_safe=`echo "termcap.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for termcap.h""... $ac_c" 1>&6 +echo "configure:1212: checking for termcap.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1222: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_TERMCAP_H 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + + + +ac_safe=`echo "term.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for term.h""... $ac_c" 1>&6 +echo "configure:1259: checking for term.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_TERM_H 1 +EOF + +else + echo "$ac_t""no" 1>&6 + + ac_safe=`echo "ncurses/term.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for ncurses/term.h""... $ac_c" 1>&6 +echo "configure:1294: checking for ncurses/term.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1304: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_NCURSES_TERM_H 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + + +ac_safe=`echo "curses.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for curses.h""... $ac_c" 1>&6 +echo "configure:1335: checking for curses.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_CURSES_H 1 +EOF + +else + echo "$ac_t""no" 1>&6 + + ac_safe=`echo "ncurses/curses.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for ncurses/curses.h""... $ac_c" 1>&6 +echo "configure:1370: checking for ncurses/curses.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1380: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_NCURSES_CURSES_H 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + + + +TARGETS="normal reentrant" + + +echo $ac_n "checking for reentrant functions""... $ac_c" 1>&6 +echo "configure:1414: checking for reentrant functions" >&5 +if eval "test \"`echo '$''{'tecla_cv_reentrant'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + KEPT_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199506L" + cat > conftest.$ac_ext < +#include +#include +#include +#include + +int main() { + + (void) readdir_r(NULL, NULL, NULL); + (void) getpwuid_r(geteuid(), NULL, NULL, 0, NULL); + (void) getpwnam_r(NULL, NULL, NULL, 0, NULL); + +; return 0; } +EOF +if { (eval echo configure:1439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + tecla_cv_reentrant=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + tecla_cv_reentrant=no +fi +rm -f conftest* + CFLAGS="$KEPT_CFLAGS" + +fi + +echo "$ac_t""$tecla_cv_reentrant" 1>&6 + + +if test $tecla_cv_reentrant = no; then + TARGETS="normal" +fi + + +echo $ac_n "checking for select system call""... $ac_c" 1>&6 +echo "configure:1462: checking for select system call" >&5 +if eval "test \"`echo '$''{'tecla_cv_select'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#endif +#include +#include +#include + +int main() { + + fd_set fds; + int nready; + FD_ZERO(&fds); + FD_SET(1, &fds); + nready = select(2, &fds, &fds, &fds, NULL); + +; return 0; } +EOF +if { (eval echo configure:1488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + tecla_cv_select=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + tecla_cv_select=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$tecla_cv_select" 1>&6 + + +if test $tecla_cv_select = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SELECT 1 +EOF + +fi + + +echo $ac_n "checking for SysV pseudo-terminals""... $ac_c" 1>&6 +echo "configure:1513: checking for SysV pseudo-terminals" >&5 +if eval "test \"`echo '$''{'tecla_cv_sysv_pty'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include +#include + +int main() { + + char *name = ptsname(0); + int i1 = grantpt(0); + int i2 = unlockpt(0); + int i3 = ioctl(0, I_PUSH, "ptem"); + return 0; + +; return 0; } +EOF +if { (eval echo configure:1536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + tecla_cv_sysv_pty=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + tecla_cv_sysv_pty=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$tecla_cv_sysv_pty" 1>&6 + + +if test $tecla_cv_sysv_pty = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SYSV_PTY 1 +EOF + +fi + + + +SHARED_EXT="" + + + +SHARED_ALT="" + + + +SHARED_CFLAGS="" + + + +LINK_SHARED="" + + +case $target in +*solaris*) + cat >> confdefs.h <<\EOF +#define __EXTENSIONS__ 1 +EOF + + SHARED_EXT=".so.${MAJOR_VER}" + SHARED_ALT=".so" + LINK_SHARED='ld -G -M $$(srcdir)/libtecla.map -o $$@ -h $$(@F) -z defs -i $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="-Kpic" + case $CC in + */cc|cc) SHARED_CFLAGS="$SHARED_CFLAGS -xstrconst" ;; + gcc) CFLAGS="-I/usr/include $CFLAGS" ;; + esac + case $target in + *sparc*) SHARED_CFLAGS="$SHARED_CFLAGS -xregs=no%appl" + esac + ;; +*linux*) + SHARED_EXT=".so.${MAJOR_VER}.${MINOR_VER}.${MICRO_VER}" + SHARED_ALT=".so .so.${MAJOR_VER}" + + + echo $ac_n "checking for --version-script in GNU ld""... $ac_c" 1>&6 +echo "configure:1600: checking for --version-script in GNU ld" >&5 +if eval "test \"`echo '$''{'tecla_cv_gnu_ld_script'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if (echo 'void dummy(void) {return;}' > dummy.c; $CC -c -fpic dummy.c; \ + ld -o dummy.so dummy.o -shared --version-script=$srcdir/libtecla.map) 1>&2 2>/dev/null; then + tecla_cv_gnu_ld_script=yes + else + tecla_cv_gnu_ld_script=no + fi + rm -f dummy.c dummy.o dummy.so + +fi + +echo "$ac_t""$tecla_cv_gnu_ld_script" 1>&6 + if test $tecla_cv_gnu_ld_script = yes; then + VERSION_OPT='--version-script=$$(srcdir)/libtecla.map' + else + VERSION_OPT='' + fi + + LINK_SHARED='ld -o $$@ -soname libtecla$$(SUFFIX).so.'${MAJOR_VER}' -shared '$VERSION_OPT' $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="-fpic" + ;; +*hpux*) + SHARED_EXT=".${MAJOR_VER}" + SHARED_ALT=".sl" + LINK_SHARED='ld -b +h $$(@F) +k +vshlibunsats -o $$@ -c libtecla.map.opt $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="+z" + ;; +*dec-osf*) + cat >> confdefs.h <<\EOF +#define _OSF_SOURCE 1 +EOF + + ;; +esac + + +if test "$GCC"_ = "yes"_ && test "$LINK_SHARED"_ != "_" ; then + SHARED_CFLAGS="-fpic" + case $target_os in + sparc*solaris*) SHARED_CFLAGS="$SHARED_CFLAGS -mno-app-regs" + esac + LINK_SHARED="$LINK_SHARED `gcc -print-libgcc-file-name`" +fi + + + + + +if test "$LINK_SHARED"_ != "_"; then + TARGET_LIBS="static shared" +else + TARGET_LIBS="static" + LINK_SHARED="@:" +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@MAJOR_VER@%$MAJOR_VER%g +s%@MINOR_VER@%$MINOR_VER%g +s%@MICRO_VER@%$MICRO_VER%g +s%@CC@%$CC%g +s%@SET_MAKE@%$SET_MAKE%g +s%@LN_S@%$LN_S%g +s%@AWK@%$AWK%g +s%@RANLIB@%$RANLIB%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CPP@%$CPP%g +s%@TARGETS@%$TARGETS%g +s%@SHARED_EXT@%$SHARED_EXT%g +s%@SHARED_ALT@%$SHARED_ALT%g +s%@SHARED_CFLAGS@%$SHARED_CFLAGS%g +s%@LINK_SHARED@%$LINK_SHARED%g +s%@TARGET_LIBS@%$TARGET_LIBS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/libtecla-1.4.1/configure.in b/libtecla-1.4.1/configure.in new file mode 100644 index 0000000..3b083b9 --- /dev/null +++ b/libtecla-1.4.1/configure.in @@ -0,0 +1,412 @@ +dnl This is the input file which autoconf uses to construct a +dnl "configure" script for the tecla library. It is a bourne shell +dnl script which autoconf pre-processes with the m4 preprocessor to +dnl expand autoconf-defined m4 macros such as AC_INIT(). The +dnl following line just initializes autoconf. Autoconf interprets the +dnl single argument as the name of an arbitrary file, which it uses to +dnl ensure that it is being run correctly from the directory which +dnl contains the libtecla source code. + +AC_INIT(getline.c) + +dnl Here we set the major version number of the tecla library. +dnl Incrementing this number implies that a change has been made to +dnl the library's public interface, which makes it binary incompatible +dnl with programs that were linked with previous shared versions of +dnl the tecla library. Incompatible changes of this type should be +dnl avoided at all costs, so it is hoped that the major version number +dnl won't ever have to change. The major version number must be a +dnl small integer number, preferably a single numeric digit. + +AC_SUBST(MAJOR_VER) +MAJOR_VER="1" + +dnl Set the minor version number of the tecla library. This number +dnl should be incremented by one whenever additional functionality, +dnl such as new functions or modules, are added to the library. The +dnl idea is that a program that was linked with a shared library of +dnl the same major version number, but a lower minor version number, +dnl will continue to function when the run-time loader links it +dnl against the updated version. The minor version number must be a +dnl small integer number, which should be reset to 0 whenever the +dnl major version number is incremented. + +AC_SUBST(MINOR_VER) +MINOR_VER="4" + +dnl Set the micro version number of the tecla library. This is +dnl incremented whenever modifications to the library are made which +dnl make no changes to the public interface, but which fix bugs and/or +dnl improve the behind-the-scenes implementation. The micro version +dnl number should be reset to 0 whenever the minor version number is +dnl incremented. The micro version number must be a small integer +dnl number. + +AC_SUBST(MICRO_VER) +MICRO_VER="1" + +dnl The AC_PROG_CC line looks for a C compiler, and if gcc is chosen, +dnl sets the $GCC shell variable to "yes". Make sure that CFLAGS is +dnl set to something first, to prevent AC_PROG_CC from substituting -g +dnl for the optimization level. + +CFLAGS="$CFLAGS" +AC_PROG_CC + +dnl Apparently not all implementations of the 'make' command define +dnl the MAKE variable. The following directive creates a variable +dnl called SET_MAKE which when expanded in a makefile is either empty +dnl if the local 'make' command was found to define the MAKE variable, +dnl or contains an assignment which will give the MAKE variable the +dnl value 'make'. + +AC_PROG_MAKE_SET + +dnl The following directive causes autoconf to see if symbolic links +dnl are supported on the current filesystem. If so, it sets the +dnl variable LN_S to "ln -s". Otherwise it sets LN_S to just "ln". +dnl This allows us to create symbolic links where possible, but falls +dnl back to creating hard links where symbolic links aren't available. + +AC_PROG_LN_S + +dnl The following macro searches for the best implementation of awk +dnl on the host system, and records it in the AWK shell variable. + +AC_PROG_AWK + +dnl If ranlib is needed on the target system, the RANLIB make variable +dnl is set to ranlib. Otherwise it is set to :, which is the do-nothing +dnl command of the bourne shell. + +AC_PROG_RANLIB + +dnl The following directive tells autoconf to figure out the target +dnl system type and assign a canonical name for this to the $target +dnl shell variable. This is used below in the target-specific case +dnl statement. + +AC_CANONICAL_SYSTEM + +dnl In early versions of Solaris, some libraries are in /usr/ccs/lib, +dnl where gcc doesn't look. The tests below for the curses library +dnl would thus fail without this directory being added to the search +dnl path. We thus add it here before the tests. Note that in the +dnl following, since [ and ] are m4 quotes, and m4 will remove the +dnl outermost quotes when it processes this file, we have to double +dnl them up here to get [0-6] to appear in the output configure +dnl script. + +case $target in +*-sun-solaris2.[[0-6]]|*-sun-solaris2.[[0-6]].*) + LIBS="$LIBS -L/usr/ccs/lib" + ;; +esac + +dnl The following lines look for terminfo functions in the normal +dnl curses library. If not found, they are searched for in the GNU +dnl ncurses library. If the terminfo functions still aren't found, +dnl then termcap functions are searched for in the curses library. If +dnl either set of functions is found, the corresponding variable +dnl USE_TERMINFO or USE_TERMCAP is arranged to be defined in CFLAGS, +dnl via the exported DEFINES shell variable, and the library in which +dnl they were found is appended to the LIBS shell variable. + +AC_CHECK_LIB(curses, tigetstr, [ + AC_DEFINE(USE_TERMINFO) + LIBS="$LIBS -lcurses" +], [AC_CHECK_LIB(ncurses, tigetstr, [ + AC_DEFINE(USE_TERMINFO) + LIBS="$LIBS -lncurses" +], [AC_CHECK_LIB(curses, tgetstr, [ + AC_DEFINE(USE_TERMCAP) + LIBS="$LIBS -lcurses" + AC_CHECK_HEADER(termcap.h, AC_DEFINE(HAVE_TERMCAP_H)) +])])]) + +dnl Some systems don't have term.h, some systems squirrel it away +dnl in an ncurses sub-directory of the system include directory. +dnl If term.h exists in the normal location, arrange for HAVE_TERM_H +dnl to be added to CFLAGS in the Makefile, by appending it to the +dnl DEFINES shell variable. Otherwise, if it exists under an ncurses +dnl sub-directory, arrange for HAVE_NCURSES_TERM_H to be set instead. +dnl If it isn't found in either of these places, neither of these +dnl variables is set, so term.h just doesn't get included. + +AC_CHECK_HEADER(term.h, AC_DEFINE(HAVE_TERM_H), [ + AC_CHECK_HEADER(ncurses/term.h, AC_DEFINE(HAVE_NCURSES_TERM_H)) +]) + +dnl Do the same search for curses.h. + +AC_CHECK_HEADER(curses.h, AC_DEFINE(HAVE_CURSES_H), [ + AC_CHECK_HEADER(ncurses/curses.h, AC_DEFINE(HAVE_NCURSES_CURSES_H)) +]) + +dnl The following variable lists the targets that will be created if +dnl the user runs make without any arguments. Initially we assume +dnl that we can create both the normal and the reentrant versions +dnl of the library. + +AC_SUBST(TARGETS) +TARGETS="normal reentrant" + +dnl Check for reentrant functions by attempting to compile and link a +dnl temporary program which calls them, being sure to include the +dnl appropriate headers and define _POSIX_C_SOURCE, just in case any +dnl of the functions are defined as macros. In the following, +dnl AC_CACHE_CHECK outputs the message "checking for reentrant +dnl functions". If this check has been done before, it assigns the +dnl cached yes/no value to tecla_cv_reentrant. Otherwise it uses +dnl AC_TRY_LINK() to attempt to compile and link the specified dummy +dnl program, and sets tecla_cv_reentrant to yes or no, depending on +dnl whether this succeeds. Finally it caches the value of +dnl tecla_cv_reentrant in the file config.cache, and writes "yes" or +dnl "no" to the terminal. + +AC_CACHE_CHECK(for reentrant functions, tecla_cv_reentrant, [ + KEPT_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199506L" + AC_TRY_LINK([ +#include +#include +#include +#include +#include + ], [ + (void) readdir_r(NULL, NULL, NULL); + (void) getpwuid_r(geteuid(), NULL, NULL, 0, NULL); + (void) getpwnam_r(NULL, NULL, NULL, 0, NULL); + ], tecla_cv_reentrant=yes, tecla_cv_reentrant=no) + CFLAGS="$KEPT_CFLAGS" +]) + +dnl If the necessary reentrant functions weren't found to be +dnl available, default to only compiling the non-reentrant version of +dnl the library. + +if test $tecla_cv_reentrant = no; then + TARGETS="normal" +fi + +dnl Check for the select system call with the normal arguments, +dnl by attempting to compile and link a temporary program which +dnl calls it, being sure to include the appropriate headers. +dnl In the following, AC_CACHE_CHECK outputs the message +dnl "checking for select system call". If this check has been done +dnl before, it assigns the cached yes/no value to tecla_cv_select. +dnl Otherwise it uses AC_TRY_LINK() to attempt to compile and link +dnl the specified dummy program, and sets tecla_cv_select to yes +dnl or no, depending on whether this succeeds. Finally it caches +dnl the value of tecla_cv_select in the file config.cache, and +dnl writes "yes" or "no" to the terminal. + +AC_CACHE_CHECK(for select system call, tecla_cv_select, [ + AC_TRY_LINK([ +#ifdef HAVE_SELECT_H +#include +#endif +#include +#include +#include + ], [ + fd_set fds; + int nready; + FD_ZERO(&fds); + FD_SET(1, &fds); + nready = select(2, &fds, &fds, &fds, NULL); + ], tecla_cv_select=yes, tecla_cv_select=no) +]) + +dnl If the select function was available, arrange for HAVE_SELECT to +dnl be defined by CFLAGS. + +if test $tecla_cv_select = yes; then + AC_DEFINE(HAVE_SELECT) +fi + +dnl Check if this system supports the system V pseudo terminal interface. + +AC_CACHE_CHECK(for SysV pseudo-terminals, tecla_cv_sysv_pty, [ + AC_TRY_LINK([ +#include +#include +#include + ], [ + char *name = ptsname(0); + int i1 = grantpt(0); + int i2 = unlockpt(0); + int i3 = ioctl(0, I_PUSH, "ptem"); + return 0; + ], tecla_cv_sysv_pty=yes, tecla_cv_sysv_pty=no) +]) + +dnl If the system-V pseudo-terminal interface is available, arrange +dnl for HAVE_SYSV_PTY to be defined by CFLAGS. + +if test $tecla_cv_sysv_pty = yes; then + AC_DEFINE(HAVE_SYSV_PTY) +fi + +dnl The following variable contains the extension to append to +dnl "libtecla" and "libtecla_r" when creating shared libraries on the +dnl target platform. This is system dependent and is ignored if +dnl LINK_SHARED remains an empty string. On most platforms that +dnl support shared libaries, this will be .so.$MAJOR_VER, where +dnl MAJOR_VER is the major version number described above, which on +dnl some systems, tells the run-time loader if the program being +dnl loaded is binary compatible with a given version of the library +dnl (see the discussion of MAJOR_VER near the top of this file). +dnl The following empty default can be overriden on a system by system +dnl basis later in this file. + +AC_SUBST(SHARED_EXT) +SHARED_EXT="" + +dnl When a shared library is installed with the extension $SHARED_EXT, +dnl you can optionally produce other copies of this library with +dnl different extensions. This is done using symbolic or hard links, +dnl depending on what is available on the current filesystem, and the +dnl extensions to use for these links are listed in the following +dnl variable, separated by spaces. The following empty default can be +dnl overriden on a system by system basis later in this file. + +AC_SUBST(SHARED_ALT) +SHARED_ALT="" + +dnl The following variable lists extra compilation flags needed to +dnl create object files that can be included in shared libraries. +dnl Normally one would include a flag to tell the C compiler to +dnl compile position-independent code. This option commonly includes +dnl the acronym 'pic'. + +AC_SUBST(SHARED_CFLAGS) +SHARED_CFLAGS="" + +dnl On systems that support shared libraries, the following variable +dnl provides the command needed to make a shared library. In this +dnl variable, $$@ will be replaced with the name of the shared +dnl library, $$(LIB_OBJECTS) will be replaced with a space separated +dnl list of the object files that are to be included in the library, +dnl and libtecla$$(SUFFIX) will be the name of the library being +dnl built, minus the system-specific extension (eg. libtecla or +dnl libtecla_r). If LINK_SHARED is left as an empty string, shared +dnl library creation will not attempted. If your system supports +dnl shared library creation, you should override the default value of +dnl this variable in the target-specific case statement later in this +dnl file. + +AC_SUBST(LINK_SHARED) +LINK_SHARED="" + +dnl The following bourne shell case statement is where system +dnl dependencies can be added. In particular, if your system supports +dnl shared library creation, the following switch is the place to +dnl configure it. To do so you will first need to find out what target +dnl type was just assigned by the AC_CANONICAL_SYSTEM macro executed +dnl previously. The target type of your current system can be +dnl determined by cd'ing to the top level directory of the tecla +dnl distribution, and typing the command "sh config.guess". This will +dnl report what autoconf thinks the system type is. Note that this +dnl will be very specific, so if you know that the configuration +dnl parameters that you are about to provide apply to different +dnl versions of the current system type, you can express this in the +dnl case statement by using a wild-card in place of the version +dnl number, or by using an | alternation to list one or more version +dnl names. Beware that autoconf uses [] as quote characters, so if you +dnl want to use a regexp character range like [a-z], you should write +dnl this as [[a-z]]. + +case $target in +*solaris*) + AC_DEFINE(__EXTENSIONS__) + SHARED_EXT=".so.${MAJOR_VER}" + SHARED_ALT=".so" + LINK_SHARED='ld -G -M $$(srcdir)/libtecla.map -o $$@ -h $$(@F) -z defs -i $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="-Kpic" + case $CC in + */cc|cc) SHARED_CFLAGS="$SHARED_CFLAGS -xstrconst" ;; + gcc) CFLAGS="-I/usr/include $CFLAGS" ;; + esac + case $target in + *sparc*) SHARED_CFLAGS="$SHARED_CFLAGS -xregs=no%appl" + esac + ;; +*linux*) + SHARED_EXT=".so.${MAJOR_VER}.${MINOR_VER}.${MICRO_VER}" + SHARED_ALT=".so .so.${MAJOR_VER}" + +dnl See if the installed version of Gnu ld accepts version scripts. + + AC_CACHE_CHECK([for --version-script in GNU ld], tecla_cv_gnu_ld_script, [ + if (echo 'void dummy(void) {return;}' > dummy.c; $CC -c -fpic dummy.c; \ + ld -o dummy.so dummy.o -shared --version-script=$srcdir/libtecla.map) 1>&2 2>/dev/null; then + tecla_cv_gnu_ld_script=yes + else + tecla_cv_gnu_ld_script=no + fi + rm -f dummy.c dummy.o dummy.so + ]) + if test $tecla_cv_gnu_ld_script = yes; then + VERSION_OPT='--version-script=$$(srcdir)/libtecla.map' + else + VERSION_OPT='' + fi + + LINK_SHARED='ld -o $$@ -soname libtecla$$(SUFFIX).so.'${MAJOR_VER}' -shared '$VERSION_OPT' $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="-fpic" + ;; +*hpux*) + SHARED_EXT=".${MAJOR_VER}" + SHARED_ALT=".sl" + LINK_SHARED='ld -b +h $$(@F) +k +vshlibunsats -o $$@ -c libtecla.map.opt $$(LIB_OBJECTS) $$(LIBS) -lc' + SHARED_CFLAGS="+z" + ;; +*dec-osf*) + AC_DEFINE(_OSF_SOURCE) + ;; +esac + +dnl The following statement checks to see if the GNU C compiler has +dnl been chosen instead of the normal compiler of the host operating +dnl system. If it has, and shared library creation has been +dnl configured, it replaces the shared-library-specific C compilation +dnl flags with those supported by gcc. Also append the gcc run-time +dnl library to the shared library link line. + +if test "$GCC"_ = "yes"_ && test "$LINK_SHARED"_ != "_" ; then + SHARED_CFLAGS="-fpic" + case $target_os in + sparc*solaris*) SHARED_CFLAGS="$SHARED_CFLAGS -mno-app-regs" + esac + LINK_SHARED="$LINK_SHARED `gcc -print-libgcc-file-name`" +fi + +dnl The following variable will list which types of libraries, +dnl "static", and possibly "shared", are to be created and installed. + +AC_SUBST(TARGET_LIBS) + +dnl If shared library creation has been configured, add shared +dnl libraries to the list of libraries to be built. + +if test "$LINK_SHARED"_ != "_"; then + TARGET_LIBS="static shared" +else + TARGET_LIBS="static" + LINK_SHARED="@:" +fi + +dnl The following directive must always be the last line of any +dnl autoconf script. It causes autoconf to create the configure +dnl script, which for each argument of AC_OUTPUT, will look for a +dnl filename formed by appending ".in" to the argument, preprocess +dnl that file, replacing @VAR@ directives with the corresponding value +dnl of the specified shell variable VAR, as set above in this file, +dnl and write the resulting output to the filename given in the +dnl argument. Note that only shell variables that were exported above +dnl with the AC_SUBST() directive will be substituted in @VAR@ +dnl directives (some macros like AC_PROG_CC also call AC_SUBST for you +dnl for the variables that they output). + +AC_OUTPUT(Makefile) diff --git a/libtecla-1.4.1/cplfile.c b/libtecla-1.4.1/cplfile.c new file mode 100644 index 0000000..73eef1d --- /dev/null +++ b/libtecla-1.4.1/cplfile.c @@ -0,0 +1,874 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Standard includes. + */ +#include +#include +#include +#include +#include +#include + +/* + * Local includes. + */ +#include "libtecla.h" +#include "direader.h" +#include "homedir.h" +#include "pathutil.h" +#include "cplfile.h" + +/* + * Set the maximum length allowed for usernames. + * names. + */ +#define USR_LEN 100 + +/* + * Set the maximum length allowed for environment variable names. + */ +#define ENV_LEN 100 + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +/* + * The resources needed to complete a filename are maintained in objects + * of the following type. + */ +struct CompleteFile { + DirReader *dr; /* A directory reader */ + HomeDir *home; /* A home directory expander */ + PathName *path; /* The buffer in which to accumulate the path */ + PathName *buff; /* A pathname work buffer */ + char usrnam[USR_LEN+1]; /* The buffer used when reading the names of */ + /* users. */ + char envnam[ENV_LEN+1]; /* The buffer used when reading the names of */ + /* environment variables. */ + char errmsg[ERRLEN+1]; /* The error-report buffer */ +}; + +static int cf_expand_home_dir(CompleteFile *cf, const char *user); +static int cf_complete_username(CompleteFile *cf, WordCompletion *cpl, + const char *prefix, const char *line, + int word_start, int word_end, int escaped); +static HOME_DIR_FN(cf_homedir_callback); +static int cf_complete_entry(CompleteFile *cf, WordCompletion *cpl, + const char *line, int word_start, int word_end, + int escaped, CplCheckFn *check_fn, + void *check_data); +static char *cf_read_name(CompleteFile *cf, const char *type, + const char *string, int slen, + char *nambuf, int nammax); +static int cf_prepare_suffix(CompleteFile *cf, const char *suffix, + int add_escapes); + +/* + * A stack based object of the following type is used to pass data to the + * cf_homedir_callback() function. + */ +typedef struct { + CompleteFile *cf; /* The file-completion resource object */ + WordCompletion *cpl; /* The string-completion rsource object */ + const char *prefix; /* The username prefix to be completed */ + const char *line; /* The line from which the prefix was extracted */ + int word_start; /* The index in line[] of the start of the username */ + int word_end; /* The index in line[] following the end of the prefix */ + int escaped; /* If true, add escapes to the completion suffixes */ +} CfHomeArgs; + +/*....................................................................... + * Create a new file-completion object. + * + * Output: + * return CompleteFile * The new object, or NULL on error. + */ +CompleteFile *_new_CompleteFile(void) +{ + CompleteFile *cf; /* The object to be returned */ +/* + * Allocate the container. + */ + cf = (CompleteFile *) malloc(sizeof(CompleteFile)); + if(!cf) { + fprintf(stderr, "_new_CompleteFile: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_CompleteFile(). + */ + cf->dr = NULL; + cf->home = NULL; + cf->path = NULL; + cf->buff = NULL; + cf->usrnam[0] = '\0'; + cf->envnam[0] = '\0'; + cf->errmsg[0] = '\0'; +/* + * Create the object that is used for reading directories. + */ + cf->dr = _new_DirReader(); + if(!cf->dr) + return _del_CompleteFile(cf); +/* + * Create the object that is used to lookup home directories. + */ + cf->home = _new_HomeDir(); + if(!cf->home) + return _del_CompleteFile(cf); +/* + * Create the buffer in which the completed pathname is accumulated. + */ + cf->path = _new_PathName(); + if(!cf->path) + return _del_CompleteFile(cf); +/* + * Create a pathname work buffer. + */ + cf->buff = _new_PathName(); + if(!cf->buff) + return _del_CompleteFile(cf); + return cf; +} + +/*....................................................................... + * Delete a file-completion object. + * + * Input: + * cf CompleteFile * The object to be deleted. + * Output: + * return CompleteFile * The deleted object (always NULL). + */ +CompleteFile *_del_CompleteFile(CompleteFile *cf) +{ + if(cf) { + cf->dr = _del_DirReader(cf->dr); + cf->home = _del_HomeDir(cf->home); + cf->path = _del_PathName(cf->path); + cf->buff = _del_PathName(cf->buff); + free(cf); + }; + return NULL; +} + +/*....................................................................... + * Look up the possible completions of the incomplete filename that + * lies between specified indexes of a given command-line string. + * + * Input: + * cpl WordCompletion * The object in which to record the completions. + * cf CompleteFile * The filename-completion resource object. + * line const char * The string containing the incomplete filename. + * word_start int The index of the first character in line[] + * of the incomplete filename. + * word_end int The index of the character in line[] that + * follows the last character of the incomplete + * filename. + * escaped int If true, backslashes in line[] are + * interpreted as escaping the characters + * that follow them, and any spaces, tabs, + * backslashes, or wildcard characters in the + * returned suffixes will be similarly escaped. + * If false, backslashes will be interpreted as + * literal parts of the file name, and no + * backslashes will be added to the returned + * suffixes. + * check_fn CplCheckFn * If not zero, this argument specifies a + * function to call to ask whether a given + * file should be included in the list + * of completions. + * check_data void * Anonymous data to be passed to check_fn(). + * Output: + * return int 0 - OK. + * 1 - Error. A description of the error can be + * acquired by calling _cf_last_error(cf). + */ +int _cf_complete_file(WordCompletion *cpl, CompleteFile *cf, + const char *line, int word_start, int word_end, + int escaped, CplCheckFn *check_fn, void *check_data) +{ + const char *lptr; /* A pointer into line[] */ + int nleft; /* The number of characters still to be processed */ + /* in line[]. */ +/* + * Check the arguments. + */ + if(!cpl || !cf || !line || word_end < word_start) { + if(cf) + strcpy(cf->errmsg, "_cf_complete_file: Invalid arguments"); + return 1; + }; +/* + * Clear the buffer in which the filename will be constructed. + */ + _pn_clear_path(cf->path); +/* + * How many characters are to be processed? + */ + nleft = word_end - word_start; +/* + * Get a pointer to the start of the incomplete filename. + */ + lptr = line + word_start; +/* + * If the first character is a tilde, then perform home-directory + * interpolation. + */ + if(nleft > 0 && *lptr == '~') { + int slen; + if(!cf_read_name(cf, "User", ++lptr, --nleft, cf->usrnam, USR_LEN)) + return 1; +/* + * Advance over the username in the input line. + */ + slen = strlen(cf->usrnam); + lptr += slen; + nleft -= slen; +/* + * If we haven't hit the end of the input string then we have a complete + * username to translate to the corresponding home directory. + */ + if(nleft > 0) { + if(cf_expand_home_dir(cf, cf->usrnam)) + return 1; +/* + * ~user and ~ are usually followed by a directory separator to + * separate them from the file contained in the home directory. + * If the home directory is the root directory, then we don't want + * to follow the home directory by a directory separator, so we should + * skip over it so that it doesn't get copied into the filename. + */ + if(strcmp(cf->path->name, FS_ROOT_DIR) == 0 && + strncmp(lptr, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { + lptr += FS_DIR_SEP_LEN; + nleft -= FS_DIR_SEP_LEN; + }; +/* + * If we have reached the end of the input string, then the username + * may be incomplete, and we should attempt to complete it. + */ + } else { +/* + * Look up the possible completions of the username. + */ + return cf_complete_username(cf, cpl, cf->usrnam, line, word_start+1, + word_end, escaped); + }; + }; +/* + * Copy the rest of the path, stopping to expand $envvar expressions + * where encountered. + */ + while(nleft > 0) { + int seglen; /* The length of the next segment to be copied */ +/* + * Find the length of the next segment to be copied, stopping if an + * unescaped '$' is seen, or the end of the path is reached. + */ + for(seglen=0; seglen < nleft; seglen++) { + int c = lptr[seglen]; + if(escaped && c == '\\') + seglen++; + else if(c == '$') + break; +/* + * We will be completing the last component of the file name, + * so whenever a directory separator is seen, assume that it + * might be the start of the last component, and mark the character + * that follows it as the start of the name that is to be completed. + */ + if(nleft >= FS_DIR_SEP_LEN && + strncmp(lptr + seglen, FS_DIR_SEP, FS_DIR_SEP_LEN)==0) { + word_start = (lptr + seglen) - line + FS_DIR_SEP_LEN; + }; + }; +/* + * We have reached either the end of the filename or the start of + * $environment_variable expression. Record the newly checked + * segment of the filename in the output filename, removing + * backslash-escapes where needed. + */ + if(_pn_append_to_path(cf->path, lptr, seglen, escaped) == NULL) { + strcpy(cf->errmsg, "Insufficient memory to complete filename"); + return 1; + }; + lptr += seglen; + nleft -= seglen; +/* + * If the above loop finished before we hit the end of the filename, + * then this was because an unescaped $ was seen. In this case, interpolate + * the value of the environment variable that follows it into the output + * filename. + */ + if(nleft > 0) { + char *value; /* The value of the environment variable */ + int vlen; /* The length of the value string */ + int nlen; /* The length of the environment variable name */ +/* + * Read the name of the environment variable. + */ + if(!cf_read_name(cf, "Environment", ++lptr, --nleft, cf->envnam, ENV_LEN)) + return 1; +/* + * Advance over the environment variable name in the input line. + */ + nlen = strlen(cf->envnam); + lptr += nlen; + nleft -= nlen; +/* + * Get the value of the environment variable. + */ + value = getenv(cf->envnam); + if(!value) { + const char *fmt = "Unknown environment variable: %.*s"; + sprintf(cf->errmsg, fmt, ERRLEN - strlen(fmt), cf->envnam); + return 1; + }; + vlen = strlen(value); +/* + * If we are at the start of the filename and the first character of the + * environment variable value is a '~', attempt home-directory + * interpolation. + */ + if(cf->path->name[0] == '\0' && value[0] == '~') { + if(!cf_read_name(cf, "User", value+1, vlen-1, cf->usrnam, USR_LEN) || + cf_expand_home_dir(cf, cf->usrnam)) + return 1; +/* + * If the home directory is the root directory, and the ~usrname expression + * was followed by a directory separator, prevent the directory separator + * from being appended to the root directory by skipping it in the + * input line. + */ + if(strcmp(cf->path->name, FS_ROOT_DIR) == 0 && + strncmp(lptr, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { + lptr += FS_DIR_SEP_LEN; + nleft -= FS_DIR_SEP_LEN; + }; + } else { +/* + * Append the value of the environment variable to the output path. + */ + if(_pn_append_to_path(cf->path, value, strlen(value), escaped)==NULL) { + strcpy(cf->errmsg, "Insufficient memory to complete filename"); + return 1; + }; +/* + * Prevent extra directory separators from being added. + */ + if(nleft >= FS_DIR_SEP_LEN && + strcmp(cf->path->name, FS_ROOT_DIR) == 0 && + strncmp(lptr, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { + lptr += FS_DIR_SEP_LEN; + nleft -= FS_DIR_SEP_LEN; + } else if(vlen > FS_DIR_SEP_LEN && + strcmp(value + vlen - FS_DIR_SEP_LEN, FS_DIR_SEP)==0) { + cf->path->name[vlen-FS_DIR_SEP_LEN] = '\0'; + }; + }; +/* + * If adding the environment variable didn't form a valid directory, + * we can't complete the line, since there is no way to separate append + * a partial filename to an environment variable reference without + * that appended part of the name being seen later as part of the + * environment variable name. Thus if the currently constructed path + * isn't a directory, quite now with no completions having been + * registered. + */ + if(!_pu_path_is_dir(cf->path->name)) + return 0; +/* + * For the reasons given above, if we have reached the end of the filename + * with the expansion of an environment variable, the only allowed + * completion involves the addition of a directory separator. + */ + if(nleft == 0) { + if(cpl_add_completion(cpl, line, lptr-line, word_end, FS_DIR_SEP, + "", "")) { + strncpy(cf->errmsg, cpl_last_error(cpl), ERRLEN); + cf->errmsg[ERRLEN] = '\0'; + return 1; + }; + return 0; + }; + }; + }; +/* + * Complete the filename if possible. + */ + return cf_complete_entry(cf, cpl, line, word_start, word_end, escaped, + check_fn, check_data); +} + +/*....................................................................... + * Return a description of the last path-completion error that occurred. + * + * Input: + * cf CompleteFile * The path-completion resource object. + * Output: + * return const char * The description of the last error. + */ +const char *_cf_last_error(CompleteFile *cf) +{ + return cf ? cf->errmsg : "NULL CompleteFile argument"; +} + +/*....................................................................... + * Lookup the home directory of the specified user, or the current user + * if no name is specified, appending it to output pathname. + * + * Input: + * cf CompleteFile * The pathname completion resource object. + * user const char * The username to lookup, or "" to lookup the + * current user. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int cf_expand_home_dir(CompleteFile *cf, const char *user) +{ +/* + * Attempt to lookup the home directory. + */ + const char *home_dir = _hd_lookup_home_dir(cf->home, user); +/* + * Failed? + */ + if(!home_dir) { + strncpy(cf->errmsg, _hd_last_home_dir_error(cf->home), ERRLEN); + cf->errmsg[ERRLEN] = '\0'; + return 1; + }; +/* + * Append the home directory to the pathname string. + */ + if(_pn_append_to_path(cf->path, home_dir, -1, 0) == NULL) { + strcpy(cf->errmsg, "Insufficient memory for home directory expansion"); + return 1; + }; + return 0; +} + +/*....................................................................... + * Lookup and report all completions of a given username prefix. + * + * Input: + * cf CompleteFile * The filename-completion resource object. + * cpl WordCompletion * The object in which to record the completions. + * prefix const char * The prefix of the usernames to lookup. + * line const char * The command-line in which the username appears. + * word_start int The index within line[] of the start of the + * username that is being completed. + * word_end int The index within line[] of the character which + * follows the incomplete username. + * escaped int True if the completions need to have special + * characters escaped. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int cf_complete_username(CompleteFile *cf, WordCompletion *cpl, + const char *prefix, const char *line, + int word_start, int word_end, int escaped) +{ +/* + * Set up a container of anonymous arguments to be sent to the + * username-lookup iterator. + */ + CfHomeArgs args; + args.cf = cf; + args.cpl = cpl; + args.prefix = prefix; + args.line = line; + args.word_start = word_start; + args.word_end = word_end; + args.escaped = escaped; +/* + * Iterate through the list of users, recording those which start + * with the specified prefix. + */ + if(_hd_scan_user_home_dirs(cf->home, &args, cf_homedir_callback)) { + strncpy(cf->errmsg, _hd_last_home_dir_error(cf->home), ERRLEN); + cf->errmsg[ERRLEN] = '\0'; + return 1; + }; + return 0; +} + +/*....................................................................... + * The user/home-directory scanner callback function (see homedir.h) + * used by cf_complete_username(). + */ +static HOME_DIR_FN(cf_homedir_callback) +{ +/* + * Get the file-completion resources from the anonymous data argument. + */ + CfHomeArgs *args = (CfHomeArgs *) data; + WordCompletion *cpl = args->cpl; + CompleteFile *cf = args->cf; +/* + * Get the length of the username prefix. + */ + int prefix_len = strlen(args->prefix); +/* + * Get the length of the latest user name that is to be compared to + * the prefix. + */ + int name_len = strlen(usrnam); +/* + * See if the latest username starts with the prefix that we are + * searching for, and record its suffix in the array of matches if so. + */ + if(name_len >= prefix_len && strncmp(args->prefix, usrnam, prefix_len)==0) { +/* + * Copy the username into the pathname work buffer, adding backslash + * escapes where needed. + */ + if(cf_prepare_suffix(cf, usrnam+prefix_len, args->escaped)) { + strncpy(errmsg, cf->errmsg, maxerr); + errmsg[maxerr] = '\0'; + return 1; + }; +/* + * Report the completion suffix that was copied above. + */ + if(cpl_add_completion(cpl, args->line, args->word_start, args->word_end, + cf->buff->name, FS_DIR_SEP, FS_DIR_SEP)) { + strncpy(errmsg, cpl_last_error(cpl), maxerr); + errmsg[maxerr] = '\0'; + return 1; + }; + }; + return 0; +} + +/*....................................................................... + * Report possible completions of the filename in cf->path->name[]. + * + * Input: + * cf CompleteFile * The file-completion resource object. + * cpl WordCompletion * The object in which to record the completions. + * line const char * The input line, as received by the callback + * function. + * word_start int The index within line[] of the start of the + * last component of the filename that is being + * completed. + * word_end int The index within line[] of the character which + * follows the incomplete filename. + * escaped int If true, escape special characters in the + * completion suffixes. + * check_fn CplCheckFn * If not zero, this argument specifies a + * function to call to ask whether a given + * file should be included in the list + * of completions. + * check_data void * Anonymous data to be passed to check_fn(). + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int cf_complete_entry(CompleteFile *cf, WordCompletion *cpl, + const char *line, int word_start, int word_end, + int escaped, CplCheckFn *check_fn, + void *check_data) +{ + const char *dirpath; /* The name of the parent directory */ + int start; /* The index of the start of the last filename */ + /* component in the transcribed filename. */ + const char *prefix; /* The filename prefix to be completed */ + int prefix_len; /* The length of the filename prefix */ + const char *file_name; /* The lastest filename being compared */ + int waserr = 0; /* True after errors */ + int terminated=0; /* True if the directory part had to be terminated */ +/* + * Get the pathname string and its current length. + */ + char *pathname = cf->path->name; + int pathlen = strlen(pathname); +/* + * Locate the start of the final component of the pathname. + */ + for(start=pathlen - 1; start >= 0 && + strncmp(pathname + start, FS_DIR_SEP, FS_DIR_SEP_LEN) != 0; start--) + ; +/* + * Is the parent directory the root directory? + */ + if(start==0 || + (start < 0 && strncmp(pathname, FS_ROOT_DIR, FS_ROOT_DIR_LEN) == 0)) { + dirpath = FS_ROOT_DIR; + start += FS_ROOT_DIR_LEN; +/* + * If we found a directory separator then the part which precedes the + * last component is the name of the directory to be opened. + */ + } else if(start > 0) { +/* + * The _dr_open_dir() function requires the directory name to be '\0' + * terminated, so temporarily do this by overwriting the first character + * of the directory separator. + */ + pathname[start] = '\0'; + dirpath = pathname; + terminated = 1; +/* + * We reached the start of the pathname before finding a directory + * separator, so arrange to open the current working directory. + */ + } else { + start = 0; + dirpath = FS_PWD; + }; +/* + * Attempt to open the directory. + */ + if(_dr_open_dir(cf->dr, dirpath, NULL)) { + const char *fmt = "Can't open directory: %.*s"; + sprintf(cf->errmsg, fmt, ERRLEN - strlen(fmt), dirpath); + return 1; + }; +/* + * If removed above, restore the directory separator and skip over it + * to the start of the filename. + */ + if(terminated) { + memcpy(pathname + start, FS_DIR_SEP, FS_DIR_SEP_LEN); + start += FS_DIR_SEP_LEN; + }; +/* + * Get the filename prefix and its length. + */ + prefix = pathname + start; + prefix_len = strlen(prefix); +/* + * Traverse the directory, looking for files who's prefixes match the + * last component of the pathname. + */ + while((file_name = _dr_next_file(cf->dr)) != NULL && !waserr) { + int name_len = strlen(file_name); +/* + * Is the latest filename a possible completion of the filename prefix? + */ + if(name_len >= prefix_len && strncmp(prefix, file_name, prefix_len)==0) { +/* + * When listing all files in a directory, don't list files that start + * with '.'. This is how hidden files are denoted in UNIX. + */ + if(prefix_len > 0 || file_name[0] != '.') { +/* + * Copy the completion suffix into the work pathname cf->buff->name, + * adding backslash escapes if needed. + */ + if(cf_prepare_suffix(cf, file_name + prefix_len, escaped)) { + waserr = 1; + } else { +/* + * We want directories to be displayed with directory suffixes, + * and other fully completed filenames to be followed by spaces. + * To check the type of the file, append the current suffix + * to the path being completed, check the filetype, then restore + * the path to its original form. + */ + const char *cont_suffix = ""; /* The suffix to add if fully */ + /* completed. */ + const char *type_suffix = ""; /* The suffix to add when listing */ + if(_pn_append_to_path(cf->path, file_name + prefix_len, + -1, escaped) == NULL) { + strcpy(cf->errmsg, "Insufficient memory to complete filename."); + return 1; + }; +/* + * Specify suffixes according to the file type. + */ + if(_pu_path_is_dir(cf->path->name)) { + cont_suffix = FS_DIR_SEP; + type_suffix = FS_DIR_SEP; + } else if(!check_fn || check_fn(check_data, cf->path->name)) { + cont_suffix = " "; + } else { + cf->path->name[pathlen] = '\0'; + continue; + }; +/* + * Remove the temporarily added suffix. + */ + cf->path->name[pathlen] = '\0'; +/* + * Record the latest completion. + */ + if(cpl_add_completion(cpl, line, word_start, word_end, cf->buff->name, + type_suffix, cont_suffix)) + waserr = 1; + }; + }; + }; + }; +/* + * Close the directory. + */ + _dr_close_dir(cf->dr); + return waserr; +} + +/*....................................................................... + * Read a username or environment variable name, stopping when a directory + * separator is seen, when the end of the string is reached, or the + * output buffer overflows. + * + * Input: + * cf CompleteFile * The file-completion resource object. + * type char * The capitalized name of the type of name being read. + * string char * The string who's prefix contains the name. + * slen int The number of characters in string[]. + * nambuf char * The output name buffer. + * nammax int The longest string that will fit in nambuf[], excluding + * the '\0' terminator. + * Output: + * return char * A pointer to nambuf on success. On error NULL is + * returned and a description of the error is recorded + * in cf->errmsg[]. + */ +static char *cf_read_name(CompleteFile *cf, const char *type, + const char *string, int slen, + char *nambuf, int nammax) +{ + int namlen; /* The number of characters in nambuf[] */ + const char *sptr; /* A pointer into string[] */ +/* + * Work out the max number of characters that should be copied. + */ + int nmax = nammax < slen ? nammax : slen; +/* + * Get the environment variable name that follows the dollar. + */ + for(sptr=string,namlen=0; + namlen < nmax && (slen-namlen < FS_DIR_SEP_LEN || + strncmp(sptr, FS_DIR_SEP, FS_DIR_SEP_LEN) != 0); + namlen++) { + nambuf[namlen] = *sptr++; + }; +/* + * Did the name overflow the buffer? + */ + if(namlen >= nammax) { + const char *fmt = "%.*s name too long"; + sprintf(cf->errmsg, fmt, ERRLEN - strlen(fmt), type); + return NULL; + }; +/* + * Terminate the string. + */ + nambuf[namlen] = '\0'; + return nambuf; +} + +/*....................................................................... + * Using the work buffer cf->buff, make a suitably escaped copy of a + * given completion suffix, ready to be passed to cpl_add_completion(). + * + * Input: + * cf CompleteFile * The file-completion resource object. + * suffix char * The suffix to be copied. + * add_escapes int If true, escape special characters. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int cf_prepare_suffix(CompleteFile *cf, const char *suffix, + int add_escapes) +{ + const char *sptr; /* A pointer into suffix[] */ + int nbsl; /* The number of backslashes to add to the suffix */ + int i; +/* + * How long is the suffix? + */ + int suffix_len = strlen(suffix); +/* + * Clear the work buffer. + */ + _pn_clear_path(cf->buff); +/* + * Count the number of backslashes that will have to be added to + * escape spaces, tabs, backslashes and wildcard characters. + */ + nbsl = 0; + if(add_escapes) { + for(sptr = suffix; *sptr; sptr++) { + switch(*sptr) { + case ' ': case '\t': case '\\': case '*': case '?': case '[': + nbsl++; + break; + }; + }; + }; +/* + * Arrange for the output path buffer to have sufficient room for the + * both the suffix and any backslashes that have to be inserted. + */ + if(_pn_resize_path(cf->buff, suffix_len + nbsl) == NULL) { + strcpy(cf->errmsg, "Insufficient memory to complete filename"); + return 1; + }; +/* + * If the suffix doesn't need any escapes, copy it directly into the + * work buffer. + */ + if(nbsl==0) { + strcpy(cf->buff->name, suffix); + } else { +/* + * Make a copy with special characters escaped? + */ + if(nbsl > 0) { + const char *src = suffix; + char *dst = cf->buff->name; + for(i=0; i +#include +#include + +/* + * Local includes. + */ +#include "libtecla.h" +#include "stringrp.h" +#include "pathutil.h" +#include "cplfile.h" + +/* + * Specify the number of strings to allocate when the string free-list + * is exhausted. This also sets the number of elements to expand the + * matches[] array by whenever it is found to be too small. + */ +#define STR_BLK_FACT 100 + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so don't decrease it below 80. + */ +#define ERRLEN 200 + +/* + * Completion matches are recorded in containers of the following + * type. + */ +struct WordCompletion { + StringGroup *sg; /* Memory for a group of strings */ + int matches_dim; /* The allocated size of result.matches[] */ + char errmsg[ERRLEN+1]; /* The error-reporting buffer */ + CplMatches result; /* Completions to be returned to the caller */ + CompleteFile *cf; /* The resources used for filename completion */ +}; + +static void cpl_sort_matches(WordCompletion *cpl); +static void cpl_zap_duplicates(WordCompletion *cpl); +static void cpl_clear_completions(WordCompletion *cpl); +static int cpl_cmp_matches(const void *v1, const void *v2); +static int cpl_cmp_suffixes(const void *v1, const void *v2); + +/* + * The new_CplFileConf() constructor sets the integer first member of + * the returned object to the following magic number. On seeing this, + * cpl_file_completions() knows when it is passed a valid CplFileConf + * object. + */ +#define CFC_ID_CODE 4568 + +/* + * A pointer to a structure of the following type can be passed to + * the builtin file-completion callback function to modify its behavior. + */ +struct CplFileConf { + int id; /* new_CplFileConf() sets this to CFC_ID_CODE */ + int escaped; /* If none-zero, backslashes in the input line are */ + /* interpreted as escaping special characters and */ + /* spaces, and any special characters and spaces in */ + /* the listed completions will also be escaped with */ + /* added backslashes. This is the default behaviour. */ + /* If zero, backslashes are interpreted as being */ + /* literal parts of the filename, and none are added */ + /* to the completion suffixes. */ + int file_start; /* The index in the input line of the first character */ + /* of the filename. If you specify -1 here, */ + /* cpl_file_completions() identifies the */ + /* the start of the filename by looking backwards for */ + /* an unescaped space, or the beginning of the line. */ + CplCheckFn *chk_fn; /* If not zero, this argument specifies a */ + /* function to call to ask whether a given */ + /* file should be included in the list */ + /* of completions. */ + void *chk_data; /* Anonymous data to be passed to check_fn(). */ +}; + +static void cpl_init_FileConf(CplFileConf *cfc); + +/*....................................................................... + * Create a new string-completion object. + * + * Output: + * return WordCompletion * The new object, or NULL on error. + */ +WordCompletion *new_WordCompletion(void) +{ + WordCompletion *cpl; /* The object to be returned */ +/* + * Allocate the container. + */ + cpl = (WordCompletion *) malloc(sizeof(WordCompletion)); + if(!cpl) { + fprintf(stderr, "new_WordCompletion: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_WordCompletion(). + */ + cpl->sg = NULL; + cpl->matches_dim = 0; + cpl->result.suffix = NULL; + cpl->result.cont_suffix = NULL; + cpl->result.matches = NULL; + cpl->result.nmatch = 0; + cpl->cf = NULL; +/* + * Allocate an object that allows a group of strings to be allocated + * efficiently by placing many of them in contiguous string segments. + */ + cpl->sg = _new_StringGroup(_pu_pathname_dim()); + if(!cpl->sg) + return del_WordCompletion(cpl); +/* + * Allocate an array for matching completions. This will be extended later + * if needed. + */ + cpl->matches_dim = STR_BLK_FACT; + cpl->result.matches = (CplMatch *) malloc(sizeof(cpl->result.matches[0]) * + cpl->matches_dim); + if(!cpl->result.matches) { + fprintf(stderr, + "new_WordCompletion: Insufficient memory to allocate array of matches.\n"); + return del_WordCompletion(cpl); + }; +/* + * Allocate a filename-completion resource object. + */ + cpl->cf = _new_CompleteFile(); + if(!cpl->cf) + return del_WordCompletion(cpl); + return cpl; +} + +/*....................................................................... + * Delete a string-completion object. + * + * Input: + * cpl WordCompletion * The object to be deleted. + * Output: + * return WordCompletion * The deleted object (always NULL). + */ +WordCompletion *del_WordCompletion(WordCompletion *cpl) +{ + if(cpl) { + cpl->sg = _del_StringGroup(cpl->sg); + if(cpl->result.matches) { + free(cpl->result.matches); + cpl->result.matches = NULL; + cpl->cf = _del_CompleteFile(cpl->cf); + }; + free(cpl); + }; + return NULL; +} + +/*....................................................................... + * This function is designed to be called by CplMatchFn callback + * functions. It adds one possible completion of the token that is being + * completed to an array of completions. If the completion needs any + * special quoting to be valid when displayed in the input line, this + * quoting must be included in the string. + * + * Input: + * cpl WordCompletion * The argument of the same name that was passed + * to the calling CplMatchFn callback function. + * line const char * The input line, as received by the callback + * function. + * word_start int The index within line[] of the start of the + * word that is being completed. + * word_end int The index within line[] of the character which + * follows the incomplete word, as received by the + * calling callback function. + * suffix const char * The appropriately quoted string that could + * be appended to the incomplete token to complete + * it. A copy of this string will be allocated + * internally. + * type_suffix const char * When listing multiple completions, gl_get_line() + * appends this string to the completion to indicate + * its type to the user. If not pertinent pass "". + * Otherwise pass a literal or static string. + * cont_suffix const char * If this turns out to be the only completion, + * gl_get_line() will append this string as + * a continuation. For example, the builtin + * file-completion callback registers a directory + * separator here for directory matches, and a + * space otherwise. If the match were a function + * name you might want to append an open + * parenthesis, etc.. If not relevant pass "". + * Otherwise pass a literal or static string. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int cpl_add_completion(WordCompletion *cpl, const char *line, + int word_start, int word_end, const char *suffix, + const char *type_suffix, const char *cont_suffix) +{ + CplMatch *match; /* The container of the new match */ + char *string; /* A newly allocated copy of the completion string */ +/* + * Check the arguments. + */ + if(!cpl) + return 1; + if(!suffix) + return 0; + if(!type_suffix) + type_suffix = ""; + if(!cont_suffix) + cont_suffix = ""; +/* + * Do we need to extend the array of matches[]? + */ + if(cpl->result.nmatch+1 > cpl->matches_dim) { + int needed = cpl->matches_dim + STR_BLK_FACT; + CplMatch *matches = (CplMatch *) realloc(cpl->result.matches, + sizeof(cpl->result.matches[0]) * needed); + if(!matches) { + strcpy(cpl->errmsg, "Insufficient memory to extend array of matches."); + return 1; + }; + cpl->result.matches = matches; + cpl->matches_dim = needed; + }; +/* + * Allocate memory to store the combined completion prefix and the + * new suffix. + */ + string = _sg_alloc_string(cpl->sg, word_end-word_start + strlen(suffix)); + if(!string) { + strcpy(cpl->errmsg, "Insufficient memory to extend array of matches."); + return 1; + }; +/* + * Compose the string. + */ + strncpy(string, line + word_start, word_end - word_start); + strcpy(string + word_end - word_start, suffix); +/* + * Record the new match. + */ + match = cpl->result.matches + cpl->result.nmatch++; + match->completion = string; + match->suffix = string + word_end - word_start; + match->type_suffix = type_suffix; +/* + * Record the continuation suffix. + */ + cpl->result.cont_suffix = cont_suffix; + return 0; +} + +/*....................................................................... + * Sort the array of matches. + * + * Input: + * cpl WordCompletion * The completion resource object. + */ +static void cpl_sort_matches(WordCompletion *cpl) +{ + qsort(cpl->result.matches, cpl->result.nmatch, + sizeof(cpl->result.matches[0]), cpl_cmp_matches); +} + +/*....................................................................... + * This is a qsort() comparison function used to sort matches. + * + * Input: + * v1, v2 void * Pointers to the two matches to be compared. + * Output: + * return int -1 -> v1 < v2. + * 0 -> v1 == v2 + * 1 -> v1 > v2 + */ +static int cpl_cmp_matches(const void *v1, const void *v2) +{ + const CplMatch *m1 = (const CplMatch *) v1; + const CplMatch *m2 = (const CplMatch *) v2; + return strcmp(m1->completion, m2->completion); +} + +/*....................................................................... + * Sort the array of matches in order of their suffixes. + * + * Input: + * cpl WordCompletion * The completion resource object. + */ +static void cpl_sort_suffixes(WordCompletion *cpl) +{ + qsort(cpl->result.matches, cpl->result.nmatch, + sizeof(cpl->result.matches[0]), cpl_cmp_suffixes); +} + +/*....................................................................... + * This is a qsort() comparison function used to sort matches in order of + * their suffixes. + * + * Input: + * v1, v2 void * Pointers to the two matches to be compared. + * Output: + * return int -1 -> v1 < v2. + * 0 -> v1 == v2 + * 1 -> v1 > v2 + */ +static int cpl_cmp_suffixes(const void *v1, const void *v2) +{ + const CplMatch *m1 = (const CplMatch *) v1; + const CplMatch *m2 = (const CplMatch *) v2; + return strcmp(m1->suffix, m2->suffix); +} + +/*....................................................................... + * Find the common prefix of all of the matching completion matches, + * and record a pointer to it in cpl->result.suffix. Note that this has + * the side effect of sorting the matches into suffix order. + * + * Input: + * cpl WordCompletion * The completion resource object. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int cpl_common_suffix(WordCompletion *cpl) +{ + CplMatches *result; /* The result container */ + const char *first, *last; /* The first and last matching suffixes */ + int length; /* The length of the common suffix */ +/* + * Get the container of the array of matching files. + */ + result = &cpl->result; +/* + * No matching completions? + */ + if(result->nmatch < 1) + return 0; +/* + * Sort th matches into suffix order. + */ + cpl_sort_suffixes(cpl); +/* + * Given that the array of matches is sorted, the first and last + * suffixes are those that differ most in their prefixes, so the common + * prefix of these strings is the longest common prefix of all of the + * suffixes. + */ + first = result->matches[0].suffix; + last = result->matches[result->nmatch - 1].suffix; +/* + * Find the point at which the first and last matching strings + * first difffer. + */ + while(*first && *first == *last) { + first++; + last++; + }; +/* + * How long is the common suffix? + */ + length = first - result->matches[0].suffix; +/* + * Allocate memory to record the common suffix. + */ + result->suffix = _sg_alloc_string(cpl->sg, length); + if(!result->suffix) { + strcpy(cpl->errmsg, + "Insufficient memory to record common completion suffix."); + return 1; + }; +/* + * Record the common suffix. + */ + strncpy(result->suffix, result->matches[0].suffix, length); + result->suffix[length] = '\0'; + return 0; +} + +/*....................................................................... + * Discard the contents of the array of possible completion matches. + * + * Input: + * cpl WordCompletion * The word-completion resource object. + */ +static void cpl_clear_completions(WordCompletion *cpl) +{ +/* + * Discard all of the strings. + */ + _clr_StringGroup(cpl->sg); +/* + * Record the fact that the array is now empty. + */ + cpl->result.nmatch = 0; + cpl->result.suffix = NULL; + cpl->result.cont_suffix = ""; +/* + * Also clear the error message. + */ + cpl->errmsg[0] = '\0'; + return; +} + +/*....................................................................... + * Given an input line and the point at which it completion is to be + * attempted, return an array of possible completions. + * + * Input: + * cpl WordCompletion * The completion resource object. + * line char * The current input line. + * word_end int The index of the character in line[] which + * follows the end of the token that is being + * completed. + * data void * Anonymous 'data' to be passed to match_fn(). + * match_fn CplMatchFn * The function that will identify the prefix + * to be completed from the input line, and + * record completion matches. + * Output: + * return CplMatches * The container of the array of possible + * completions. The returned pointer refers + * to a container owned by the parent WordCompletion + * object, and its contents thus potentially + * change on every call to cpl_matches(). + * On error, NULL is returned, and a description + * of the error can be acquired by calling + * cpl_last_error(cpl). + */ +CplMatches *cpl_complete_word(WordCompletion *cpl, const char *line, + int word_end, void *data, + CplMatchFn *match_fn) +{ + int line_len; /* The total length of the input line */ +/* + * How long is the input line? + */ + line_len = strlen(line); +/* + * Check the arguments. + */ + if(!cpl || !line || !match_fn || word_end < 0 || word_end > line_len) { + if(cpl) + strcpy(cpl->errmsg, "cpl_complete_word: Invalid arguments."); + return NULL; + }; +/* + * Clear the return container. + */ + cpl_clear_completions(cpl); +/* + * Have the matching function record possible completion matches in + * cpl->result.matches. + */ + if(match_fn(cpl, data, line, word_end)) { + if(cpl->errmsg[0] == '\0') + strcpy(cpl->errmsg, "Error completing word."); + return NULL; + }; +/* + * Record a copy of the common initial part of all of the prefixes + * in cpl->result.common. + */ + if(cpl_common_suffix(cpl)) + return NULL; +/* + * Sort the matches into lexicographic order. + */ + cpl_sort_matches(cpl); +/* + * Discard any duplicate matches. + */ + cpl_zap_duplicates(cpl); +/* + * If there is more than one match, discard the continuation suffix. + */ + if(cpl->result.nmatch > 1) + cpl->result.cont_suffix = ""; +/* + * Return the array of matches. + */ + return &cpl->result; +} + +/*....................................................................... + * Print out an array of matching completions. + * + * Input: + * result CplMatches * The container of the sorted array of + * completions. + * fp FILE * The output stream to write to. + * term_width int The width of the terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int cpl_list_completions(CplMatches *result, FILE *fp, int term_width) +{ + int maxlen; /* The length of the longest matching string */ + int width; /* The width of a column */ + int ncol; /* The number of columns to list */ + int nrow; /* The number of rows needed to list all of the matches */ + int row,col; /* The row and column being written to */ + int i; +/* + * Check the arguments. + */ + if(!result || !fp) { + fprintf(stderr, "cpl_list_completions: NULL argument(s).\n"); + return 1; + }; +/* + * Not enough space to list anything? + */ + if(term_width < 1) + return 0; +/* + * Work out the maximum length of the matching strings. + */ + maxlen = 0; + for(i=0; inmatch; i++) { + CplMatch *match = result->matches + i; + int len = strlen(match->completion) + + strlen(match->type_suffix); + if(len > maxlen) + maxlen = len; + }; +/* + * Nothing to list? + */ + if(maxlen == 0) + return 0; +/* + * Split the available terminal width into columns of maxlen + 2 characters. + */ + width = maxlen + 2; + ncol = term_width / width; +/* + * If the column width is greater than the terminal width, the matches will + * just have to overlap onto the next line. + */ + if(ncol < 1) + ncol = 1; +/* + * How many rows will be needed? + */ + nrow = (result->nmatch + ncol - 1) / ncol; +/* + * Print the matches out in ncol columns, sorted in row order within each + * column. + */ + for(row=0; row < nrow; row++) { + for(col=0; col < ncol; col++) { + int m = col*nrow + row; + if(m < result->nmatch) { + CplMatch *match = result->matches + m; + if(fprintf(fp, "%s%-*s%s", match->completion, + (int) (ncol > 1 ? maxlen - strlen(match->completion):0), + match->type_suffix, colerrmsg : "NULL WordCompletion argument"; +} + +/*....................................................................... + * When an error occurs while performing a completion, you registerf a + * terse description of the error by calling cpl_record_error(). This + * message will then be returned on the next call to cpl_last_error(). + * + * Input: + * cpl WordCompletion * The string-completion resource object that was + * originally passed to the callback. + * errmsg const char * The description of the error. + */ +void cpl_record_error(WordCompletion *cpl, const char *errmsg) +{ + if(cpl && errmsg) { + strncpy(cpl->errmsg, errmsg, ERRLEN); + cpl->errmsg[ERRLEN] = '\0'; + }; +} + +/*....................................................................... + * This is the builtin completion callback function which performs file + * completion. + * + * Input: + * cpl WordCompletion * An opaque pointer to the object that will + * contain the matches. This should be filled + * via zero or more calls to cpl_add_completion(). + * data void * Either NULL to request the default + * file-completion behavior, or a pointer to a + * CplFileConf structure, whose members specify + * a different behavior. + * line char * The current input line. + * word_end int The index of the character in line[] which + * follows the end of the token that is being + * completed. + * Output + * return int 0 - OK. + * 1 - Error. + */ +CPL_MATCH_FN(cpl_file_completions) +{ + const char *start_path; /* The pointer to the start of the pathname */ + /* in line[]. */ + CplFileConf *conf; /* The new-style configuration object. */ +/* + * The following configuration object will be used if the caller didn't + * provide one. + */ + CplFileConf default_conf; +/* + * This function can be called externally, so check its arguments. + */ + if(!cpl) + return 1; + if(!line || word_end < 0) { + strcpy(cpl->errmsg, "cpl_file_completions: Invalid arguments."); + return 1; + }; +/* + * The 'data' argument is either a CplFileConf pointer, identifiable + * by having an integer id code as its first member, or the deprecated + * CplFileArgs pointer, or can be NULL to request the default + * configuration. + */ + if(data && *(int *)data == CFC_ID_CODE) { + conf = (CplFileConf *) data; + } else { +/* + * Select the defaults. + */ + conf = &default_conf; + cpl_init_FileConf(&default_conf); +/* + * If we have been passed an instance of the deprecated CplFileArgs + * structure, copy its configuration parameters over the defaults. + */ + if(data) { + CplFileArgs *args = (CplFileArgs *) data; + conf->escaped = args->escaped; + conf->file_start = args->file_start; + }; + }; +/* + * Get the start of the filename. If not specified by the caller + * identify it by searching backwards in the input line for an + * unescaped space or the start of the line. + */ + if(conf->file_start < 0) { + start_path = _pu_start_of_path(line, word_end); + if(!start_path) { + strcpy(cpl->errmsg, "Unable to find the start of the filename."); + return 1; + }; + } else { + start_path = line + conf->file_start; + }; +/* + * Perform the completion. + */ + if(_cf_complete_file(cpl, cpl->cf, line, start_path - line, word_end, + conf->escaped, conf->chk_fn, conf->chk_data)) { + cpl_record_error(cpl, _cf_last_error(cpl->cf)); + return 1; + }; + return 0; +} + +/*....................................................................... + * Initialize a CplFileArgs structure with default configuration + * parameters. Note that the CplFileArgs configuration type is + * deprecated. The opaque CplFileConf object should be used in future + * applications. + * + * Input: + * cfa CplFileArgs * The configuration object of the + * cpl_file_completions() callback. + */ +void cpl_init_FileArgs(CplFileArgs *cfa) +{ + if(cfa) { + cfa->escaped = 1; + cfa->file_start = -1; + }; +} + +/*....................................................................... + * Initialize a CplFileConf structure with default configuration + * parameters. + * + * Input: + * cfc CplFileConf * The configuration object of the + * cpl_file_completions() callback. + */ +static void cpl_init_FileConf(CplFileConf *cfc) +{ + if(cfc) { + cfc->id = CFC_ID_CODE; + cfc->escaped = 1; + cfc->file_start = -1; + cfc->chk_fn = 0; + cfc->chk_data = NULL; + }; +} + +/*....................................................................... + * Create a new CplFileConf object and initialize it with defaults. + * + * Output: + * return CplFileConf * The new object, or NULL on error. + */ +CplFileConf *new_CplFileConf(void) +{ + CplFileConf *cfc; /* The object to be returned */ +/* + * Allocate the container. + */ + cfc = (CplFileConf *)malloc(sizeof(CplFileConf)); + if(!cfc) + return NULL; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_CplFileConf(). + */ + cpl_init_FileConf(cfc); + return cfc; +} + +/*....................................................................... + * Delete a CplFileConf object. + * + * Input: + * cfc CplFileConf * The object to be deleted. + * Output: + * return CplFileConf * The deleted object (always NULL). + */ +CplFileConf *del_CplFileConf(CplFileConf *cfc) +{ + if(cfc) { +/* + * Delete the container. + */ + free(cfc); + }; + return NULL; +} + +/*....................................................................... + * If backslashes in the filename should be treated as literal + * characters, call the following function with literal=1. Otherwise + * the default is to treat them as escape characters, used for escaping + * spaces etc.. + * + * Input: + * cfc CplFileConf * The cpl_file_completions() configuration object + * to be configured. + * literal int Pass non-zero here to enable literal interpretation + * of backslashes. Pass 0 to turn off literal + * interpretation. + */ +void cfc_literal_escapes(CplFileConf *cfc, int literal) +{ + if(cfc) + cfc->escaped = !literal; +} + +/*....................................................................... + * Call this function if you know where the index at which the + * filename prefix starts in the input line. Otherwise by default, + * or if you specify start_index to be -1, the filename is taken + * to start after the first unescaped space preceding the cursor, + * or the start of the line, which ever comes first. + * + * Input: + * cfc CplFileConf * The cpl_file_completions() configuration object + * to be configured. + * start_index int The index of the start of the filename in + * the input line, or -1 to select the default. + */ +void cfc_file_start(CplFileConf *cfc, int start_index) +{ + if(cfc) + cfc->file_start = start_index; +} + +/*....................................................................... + * If you only want certain types of files to be included in the + * list of completions, you use the following function to specify a + * callback function which will be called to ask whether a given file + * should be included. + * + * Input: + * cfc CplFileConf * The cpl_file_completions() configuration object + * to be configured. + * chk_fn CplCheckFn * Zero to disable filtering, or a pointer to a + * function that returns 1 if a given file should + * be included in the list of completions. + * chk_data void * Anonymous data to be passed to chk_fn() + * every time that it is called. + */ +void cfc_set_check_fn(CplFileConf *cfc, CplCheckFn *chk_fn, void *chk_data) +{ + if(cfc) { + cfc->chk_fn = chk_fn; + cfc->chk_data = chk_data; + }; +} + +/*....................................................................... + * The following CplCheckFn callback returns non-zero if the specified + * filename is that of an executable. + */ +CPL_CHECK_FN(cpl_check_exe) +{ + return _pu_path_is_exe(pathname); +} + +/*....................................................................... + * Remove duplicates from a sorted array of matches. + * + * Input: + * cpl WordCompletion * The completion resource object. + */ +static void cpl_zap_duplicates(WordCompletion *cpl) +{ + CplMatch *matches; /* The array of matches */ + int nmatch; /* The number of elements in matches[] */ + const char *completion; /* The completion string of the last unique match */ + const char *type_suffix; /* The type of the last unique match */ + int src; /* The index of the match being considered */ + int dst; /* The index at which to record the next */ + /* unique match. */ +/* + * Get the array of matches and the number of matches that it + * contains. + */ + matches = cpl->result.matches; + nmatch = cpl->result.nmatch; +/* + * No matches? + */ + if(nmatch < 1) + return; +/* + * Initialize the comparison strings with the first match. + */ + completion = matches[0].completion; + type_suffix = matches[0].type_suffix; +/* + * Go through the array of matches, copying each new unrecorded + * match at the head of the array, while discarding duplicates. + */ + for(src=dst=1; srccompletion) != 0 || + strcmp(type_suffix, match->type_suffix) != 0) { + if(src != dst) + matches[dst] = *match; + dst++; + completion = match->completion; + type_suffix = match->type_suffix; + }; + }; +/* + * Record the number of unique matches that remain. + */ + cpl->result.nmatch = dst; + return; +} diff --git a/libtecla-1.4.1/demo.c b/libtecla-1.4.1/demo.c new file mode 100644 index 0000000..8bee92d --- /dev/null +++ b/libtecla-1.4.1/demo.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2000, 2001 by the California Institute of Technology. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "libtecla.h" + +int main(int argc, char *argv[]) +{ + char *line; /* A line of input */ + GetLine *gl; /* The line editor */ + int major,minor,micro; /* The version number of the library */ +/* + * Create the line editor, specifying a max line length of 500 bytes, + * and 10000 bytes to allocate to storage of historical input lines. + */ + gl = new_GetLine(500, 5000); + if(!gl) + return 1; +/* + * If the user has the LC_CTYPE or LC_ALL environment variables set, + * enable display of characters corresponding to the specified locale. + */ + (void) setlocale(LC_CTYPE, ""); +/* + * Lookup and display the version number of the library. + */ + libtecla_version(&major, &minor, µ); + printf("Welcome to the demo program of libtecla version %d.%d.%d\n", + major, minor, micro); +/* + * Load history. + */ + (void) gl_load_history(gl, "~/.demo_history", "#"); +/* + * Read lines of input from the user and print them to stdout. + */ + do { +/* + * Get a new line from the user. + */ + line = gl_get_line(gl, "$ ", NULL, 0); + if(!line) + break; +/* + * Display what was entered. + */ + if(printf("You entered: %s", line) < 0 || fflush(stdout)) + break; +/* + * If the user types "exit", quit the program. + */ + if(strcmp(line, "exit\n")==0) + break; + else if(strcmp(line, "history\n")==0) + gl_show_history(gl, stdout, "%N %T %H\n", 0, -1); + else if(strcmp(line, "size\n")==0) { + GlTerminalSize size = gl_terminal_size(gl, 80, 24); + printf("Terminal size = %d columns x %d lines.\n", size.ncolumn, + size.nline); + }; + } while(1); +/* + * Save historical command lines. + */ + (void) gl_save_history(gl, "~/.demo_history", "#", -1); +/* + * Clean up. + */ + gl = del_GetLine(gl); + return 0; +} + diff --git a/libtecla-1.4.1/demo2.c b/libtecla-1.4.1/demo2.c new file mode 100644 index 0000000..e1e80c6 --- /dev/null +++ b/libtecla-1.4.1/demo2.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "libtecla.h" + +/* + * Encapsulate the resources needed by this demo. + */ +typedef struct { + GetLine *gl; /* The line editor */ + PathCache *pc; /* A cache of executables in the user's path */ + PcaPathConf *ppc; /* The configuration argument of pca_path_completions() */ +} DemoRes; + +/* + * The following functions allocate and free instances of the above + * structure. + */ +static DemoRes *new_DemoRes(void); +static DemoRes *del_DemoRes(DemoRes *res); + +/* + * Search backwards for the start of a pathname. + */ +static char *start_of_path(const char *string, int back_from); + +/* + * Find the array indexes of the first character of the first + * space-delimited word in the specified string, and of the character + * that follows it. + */ +static int get_word_limits(const char *string, int *wa, int *wb); + +/* + * This is the demonstration completion callback function (defined below). + */ +static CPL_MATCH_FN(demo_cpl_fn); + +/*....................................................................... + * This demo takes no arguments. It reads lines of input until the + * word 'exit' is entered, or C-d is pressed. It replaces the default + * tab-completion callback with one which when invoked at the start of + * a line, looks up completions of commands in the user's execution + * path, and when invoked in other parts of the line, reverts to + * normal filename completion. Whenever a new line is entered, it + * extracts the first word on the line, looks it up in the user's + * execution path to see if it corresponds to a known executable file, + * and if so, displays the full pathname of the file, along with the + * remaining arguments. + */ +int main(int argc, char *argv[]) +{ + char *line; /* A line of input */ + DemoRes *res; /* The resources of the demo */ + int wa,wb; /* The delimiting indexes of a word in line[] */ + int major,minor,micro; /* The version number of the library */ +/* + * Allocate the resources needed by this demo. + */ + res = new_DemoRes(); + if(!res) + return 1; +/* + * If the user has the LC_CTYPE or LC_ALL environment variables set, + * enable display of characters corresponding to the specified locale. + */ + (void) setlocale(LC_CTYPE, ""); +/* + * Lookup and display the version number of the library. + */ + libtecla_version(&major, &minor, µ); + printf("Welcome to the demo2 program of libtecla version %d.%d.%d\n", + major, minor, micro); +/* + * Read lines of input from the user and print them to stdout. + */ + do { +/* + * Get a new line from the user. + */ + line = gl_get_line(res->gl, "$ ", NULL, 0); + if(!line) + break; +/* + * Work out the extent of the first word in the input line, and + * try to identify this as a command in the path, displaying the + * full pathname of the match if found. + */ + if(get_word_limits(line, &wa, &wb) == 0) { + char *cmd = pca_lookup_file(res->pc, line + wa, wb-wa, 0); + if(cmd) { + printf("Command=%s\n", cmd); + printf("Arguments=%s", line+wb); + } else { + printf("Command not found\n"); + }; + }; +/* + * If the user types "exit", quit the program. + */ + if(strcmp(line, "exit\n")==0) + break; + } while(1); +/* + * Clean up. + */ + res = del_DemoRes(res); + return 0; +} + +/*....................................................................... + * This completion callback searches for completions of executables in + * the user's path when invoked on a word at the start of the path, and + * performs normal filename completion elsewhere. + */ +static CPL_MATCH_FN(demo_cpl_fn) +{ +/* + * Get the resource object that was passed to gl_customize_completion(). + */ + DemoRes *res = (DemoRes *) data; +/* + * Find the start of the filename prefix to be completed, searching + * backwards for the first unescaped space, or the start of the line. + */ + char *start = start_of_path(line, word_end); +/* + * Skip spaces preceding the start of the prefix. + */ + while(start > line && isspace((int)(unsigned char) start[-1])) + start--; +/* + * If the filename prefix is at the start of the line, attempt + * to complete the filename as a command in the path. Otherwise + * perform normal filename completion. + */ + return (start == line) ? + pca_path_completions(cpl, res->ppc, line, word_end) : + cpl_file_completions(cpl, NULL, line, word_end); +} + +/*....................................................................... + * Search backwards for the potential start of a filename. This + * looks backwards from the specified index in a given string, + * stopping at the first unescaped space or the start of the line. + * + * Input: + * string const char * The string to search backwards in. + * back_from int The index of the first character in string[] + * that follows the pathname. + * Output: + * return char * The pointer to the first character of + * the potential pathname, or NULL on error. + */ +static char *start_of_path(const char *string, int back_from) +{ + int i, j; +/* + * Search backwards from the specified index. + */ + for(i=back_from-1; i>=0; i--) { + int c = string[i]; +/* + * Stop on unescaped spaces. + */ + if(isspace((int)(unsigned char)c)) { +/* + * The space can't be escaped if we are at the start of the line. + */ + if(i==0) + break; +/* + * Find the extent of the escape characters which precedes the space. + */ + for(j=i-1; j>=0 && string[j]=='\\'; j--) + ; +/* + * If there isn't an odd number of escape characters before the space, + * then the space isn't escaped. + */ + if((i - 1 - j) % 2 == 0) + break; + }; + }; + return (char *)string + i + 1; +} + +/*....................................................................... + * Create a new DemoRes object containing the resources needed by the + * demo. + * + * Output: + * return DemoRes * The new object, or NULL on error. + */ +static DemoRes *new_DemoRes(void) +{ + DemoRes *res; /* The object to be returned */ +/* + * Allocate the container. + */ + res = (DemoRes *)malloc(sizeof(DemoRes)); + if(!res) { + fprintf(stderr, "new_DemoRes: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_DemoRes(). + */ + res->gl = NULL; + res->pc = NULL; + res->ppc = NULL; +/* + * Create the line editor, specifying a max line length of 500 bytes, + * and 10000 bytes to allocate to storage of historical input lines. + */ + res->gl = new_GetLine(500, 10000); + if(!res->gl) + return del_DemoRes(res); +/* + * Enable text attribute formatting directives in prompt strings. + */ + gl_prompt_style(res->gl, GL_FORMAT_PROMPT); +/* + * Allocate a cache of the executable files found in the user's path. + */ + res->pc = new_PathCache(); + if(!res->pc) + return del_DemoRes(res); +/* + * Populate the cache with the contents of the user's path. + */ + if(pca_scan_path(res->pc, getenv("PATH"))) + return del_DemoRes(res); +/* + * Arrange for susequent calls to pca_lookup_file() and pca_path_completions() + * to only report files that are executable by the user. + */ + pca_set_check_fn(res->pc, cpl_check_exe, NULL); +/* + * Allocate a configuration object for use with pca_path_completions(). + */ + res->ppc = new_PcaPathConf(res->pc); + if(!res->ppc) + return del_DemoRes(res); +/* + * Replace the builtin filename completion callback with one which + * searches for completions of executables in the user's path when + * invoked on a word at the start of the path, and completes files + * elsewhere. + */ + if(gl_customize_completion(res->gl, res, demo_cpl_fn)) + return del_DemoRes(res); + return res; +} + +/*....................................................................... + * Delete a DemoRes object. + * + * Input: + * res DemoRes * The object to be deleted. + * Output: + * return DemoRes * The deleted object (always NULL). + */ +static DemoRes *del_DemoRes(DemoRes *res) +{ + if(res) { + res->gl = del_GetLine(res->gl); + res->pc = del_PathCache(res->pc); + res->ppc = del_PcaPathConf(res->ppc); + free(res); + }; + return NULL; +} + +/*....................................................................... + * Return the limits of the word at the start of a given string, ignoring + * leading white-space, and interpretting the first unescaped space, tab or + * the end of the line, as the end of the word. + * + * Input: + * string const char * The string to tokenize. + * Input/Output: + * wa,wb int * The indexes of the first character of the word, + * and the character which follows the last + * character of the word, will be assigned to + * *wa and *wb, respectively. + * Output: + * return int 0 - A word was found. + * 1 - No word was found before the end of the + * string. + */ +static int get_word_limits(const char *string, int *wa, int *wb) +{ + int escaped = 0; /* True if the next character is escaped */ +/* + * Skip leading white-space. + */ + for(*wa=0; isspace((int)(unsigned char)string[*wa]); (*wa)++) + ; +/* + * Find the first unescaped space, stopping early if the end of the + * string is reached. + */ + for(*wb = *wa; ; (*wb)++) { + int c = string[*wb]; + if(c=='\\') + escaped = !escaped; + else if((!escaped && isspace((int)(unsigned char)c)) || c=='\0') + break; + }; + return *wa == *wb; +} diff --git a/libtecla-1.4.1/direader.c b/libtecla-1.4.1/direader.c new file mode 100644 index 0000000..8a81fbf --- /dev/null +++ b/libtecla-1.4.1/direader.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Standard includes. + */ +#include +#include +#include +#include + +/* + * Operating system includes. + */ +#include +#include +#include +#include + +#include "direader.h" + +/* + * Use the reentrant POSIX threads version of readdir()? + */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L +#define USE_READDIR_R 1 +#endif + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +/* + * Objects of the following type are used to maintain the resources + * needed to read directories. + */ +struct DirReader { + DIR *dir; /* The directory stream (if open, NULL otherwise) */ + struct dirent *file; /* The latest directory entry */ + char errmsg[ERRLEN+1]; /* Error-report buffer */ +#ifdef USE_READDIR_R + struct dirent *buffer; /* A buffer used by the threaded version of readdir */ + int buffer_dim; /* The allocated size of buffer[] */ +#endif +}; + +static int _dr_path_is_dir(const char *pathname); + +/*....................................................................... + * Create a new DirReader object. + * + * Output: + * return DirReader * The new object, or NULL on error. + */ +DirReader *_new_DirReader(void) +{ + DirReader *dr; /* The object to be returned */ +/* + * Allocate the container. + */ + dr = (DirReader *) malloc(sizeof(DirReader)); + if(!dr) { + fprintf(stderr, "_new_DirReader: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_DirReader(). + */ + dr->dir = NULL; + dr->file = NULL; + dr->errmsg[0] = '\0'; +#ifdef USE_READDIR_R + dr->buffer = NULL; + dr->buffer_dim = 0; +#endif + return dr; +} + +/*....................................................................... + * Delete a DirReader object. + * + * Input: + * dr DirReader * The object to be deleted. + * Output: + * return DirReader * The deleted object (always NULL). + */ +DirReader *_del_DirReader(DirReader *dr) +{ + if(dr) { + _dr_close_dir(dr); +#ifdef USE_READDIR_R + free(dr->buffer); +#endif + free(dr); + }; + return NULL; +} + +/*....................................................................... + * Open a new directory. + * + * Input: + * dr DirReader * The directory reader resource object. + * path const char * The directory to be opened. + * Input/Output: + * errmsg char ** If an error occurs and errmsg isn't NULL, a + * pointer to an error description will be assigned + * to *errmsg. + * Output: + * return int 0 - OK. + * 1 - Error (see *errmsg for a description). + */ +int _dr_open_dir(DirReader *dr, const char *path, char **errmsg) +{ + DIR *dir = NULL; /* The directory stream */ +/* + * If a directory is already open, close it first. + */ + (void) _dr_close_dir(dr); +/* + * Is the path a directory? + */ + if(!_dr_path_is_dir(path)) { + if(errmsg) { + const char *fmt = "Can't open directory: %.*s\n"; + sprintf(dr->errmsg, fmt, ERRLEN - strlen(fmt), path); + *errmsg = dr->errmsg; + }; + return 1; + }; +/* + * Attempt to open the directory. + */ + dir = opendir(path); + if(!dir) { + if(errmsg) { + const char *fmt = "Can't open directory: %.*s\n"; + sprintf(dr->errmsg, fmt, ERRLEN - strlen(fmt), path); + *errmsg = dr->errmsg; + }; + return 1; + }; +/* + * If using POSIX threads, allocate a buffer for readdir_r(). + */ +#ifdef USE_READDIR_R + { + size_t size; + int name_max = pathconf(path, _PC_NAME_MAX); +#ifdef NAME_MAX + if(name_max < 0) + name_max = NAME_MAX; +#endif + if(name_max < 0) { + if(errmsg) { + strcpy(dr->errmsg, "Unable to deduce readdir() buffer size."); + *errmsg = dr->errmsg; + }; + closedir(dir); + return 1; + }; +/* + * How big a buffer do we need to allocate? + */ + size = sizeof(struct dirent) + name_max; +/* + * Extend the buffer? + */ + if(size > dr->buffer_dim || !dr->buffer) { + struct dirent *buffer = (struct dirent *) (dr->buffer ? + realloc(dr->buffer, size) : + malloc(size)); + if(!buffer) { + if(errmsg) { + strcpy(dr->errmsg, "Insufficient memory for readdir() buffer."); + *errmsg = dr->errmsg; + }; + closedir(dir); + return 1; + }; + dr->buffer = buffer; + dr->buffer_dim = size; + }; + }; +#endif +/* + * Record the successfully opened directory. + */ + dr->dir = dir; + return 0; +} + +/*....................................................................... + * If the DirReader object is currently contains an open directory, + * close it. + * + * Input: + * dr DirReader * The directory reader resource object. + */ +void _dr_close_dir(DirReader *dr) +{ + if(dr && dr->dir) { + closedir(dr->dir); + dr->dir = NULL; + dr->file = NULL; + dr->errmsg[0] = '\0'; + }; +} + +/*....................................................................... + * Read the next file from the directory opened with _dr_open_dir(). + * + * Input: + * dr DirReader * The directory reader resource object. + * Output: + * return char * The name of the new file, or NULL if we reached + * the end of the directory. + */ +char *_dr_next_file(DirReader *dr) +{ +/* + * Are we currently reading a directory? + */ + if(dr->dir) { +/* + * Read the next directory entry. + */ +#ifdef USE_READDIR_R + if(readdir_r(dr->dir, dr->buffer, &dr->file) == 0 && dr->file) + return dr->file->d_name; +#else + dr->file = readdir(dr->dir); + if(dr->file) + return dr->file->d_name; +#endif + }; +/* + * When the end of a directory is reached, close it. + */ + _dr_close_dir(dr); + return NULL; +} + +/*....................................................................... + * Return 1 if the specified pathname refers to a directory. + * + * Input: + * pathname const char * The path to test. + * Output: + * return int 0 - Not a directory. + * 1 - pathname[] refers to a directory. + */ +static int _dr_path_is_dir(const char *pathname) +{ + struct stat statbuf; /* The file-statistics return buffer */ +/* + * Look up the file attributes. + */ + if(stat(pathname, &statbuf) < 0) + return 0; +/* + * Is the file a directory? + */ + return S_ISDIR(statbuf.st_mode) != 0; +} diff --git a/libtecla-1.4.1/direader.h b/libtecla-1.4.1/direader.h new file mode 100644 index 0000000..2cf178e --- /dev/null +++ b/libtecla-1.4.1/direader.h @@ -0,0 +1,44 @@ +#ifndef dirreader_h +#define dirreader_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +typedef struct DirReader DirReader; + +DirReader *_new_DirReader(void); +DirReader *_del_DirReader(DirReader *dr); + +int _dr_open_dir(DirReader *dr, const char *pathname, char **errmsg); +char *_dr_next_file(DirReader *dr); +void _dr_close_dir(DirReader *dr); + +#endif diff --git a/libtecla-1.4.1/enhance.c b/libtecla-1.4.1/enhance.c new file mode 100644 index 0000000..72f5061 --- /dev/null +++ b/libtecla-1.4.1/enhance.c @@ -0,0 +1,689 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#if HAVE_SYSV_PTY +#include /* System-V stream I/O */ +char *ptsname(int fd); +int grantpt(int fd); +int unlockpt(int fd); +#endif + +#include "libtecla.h" + +/* + * Pseudo-terminal devices are found in the following directory. + */ +#define PTY_DEV_DIR "/dev/" + +/* + * Pseudo-terminal controller device file names start with the following + * prefix. + */ +#define PTY_CNTRL "pty" + +/* + * Pseudo-terminal slave device file names start with the following + * prefix. + */ +#define PTY_SLAVE "tty" + +/* + * Specify the maximum suffix length for the control and slave device + * names. + */ +#define PTY_MAX_SUFFIX 10 + +/* + * Set the maximum length of the master and slave terminal device filenames, + * including space for a terminating '\0'. + */ +#define PTY_MAX_NAME (sizeof(PTY_DEV_DIR)-1 + \ + (sizeof(PTY_SLAVE) > sizeof(PTY_CNTRL) ? \ + sizeof(PTY_SLAVE) : sizeof(PTY_CNTRL))-1 \ + + PTY_MAX_SUFFIX + 1) +/* + * Set the maximum length of an input line. + */ +#define PTY_MAX_LINE 4096 + +/* + * Set the size of the buffer used for accumulating bytes written by the + * user's terminal to its stdout. + */ +#define PTY_MAX_READ 1000 + +/* + * Set the amount of memory used to record history. + */ +#define PTY_HIST_SIZE 10000 + +/* + * Set the timeout delay used to check for quickly arriving + * sequential output from the application. + */ +#define PTY_READ_TIMEOUT 100000 /* micro-seconds */ + +static int pty_open_master(const char *prog, int *cntrl, char *slave_name); +static int pty_open_slave(const char *prog, char *slave_name); +static int pty_child(const char *prog, int slave, char *argv[]); +static int pty_parent(const char *prog, int cntrl); +static int pty_stop_parent(int waserr, int cntrl, GetLine *gl, char *rbuff); +static GL_FD_EVENT_FN(pty_read_from_program); +static int pty_write_to_fd(int fd, const char *string, int n); +static void pty_child_exited(int sig); +static int pty_master_readable(int fd, long usec); + +/*....................................................................... + * Run a program with enhanced terminal editing facilities. + * + * Usage: + * enhance program [args...] + */ +int main(int argc, char *argv[]) +{ + int cntrl = -1; /* The fd of the pseudo-terminal controller device */ + int slave = -1; /* The fd of the pseudo-terminal slave device */ + pid_t pid; /* The return value of fork() */ + int status; /* The return statuses of the parent and child functions */ + char slave_name[PTY_MAX_NAME]; /* The filename of the slave end of the */ + /* pseudo-terminal. */ + char *prog; /* The name of the program (ie. argv[0]) */ +/* + * Check the arguments. + */ + if(argc < 2) { + fprintf(stderr, "Usage: %s [arguments...]\n", argv[0]); + return 1; + }; +/* + * Get the name of the program. + */ + prog = argv[0]; +/* + * If the user has the LC_CTYPE or LC_ALL environment variables set, + * enable display of characters corresponding to the specified locale. + */ + (void) setlocale(LC_CTYPE, ""); +/* + * If the program is taking its input from a pipe or a file, or + * sending its output to something other than a terminal, run the + * program without tecla. + */ + if(!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { + if(execvp(argv[1], argv + 1) < 0) { + fprintf(stderr, "%s: Unable to execute %s (%s).\n", prog, argv[1], + strerror(errno)); + fflush(stderr); + _exit(1); + }; + }; +/* + * Open the master side of a pseudo-terminal pair, and return + * the corresponding file descriptor and the filename of the + * slave end of the pseudo-terminal. + */ + if(pty_open_master(prog, &cntrl, slave_name)) + return 1; +/* + * Set up a signal handler to watch for the child process exiting. + */ + signal(SIGCHLD, pty_child_exited); +/* + * The above signal handler sends the parent process a SIGINT signal. + * This signal is caught by gl_get_line(), which resets the terminal + * settings, and if the application signal handler for this signal + * doesn't abort the process, gl_get_line() returns NULL with errno + * set to EINTR. Arrange to ignore the signal, so that gl_get_line() + * returns and we have a chance to cleanup. + */ + signal(SIGINT, SIG_IGN); +/* + * We will read user input in one process, and run the user's program + * in a child process. + */ + pid = fork(); + if(pid < 0) { + fprintf(stderr, "%s: Unable to fork child process (%s).\n", prog, + strerror(errno)); + return 1; + }; +/* + * Are we the parent? + */ + if(pid!=0) { + status = pty_parent(prog, cntrl); + close(cntrl); + } else { + close(cntrl); /* The child doesn't use the slave device */ + signal(SIGCHLD, pty_child_exited); + if((slave = pty_open_slave(prog, slave_name)) >= 0) { + status = pty_child(prog, slave, argv + 1); + close(slave); + } else { + status = 1; + }; + }; + return status; +} + +/*....................................................................... + * Open the master side of a pseudo-terminal pair, and return + * the corresponding file descriptor and the filename of the + * slave end of the pseudo-terminal. + * + * Input/Output: + * prog const char * The name of this program. + * cntrl int * The file descriptor of the pseudo-terminal + * controller device will be assigned tp *cntrl. + * slave_name char * The file-name of the pseudo-terminal slave device + * will be recorded in slave_name[], which must have + * at least PTY_MAX_NAME elements. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int pty_open_master(const char *prog, int *cntrl, char *slave_name) +{ + char master_name[PTY_MAX_NAME]; /* The filename of the master device */ + DIR *dir; /* The directory iterator */ + struct dirent *file; /* A file in "/dev" */ +/* + * Mark the controller device as not opened yet. + */ + *cntrl = -1; +/* + * On systems with the Sys-V pseudo-terminal interface, we don't + * have to search for a free master terminal. We just open /dev/ptmx, + * and if there is a free master terminal device, we are given a file + * descriptor connected to it. + */ +#if HAVE_SYSV_PTY + *cntrl = open("/dev/ptmx", O_RDWR); + if(*cntrl >= 0) { +/* + * Get the filename of the slave side of the pseudo-terminal. + */ + char *name = ptsname(*cntrl); + if(name) { + if(strlen(name)+1 > PTY_MAX_NAME) { + fprintf(stderr, "%s: Slave pty filename too long.\n", prog); + return 1; + }; + strcpy(slave_name, name); +/* + * If unable to get the slave name, discard the controller file descriptor, + * ready to try a search instead. + */ + } else { + close(*cntrl); + *cntrl = -1; + }; + } else { +#endif +/* + * On systems without /dev/ptmx, or if opening /dev/ptmx failed, + * we open one master terminal after another, until one that isn't + * in use by another program is found. + * + * Open the devices directory. + */ + dir = opendir(PTY_DEV_DIR); + if(!dir) { + fprintf(stderr, "%s: Couldn't open %s (%s)\n", prog, PTY_DEV_DIR, + strerror(errno)); + return 1; + }; +/* + * Look for pseudo-terminal controller device files in the devices + * directory. + */ + while(*cntrl < 0 && (file = readdir(dir))) { + if(strncmp(file->d_name, PTY_CNTRL, sizeof(PTY_CNTRL)-1) == 0) { +/* + * Get the common extension of the control and slave filenames. + */ + const char *ext = file->d_name + sizeof(PTY_CNTRL)-1; + if(strlen(ext) > PTY_MAX_SUFFIX) + continue; +/* + * Attempt to open the control file. + */ + strcpy(master_name, PTY_DEV_DIR); + strcat(master_name, PTY_CNTRL); + strcat(master_name, ext); + *cntrl = open(master_name, O_RDWR); + if(*cntrl < 0) + continue; +/* + * Attempt to open the matching slave file. + */ + strcpy(slave_name, PTY_DEV_DIR); + strcat(slave_name, PTY_SLAVE); + strcat(slave_name, ext); + }; + }; + closedir(dir); +#if HAVE_SYSV_PTY + }; +#endif +/* + * Did we fail to find a pseudo-terminal pair that we could open? + */ + if(*cntrl < 0) { + fprintf(stderr, "%s: Unable to find a free pseudo-terminal.\n", prog); + return 1; + }; +/* + * System V systems require the program that opens the master to + * grant access to the slave side of the pseudo-terminal. + */ +#ifdef HAVE_SYSV_PTY + if(grantpt(*cntrl) < 0 || + unlockpt(*cntrl) < 0) { + fprintf(stderr, "%s: Unable to unlock terminal (%s).\n", prog, + strerror(errno)); + return 1; + }; +#endif +/* + * Success. + */ + return 0; +} + +/*....................................................................... + * Open the slave end of a pseudo-terminal. + * + * Input: + * prog const char * The name of this program. + * slave_name char * The filename of the slave device. + * Output: + * return int The file descriptor of the successfully opened + * slave device, or < 0 on error. + */ +static int pty_open_slave(const char *prog, char *slave_name) +{ + int fd; /* The file descriptor of the slave device */ +/* + * Place the process in its own process group. In system-V based + * OS's, this ensures that when the pseudo-terminal is opened, it + * becomes the controlling terminal of the process. + */ + if(setsid() < 0) { + fprintf(stderr, "%s: Unable to form new process group (%s).\n", prog, + strerror(errno)); + return -1; + }; +/* + * Attempt to open the specified device. + */ + fd = open(slave_name, O_RDWR); + if(fd < 0) { + fprintf(stderr, "%s: Unable to open pseudo-terminal slave device (%s).\n", + prog, strerror(errno)); + return -1; + }; +/* + * On system-V streams based systems, we need to push the stream modules + * that implement pseudo-terminal and termio interfaces. At least on + * Solaris, which pushes these automatically when a slave is opened, + * this is redundant, so ignore errors when pushing the modules. + */ +#if HAVE_SYSV_PTY + (void) ioctl(fd, I_PUSH, "ptem"); + (void) ioctl(fd, I_PUSH, "ldterm"); +/* + * On BSD based systems other than SunOS 4.x, the following makes the + * pseudo-terminal the controlling terminal of the child process. + * According to the pseudo-terminal example code in Steven's + * Advanced programming in the unix environment, the !defined(CIBAUD) + * part of the clause prevents this from being used under SunOS. Since + * I only have his code with me, and won't have access to the book, + * I don't know why this is necessary. + */ +#elif defined(TIOCSCTTY) && !defined(CIBAUD) + if(ioctl(fd, TIOCSCTTY, (char *) 0) < 0) { + fprintf(stderr, "%s: Unable to establish controlling terminal (%s).\n", + prog, strerror(errno)); + close(fd); + return -1; + }; +#endif + return fd; +} + +/*....................................................................... + * Read input from the controlling terminal of the program, using + * gl_get_line(), and feed it to the user's program running in a child + * process, via the controller side of the pseudo-terminal. Also pass + * data received from the user's program via the conroller end of + * the pseudo-terminal, to stdout. + * + * Input: + * prog const char * The name of this program. + * cntrl int The file descriptor of the controller end of the + * pseudo-terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int pty_parent(const char *prog, int cntrl) +{ + GetLine *gl = NULL; /* The gl_get_line() resource object */ + char *line; /* An input line read from the user */ + char *rbuff=NULL; /* A buffer for reading from the pseudo terminal */ +/* + * Allocate the gl_get_line() resource object. + */ + gl = new_GetLine(PTY_MAX_LINE, PTY_HIST_SIZE); + if(!gl) + return pty_stop_parent(1, cntrl, gl, rbuff); +/* + * Allocate a buffer to use to accumulate bytes read from the + * pseudo-terminal. + */ + rbuff = (char *) malloc(PTY_MAX_READ+1); + if(!rbuff) + return pty_stop_parent(1, cntrl, gl, rbuff); + rbuff[0] = '\0'; +/* + * Register an event handler to watch for data appearing from the + * user's program on the controller end of the pseudo terminal. + */ + if(gl_watch_fd(gl, cntrl, GLFD_READ, pty_read_from_program, rbuff)) + return pty_stop_parent(1, cntrl, gl, rbuff); +/* + * Read input lines from the user and pass them on to the user's program, + * by writing to the controller end of the pseudo-terminal. + */ + while((line=gl_get_line(gl, rbuff, NULL, 0))) { + if(pty_write_to_fd(cntrl, line, strlen(line))) + return pty_stop_parent(1, cntrl, gl, rbuff); + rbuff[0] = '\0'; + }; + return pty_stop_parent(0, cntrl, gl, rbuff); +} + +/*....................................................................... + * This is a private return function of pty_parent(), used to release + * dynamically allocated resources, close the controller end of the + * pseudo-terminal, and wait for the child to exit. It returns the + * exit status of the child process, unless the caller reports an + * error itself, in which case the caller's error status is returned. + * + * Input: + * waserr int True if the caller is calling this function because + * an error occured. + * cntrl int The file descriptor of the controller end of the + * pseudo-terminal. + * gl GetLine * The resource object of gl_get_line(). + * rbuff char * The buffer used to accumulate bytes read from + * the pseudo-terminal. + * Output: + * return int The desired exit status of the program. + */ +static int pty_stop_parent(int waserr, int cntrl, GetLine *gl, char *rbuff) +{ + int status; /* The return status of the child process */ +/* + * Close the controller end of the terminal. + */ + close(cntrl); +/* + * Delete the resource object. + */ + gl = del_GetLine(gl); +/* + * Delete the read buffer. + */ + if(rbuff) + free(rbuff); +/* + * Wait for the user's program to end. + */ + (void) wait(&status); +/* + * Return either our error status, or the return status of the child + * program. + */ + return waserr ? 1 : status; +} + +/*....................................................................... + * Run the user's program, with its stdin and stdout connected to the + * slave end of the psuedo-terminal. + * + * Input: + * prog const char * The name of this program. + * slave int The file descriptor of the slave end of the + * pseudo terminal. + * argv char *[] The argument vector to pass to the user's program, + * where argv[0] is the name of the user's program, + * and the last argument is followed by a pointer + * to NULL. + * Output: + * return int If this function returns at all, an error must + * have occured when trying to overlay the process + * with the user's program. In this case 1 is + * returned. + */ +static int pty_child(const char *prog, int slave, char *argv[]) +{ + struct termios attr; /* The terminal attributes */ +/* + * We need to stop the pseudo-terminal from echoing everything that we send it. + */ + if(tcgetattr(slave, &attr)) { + fprintf(stderr, "%s: Can't get pseudo-terminal attributes (%s).\n", prog, + strerror(errno)); + return 1; + }; + attr.c_lflag &= ~(ECHO); + while(tcsetattr(slave, TCSADRAIN, &attr)) { + if(errno != EINTR) { + fprintf(stderr, "%s: tcsetattr error: %s\n", prog, strerror(errno)); + return 1; + }; + }; +/* + * Arrange for stdin, stdout and stderr to be connected to the slave device, + * ignoring errors that imply that either stdin or stdout is closed. + */ + while(dup2(slave, STDIN_FILENO) < 0 && errno==EINTR) + ; + while(dup2(slave, STDOUT_FILENO) < 0 && errno==EINTR) + ; + while(dup2(slave, STDERR_FILENO) < 0 && errno==EINTR) + ; +/* + * Run the user's program. + */ + if(execvp(argv[0], argv) < 0) { + fprintf(stderr, "%s: Unable to execute %s (%s).\n", prog, argv[0], + strerror(errno)); + fflush(stderr); + _exit(1); + }; + return 0; /* This should never be reached */ +} + +/*....................................................................... + * This is the event-handler that is called by gl_get_line() whenever + * there is tet waiting to be read from the user's program, via the + * controller end of the pseudo-terminal. See libtecla.h for details + * about its arguments. + */ +static GL_FD_EVENT_FN(pty_read_from_program) +{ + char *nlptr; /* A pointer to the last newline in the accumulated string */ + char *crptr; /* A pointer to the last '\r' in the accumulated string */ + char *nextp; /* A pointer to the next unprocessed character */ +/* + * Get the read buffer in which we are accumulating a line to be + * forwarded to stdout. + */ + char *rbuff = (char *) data; +/* + * New data may arrive while we are processing the current read, and + * it is more efficient to display this here than to keep returning to + * gl_get_line() and have it display the latest prefix as a prompt, + * followed by the current input line, so we loop, delaying a bit at + * the end of each iteration to check for more data arriving from + * the application, before finally returning to gl_get_line() when + * no more input is available. + */ + do { +/* + * Get the current length of the output string. + */ + int len = strlen(rbuff); +/* + * Read the text from the program. + */ + int nnew = read(fd, rbuff + len, PTY_MAX_READ - len); + if(nnew < 0) + return GLFD_ABORT; + len += nnew; +/* + * Nul terminate the accumulated string. + */ + rbuff[len] = '\0'; +/* + * Find the last newline and last carriage return in the buffer, if any. + */ + nlptr = strrchr(rbuff, '\n'); + crptr = strrchr(rbuff, '\r'); +/* + * We want to output up to just before the last newline or carriage + * return. If there are no newlines of carriage returns in the line, + * and the buffer is full, then we should output the whole line. In + * all cases a new output line will be started after the latest text + * has been output. The intention is to leave any incomplete line + * in the buffer, for (perhaps temporary) use as the current prompt. + */ + if(nlptr) { + nextp = crptr && crptr < nlptr ? crptr : nlptr; + } else if(crptr) { + nextp = crptr; + } else if(len >= PTY_MAX_READ) { + nextp = rbuff + len; + } else { + nextp = NULL; + }; +/* + * Do we have any text to output yet? + */ + if(nextp) { +/* + * If there was already some text in rbuff before this function + * was called, then it will have been used as a prompt. Arrange + * to rewrite this prefix, plus the new suffix, by moving back to + * the start of the line. + */ + if(len > 0) + (void) pty_write_to_fd(STDOUT_FILENO, "\r", 1); +/* + * Write everything up to the last newline to stdout. + */ + (void) pty_write_to_fd(STDOUT_FILENO, rbuff, nextp - rbuff); +/* + * Start a new line. + */ + (void) pty_write_to_fd(STDOUT_FILENO, "\r\n", 2); +/* + * Skip trailing carriage returns and newlines. + */ + while(*nextp=='\n' || *nextp=='\r') + nextp++; +/* + * Move any unwritten text following the newline, to the start of the + * buffer. + */ + memmove(rbuff, nextp, len - (nextp - rbuff) + 1); + }; + } while(pty_master_readable(fd, PTY_READ_TIMEOUT)); +/* + * Make the incomplete line in the output buffer the current prompt. + */ + gl_replace_prompt(gl, rbuff); + return GLFD_REFRESH; +} + +/*....................................................................... + * Write a given string to a specified file descriptor. + * + * Input: + * fd int The file descriptor to write to. + * string const char * The string to write (of at least 'n' characters). + * n int The number of characters to write. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int pty_write_to_fd(int fd, const char *string, int n) +{ + int ndone = 0; /* The number of characters written so far */ +/* + * Do as many writes as are needed to write the whole string. + */ + while(ndone < n) { + int nnew = write(fd, string + ndone, n - ndone); + if(nnew > 0) + ndone += nnew; + else if(errno != EINTR) + return 1; + }; + return 0; +} + +/*....................................................................... + * This is the signal handler that is called when the child process + * that is running the user's program exits for any reason. It closes + * the slave end of the terminal, so that gl_get_line() in the parent + * process sees an end of file. + */ +static void pty_child_exited(int sig) +{ + raise(SIGINT); +} + +/*....................................................................... + * Return non-zero after a given amount of time if there is data waiting + * to be read from a given file descriptor. + * + * Input: + * fd int The descriptor to watch. + * usec long The number of micro-seconds to wait for input to + * arrive before giving up. + * Output: + * return int 0 - No data is waiting to be read (or select isn't + * available). + * 1 - Data is waiting to be read. + */ +static int pty_master_readable(int fd, long usec) +{ +#if HAVE_SELECT + fd_set rfds; /* The set of file descriptors to check */ + struct timeval timeout; /* The timeout */ + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + timeout.tv_sec = 0; + timeout.tv_usec = usec; + return select(fd+1, &rfds, NULL, NULL, &timeout) == 1; +#else + return 0; +#endif +} diff --git a/libtecla-1.4.1/expand.c b/libtecla-1.4.1/expand.c new file mode 100644 index 0000000..c1600ab --- /dev/null +++ b/libtecla-1.4.1/expand.c @@ -0,0 +1,1265 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include + +#include "freelist.h" +#include "direader.h" +#include "pathutil.h" +#include "homedir.h" +#include "stringrp.h" +#include "libtecla.h" + +/* + * Specify the number of elements to extend the files[] array by + * when it proves to be too small. This also sets the initial size + * of the array. + */ +#define MATCH_BLK_FACT 256 + +/* + * A list of directory iterators is maintained using nodes of the + * following form. + */ +typedef struct DirNode DirNode; +struct DirNode { + DirNode *next; /* The next directory in the list */ + DirNode *prev; /* The node that precedes this node in the list */ + DirReader *dr; /* The directory reader object */ +}; + +typedef struct { + FreeList *mem; /* Memory for DirNode list nodes */ + DirNode *head; /* The head of the list of used and unused cache nodes */ + DirNode *next; /* The next unused node between head and tail */ + DirNode *tail; /* The tail of the list of unused cache nodes */ +} DirCache; + +/* + * Specify how many directory cache nodes to allocate at a time. + */ +#define DIR_CACHE_BLK 20 + +/* + * Set the maximum length allowed for usernames. + */ +#define USR_LEN 100 + +/* + * Set the maximum length allowed for environment variable names. + */ +#define ENV_LEN 100 + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +struct ExpandFile { + StringGroup *sg; /* A list of string segments in which */ + /* matching filenames are stored. */ + DirCache cache; /* The cache of directory reader objects */ + PathName *path; /* The pathname being matched */ + HomeDir *home; /* Home-directory lookup object */ + int files_dim; /* The allocated dimension of result.files[] */ + char usrnam[USR_LEN+1]; /* A user name */ + char envnam[ENV_LEN+1]; /* An environment variable name */ + char errmsg[ERRLEN+1]; /* Error-report buffer */ + FileExpansion result; /* The container used to return the results of */ + /* expanding a path. */ +}; + +static int ef_record_pathname(ExpandFile *ef, const char *pathname, + int remove_escapes); +static char *ef_cache_pathname(ExpandFile *ef, const char *pathname, + int remove_escapes); +static void ef_clear_files(ExpandFile *ef); + +static DirNode *ef_open_dir(ExpandFile *ef, const char *pathname); +static DirNode *ef_close_dir(ExpandFile *ef, DirNode *node); +static char *ef_expand_special(ExpandFile *ef, const char *path, int pathlen); +static int ef_match_relative_pathname(ExpandFile *ef, DirReader *dr, + const char *pattern, int separate); +static int ef_matches_range(int c, const char *pattern, const char **endp); +static int ef_string_matches_pattern(const char *file, const char *pattern, + int xplicit, const char *nextp); +static int ef_cmp_strings(const void *v1, const void *v2); + +/*....................................................................... + * Create the resources needed to expand filenames. + * + * Output: + * return ExpandFile * The new object, or NULL on error. + */ +ExpandFile *new_ExpandFile(void) +{ + ExpandFile *ef; /* The object to be returned */ +/* + * Allocate the container. + */ + ef = (ExpandFile *) malloc(sizeof(ExpandFile)); + if(!ef) { + fprintf(stderr, "new_ExpandFile: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_ExpandFile(). + */ + ef->sg = NULL; + ef->cache.mem = NULL; + ef->cache.head = NULL; + ef->cache.next = NULL; + ef->cache.tail = NULL; + ef->path = NULL; + ef->home = NULL; + ef->result.files = NULL; + ef->result.nfile = 0; + ef->usrnam[0] = '\0'; + ef->envnam[0] = '\0'; + ef->errmsg[0] = '\0'; +/* + * Allocate a list of string segments for storing filenames. + */ + ef->sg = _new_StringGroup(_pu_pathname_dim()); + if(!ef->sg) + return del_ExpandFile(ef); +/* + * Allocate a freelist for allocating directory cache nodes. + */ + ef->cache.mem = _new_FreeList("new_ExpandFile", sizeof(DirNode), DIR_CACHE_BLK); + if(!ef->cache.mem) + return del_ExpandFile(ef); +/* + * Allocate a pathname buffer. + */ + ef->path = _new_PathName(); + if(!ef->path) + return del_ExpandFile(ef); +/* + * Allocate an object for looking up home-directories. + */ + ef->home = _new_HomeDir(); + if(!ef->home) + return del_ExpandFile(ef); +/* + * Allocate an array for files. This will be extended later if needed. + */ + ef->files_dim = MATCH_BLK_FACT; + ef->result.files = (char **) malloc(sizeof(ef->result.files[0]) * + ef->files_dim); + if(!ef->result.files) { + fprintf(stderr, + "new_ExpandFile: Insufficient memory to allocate array of files.\n"); + return del_ExpandFile(ef); + }; + return ef; +} + +/*....................................................................... + * Delete a ExpandFile object. + * + * Input: + * ef ExpandFile * The object to be deleted. + * Output: + * return ExpandFile * The deleted object (always NULL). + */ +ExpandFile *del_ExpandFile(ExpandFile *ef) +{ + if(ef) { + DirNode *dnode; +/* + * Delete the string segments. + */ + ef->sg = _del_StringGroup(ef->sg); +/* + * Delete the cached directory readers. + */ + for(dnode=ef->cache.head; dnode; dnode=dnode->next) + dnode->dr = _del_DirReader(dnode->dr); +/* + * Delete the memory from which the DirNode list was allocated, thus + * deleting the list at the same time. + */ + ef->cache.mem = _del_FreeList("del_ExpandFile", ef->cache.mem, 1); + ef->cache.head = ef->cache.tail = ef->cache.next = NULL; +/* + * Delete the pathname buffer. + */ + ef->path = _del_PathName(ef->path); +/* + * Delete the home-directory lookup object. + */ + ef->home = _del_HomeDir(ef->home); +/* + * Delete the array of pointers to files. + */ + if(ef->result.files) { + free(ef->result.files); + ef->result.files = NULL; + }; +/* + * Delete the container. + */ + free(ef); + }; + return NULL; +} + +/*....................................................................... + * Expand a pathname, converting ~user/ and ~/ patterns at the start + * of the pathname to the corresponding home directories, replacing + * $envvar with the value of the corresponding environment variable, + * and then, if there are any wildcards, matching these against existing + * filenames. + * + * If no errors occur, a container is returned containing the array of + * files that resulted from the expansion. If there were no wildcards + * in the input pathname, this will contain just the original pathname + * after expansion of ~ and $ expressions. If there were any wildcards, + * then the array will contain the files that matched them. Note that + * if there were any wildcards but no existing files match them, this + * is counted as an error and NULL is returned. + * + * The supported wildcards and their meanings are: + * * - Match any sequence of zero or more characters. + * ? - Match any single character. + * [chars] - Match any single character that appears in 'chars'. + * If 'chars' contains an expression of the form a-b, + * then any character between a and b, including a and b, + * matches. The '-' character looses its special meaning + * as a range specifier when it appears at the start + * of the sequence of characters. + * [^chars] - The same as [chars] except that it matches any single + * character that doesn't appear in 'chars'. + * + * Wildcard expressions are applied to individual filename components. + * They don't match across directory separators. A '.' character at + * the beginning of a filename component must also be matched + * explicitly by a '.' character in the input pathname, since these + * are UNIX's hidden files. + * + * Input: + * ef ExpandFile * The pathname expansion resource object. + * path char * The path name to be expanded. + * pathlen int The length of the suffix of path[] that + * constitutes the filename to be expanded, + * or -1 to specify that the whole of the + * path string should be used. Note that + * regardless of the value of this argument, + * path[] must contain a '\0' terminated + * string, since this function checks that + * pathlen isn't mistakenly too long. + * Output: + * return FileExpansion * A pointer to a container within the given + * ExpandFile object. This contains an array + * of the pathnames that resulted from expanding + * ~ and $ expressions and from matching any + * wildcards, sorted into lexical order. + * This container and its contents will be + * recycled on subsequent calls, so if you need + * to keep the results of two successive runs, + * you will either have to allocate a private + * copy of the array, or use two ExpandFile + * objects. + * + * On error NULL is returned. A description + * of the error can be acquired by calling the + * ef_last_error() function. + */ +FileExpansion *ef_expand_file(ExpandFile *ef, const char *path, int pathlen) +{ + DirNode *dnode; /* A directory-reader cache node */ + const char *dirname; /* The name of the top level directory of the search */ + const char *pptr; /* A pointer into path[] */ + int wild; /* True if the path contains any wildcards */ +/* + * Check the arguments. + */ + if(!ef || !path) { + if(ef) + strcpy(ef->errmsg, "ef_expand_file: NULL path argument"); + else + fprintf(stderr, "ef_expand_file: NULL argument(s).\n"); + return NULL; + }; +/* + * If the caller specified that the whole of path[] be matched, + * work out the corresponding length. + */ + if(pathlen < 0 || pathlen > strlen(path)) + pathlen = strlen(path); +/* + * Discard previous expansion results. + */ + ef_clear_files(ef); +/* + * Preprocess the path, expanding ~/, ~user/ and $envvar references, + * using ef->path as a work directory and returning a pointer to + * a copy of the resulting pattern in the cache. + */ + path = ef_expand_special(ef, path, pathlen); + if(!path) + return NULL; +/* + * Clear the pathname buffer. + */ + _pn_clear_path(ef->path); +/* + * Does the pathname contain any wildcards? + */ + for(wild=0,pptr=path; !wild && *pptr; pptr++) { + switch(*pptr) { + case '\\': /* Skip escaped characters */ + if(pptr[1]) + pptr++; + break; + case '*': case '?': case '[': /* A wildcard character? */ + wild = 1; + break; + }; + }; +/* + * If there are no wildcards to match, copy the current expanded + * path into the output array, removing backslash escapes while doing so. + */ + if(!wild) { + if(ef_record_pathname(ef, path, 1)) + return NULL; +/* + * Does the filename exist? + */ + ef->result.exists = _pu_file_exists(ef->result.files[0]); +/* + * Match wildcards against existing files. + */ + } else { +/* + * Only existing files that match the pattern will be returned in the + * cache. + */ + ef->result.exists = 1; +/* + * Treat matching of the root-directory as a special case since it + * isn't contained in a directory. + */ + if(strcmp(path, FS_ROOT_DIR) == 0) { + if(ef_record_pathname(ef, FS_ROOT_DIR, 0)) + return NULL; + } else { +/* + * What should the top level directory of the search be? + */ + if(strncmp(path, FS_ROOT_DIR, FS_ROOT_DIR_LEN) == 0) { + dirname = FS_ROOT_DIR; + if(!_pn_append_to_path(ef->path, FS_ROOT_DIR, -1, 0)) { + strcpy(ef->errmsg, "Insufficient memory to record path"); + return NULL; + }; + path += FS_ROOT_DIR_LEN; + } else { + dirname = FS_PWD; + }; +/* + * Open the top-level directory of the search. + */ + dnode = ef_open_dir(ef, dirname); + if(!dnode) + return NULL; +/* + * Recursively match successive directory components of the path. + */ + if(ef_match_relative_pathname(ef, dnode->dr, path, 0)) { + dnode = ef_close_dir(ef, dnode); + return NULL; + }; +/* + * Cleanup. + */ + dnode = ef_close_dir(ef, dnode); + }; +/* + * No files matched? + */ + if(ef->result.nfile < 1) { + strcpy(ef->errmsg, "No files match"); + return NULL; + }; +/* + * Sort the pathnames that matched. + */ + qsort(ef->result.files, ef->result.nfile, sizeof(ef->result.files[0]), + ef_cmp_strings); + }; +/* + * Return the result container. + */ + return &ef->result; +} + +/*....................................................................... + * Attempt to recursively match the given pattern with the contents of + * the current directory, descending sub-directories as needed. + * + * Input: + * ef ExpandFile * The pathname expansion resource object. + * dr DirReader * The directory reader object of the directory + * to be searched. + * pattern const char * The pattern to match with files in the current + * directory. + * separate int When appending a filename from the specified + * directory to ef->pathname, insert a directory + * separator between the existing pathname and + * the filename, unless separate is zero. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int ef_match_relative_pathname(ExpandFile *ef, DirReader *dr, + const char *pattern, int separate) +{ + const char *nextp; /* The pointer to the character that follows the part */ + /* of the pattern that is to be matched with files */ + /* in the current directory. */ + char *file; /* The name of the file being matched */ + int pathlen; /* The length of ef->pathname[] on entry to this */ + /* function */ +/* + * Record the current length of the pathname string recorded in + * ef->pathname[]. + */ + pathlen = strlen(ef->path->name); +/* + * Get a pointer to the character that follows the end of the part of + * the pattern that should be matched to files within the current directory. + * This will either point to a directory separator, or to the '\0' terminator + * of the pattern string. + */ + for(nextp=pattern; *nextp && strncmp(nextp, FS_DIR_SEP, FS_DIR_SEP_LEN) != 0; + nextp++) + ; +/* + * Read each file from the directory, attempting to match it to the + * current pattern. + */ + while((file=_dr_next_file(dr)) != NULL) { +/* + * Does the latest file match the pattern up to nextp? + */ + if(ef_string_matches_pattern(file, pattern, file[0]=='.', nextp)) { +/* + * Append the new directory entry to the current matching pathname. + */ + if((separate && _pn_append_to_path(ef->path, FS_DIR_SEP, -1, 0)==NULL) || + _pn_append_to_path(ef->path, file, -1, 0)==NULL) { + strcpy(ef->errmsg, "Insufficient memory to record path"); + return 1; + }; +/* + * If we have reached the end of the pattern, record the accumulated + * pathname in the list of matching files. + */ + if(*nextp == '\0') { + if(ef_record_pathname(ef, ef->path->name, 0)) + return 1; +/* + * If the matching directory entry is a subdirectory, and the + * next character of the pattern is a directory separator, + * recursively call the current function to scan the sub-directory + * for matches. + */ + } else if(_pu_path_is_dir(ef->path->name) && + strncmp(nextp, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { +/* + * If the pattern finishes with the directory separator, then + * record the pathame as matching. + */ + if(nextp[FS_DIR_SEP_LEN] == '\0') { + if(ef_record_pathname(ef, ef->path->name, 0)) + return 1; +/* + * Match files within the directory. + */ + } else { + DirNode *subdnode = ef_open_dir(ef, ef->path->name); + if(subdnode) { + if(ef_match_relative_pathname(ef, subdnode->dr, + nextp+FS_DIR_SEP_LEN, 1)) { + subdnode = ef_close_dir(ef, subdnode); + return 1; + }; + subdnode = ef_close_dir(ef, subdnode); + }; + }; + }; +/* + * Remove the latest filename from the pathname string, so that + * another matching file can be appended. + */ + ef->path->name[pathlen] = '\0'; + }; + }; + return 0; +} + +/*....................................................................... + * Record a new matching filename. + * + * Input: + * ef ExpandFile * The filename-match resource object. + * pathname const char * The pathname to record. + * remove_escapes int If true, remove backslash escapes in the + * recorded copy of the pathname. + * Output: + * return int 0 - OK. + * 1 - Error (ef->errmsg will contain a + * description of the error). + */ +static int ef_record_pathname(ExpandFile *ef, const char *pathname, + int remove_escapes) +{ + char *copy; /* The recorded copy of pathname[] */ +/* + * Attempt to make a copy of the pathname in the cache. + */ + copy = ef_cache_pathname(ef, pathname, remove_escapes); + if(!copy) + return 1; +/* + * If there isn't room to record a pointer to the recorded pathname in the + * array of files, attempt to extend the array. + */ + if(ef->result.nfile + 1 > ef->files_dim) { + int files_dim = ef->files_dim + MATCH_BLK_FACT; + char **files = (char **) realloc(ef->result.files, + files_dim * sizeof(files[0])); + if(!files) { + sprintf(ef->errmsg, + "Insufficient memory to record all of the matching filenames"); + return 1; + }; + ef->result.files = files; + ef->files_dim = files_dim; + }; +/* + * Record a pointer to the new match. + */ + ef->result.files[ef->result.nfile++] = copy; + return 0; +} + +/*....................................................................... + * Record a pathname in the cache. + * + * Input: + * ef ExpandFile * The filename-match resource object. + * pathname char * The pathname to record. + * remove_escapes int If true, remove backslash escapes in the + * copy of the pathname. + * Output: + * return char * The pointer to the copy of the pathname. + * On error NULL is returned and a description + * of the error is left in ef->errmsg[]. + */ +static char *ef_cache_pathname(ExpandFile *ef, const char *pathname, + int remove_escapes) +{ + char *copy = _sg_store_string(ef->sg, pathname, remove_escapes); + if(!copy) + strcpy(ef->errmsg, "Insufficient memory to store pathname"); + return copy; +} + +/*....................................................................... + * Clear the results of the previous expansion operation, ready for the + * next. + * + * Input: + * ef ExpandFile * The pathname expansion resource object. + */ +static void ef_clear_files(ExpandFile *ef) +{ + _clr_StringGroup(ef->sg); + _pn_clear_path(ef->path); + ef->result.exists = 0; + ef->result.nfile = 0; + ef->errmsg[0] = '\0'; + return; +} + +/*....................................................................... + * Get a new directory reader object from the cache. + * + * Input: + * ef ExpandFile * The pathname expansion resource object. + * pathname const char * The pathname of the directory. + * Output: + * return DirNode * The cache entry of the new directory reader, + * or NULL on error. On error, ef->errmsg will + * contain a description of the error. + */ +static DirNode *ef_open_dir(ExpandFile *ef, const char *pathname) +{ + char *errmsg = NULL; /* An error message from a called function */ + DirNode *node; /* The cache node used */ +/* + * Get the directory reader cache. + */ + DirCache *cache = &ef->cache; +/* + * Extend the cache if there are no free cache nodes. + */ + if(!cache->next) { + node = (DirNode *) _new_FreeListNode(cache->mem); + if(!node) { + sprintf(ef->errmsg, "Insufficient memory to open a new directory"); + return NULL; + }; +/* + * Initialize the cache node. + */ + node->next = NULL; + node->prev = NULL; + node->dr = NULL; +/* + * Allocate a directory reader object. + */ + node->dr = _new_DirReader(); + if(!node->dr) { + sprintf(ef->errmsg, "Insufficient memory to open a new directory"); + node = (DirNode *) _del_FreeListNode(cache->mem, node); + return NULL; + }; +/* + * Append the node to the cache list. + */ + node->prev = cache->tail; + if(cache->tail) + cache->tail->next = node; + else + cache->head = node; + cache->next = cache->tail = node; + }; +/* + * Get the first unused node, but don't remove it from the list yet. + */ + node = cache->next; +/* + * Attempt to open the specified directory. + */ + if(_dr_open_dir(node->dr, pathname, &errmsg)) { + strncpy(ef->errmsg, errmsg, ERRLEN); + ef->errmsg[ERRLEN] = '\0'; + return NULL; + }; +/* + * Now that we have successfully opened the specified directory, + * remove the cache node from the list, and relink the list around it. + */ + cache->next = node->next; + if(node->prev) + node->prev->next = node->next; + else + cache->head = node->next; + if(node->next) + node->next->prev = node->prev; + else + cache->tail = node->prev; + node->next = node->prev = NULL; +/* + * Return the successfully initialized cache node to the caller. + */ + return node; +} + +/*....................................................................... + * Return a directory reader object to the cache, after first closing + * the directory that it was managing. + * + * Input: + * ef ExpandFile * The pathname expansion resource object. + * node DirNode * The cache entry of the directory reader, as returned + * by ef_open_dir(). + * Output: + * return DirNode * The deleted DirNode (ie. allways NULL). + */ +static DirNode *ef_close_dir(ExpandFile *ef, DirNode *node) +{ +/* + * Get the directory reader cache. + */ + DirCache *cache = &ef->cache; +/* + * Close the directory. + */ + _dr_close_dir(node->dr); +/* + * Return the node to the tail of the cache list. + */ + node->next = NULL; + node->prev = cache->tail; + if(cache->tail) + cache->tail->next = node; + else + cache->head = cache->tail = node; + if(!cache->next) + cache->next = node; + return NULL; +} + +/*....................................................................... + * Return non-zero if the specified file name matches a given glob + * pattern. + * + * Input: + * file const char * The file-name component to be matched to the pattern. + * pattern const char * The start of the pattern to match against file[]. + * xplicit int If non-zero, the first character must be matched + * explicitly (ie. not with a wildcard). + * nextp const char * The pointer to the the character following the + * end of the pattern in pattern[]. + * Output: + * return int 0 - Doesn't match. + * 1 - The file-name string matches the pattern. + */ +static int ef_string_matches_pattern(const char *file, const char *pattern, + int xplicit, const char *nextp) +{ + const char *pptr = pattern; /* The pointer used to scan the pattern */ + const char *fptr = file; /* The pointer used to scan the filename string */ +/* + * Match each character of the pattern in turn. + */ + while(pptr < nextp) { +/* + * Handle the next character of the pattern. + */ + switch(*pptr) { +/* + * A match zero-or-more characters wildcard operator. + */ + case '*': +/* + * Skip the '*' character in the pattern. + */ + pptr++; +/* + * If wildcards aren't allowed, the pattern doesn't match. + */ + if(xplicit) + return 0; +/* + * If the pattern ends with a the '*' wildcard, then the + * rest of the filename matches this. + */ + if(pptr >= nextp) + return 1; +/* + * Using the wildcard to match successively longer sections of + * the remaining characters of the filename, attempt to match + * the tail of the filename against the tail of the pattern. + */ + for( ; *fptr; fptr++) { + if(ef_string_matches_pattern(fptr, pptr, 0, nextp)) + return 1; + }; + return 0; /* The pattern following the '*' didn't match */ + break; +/* + * A match-one-character wildcard operator. + */ + case '?': +/* + * If there is a character to be matched, skip it and advance the + * pattern pointer. + */ + if(!xplicit && *fptr) { + fptr++; + pptr++; +/* + * If we hit the end of the filename string, there is no character + * matching the operator, so the string doesn't match. + */ + } else { + return 0; + }; + break; +/* + * A character range operator, with the character ranges enclosed + * in matching square brackets. + */ + case '[': + if(xplicit || !ef_matches_range(*fptr++, ++pptr, &pptr)) + return 0; + break; +/* + * A backslash in the pattern prevents the following character as + * being seen as a special character. + */ + case '\\': + pptr++; + /* Note fallthrough to default */ +/* + * A normal character to be matched explicitly. + */ + default: + if(*fptr == *pptr) { + fptr++; + pptr++; + } else { + return 0; + }; + break; + }; +/* + * After passing the first character, turn off the explicit match + * requirement. + */ + xplicit = 0; + }; +/* + * To get here the pattern must have been exhausted. If the filename + * string matched, then the filename string must also have been + * exhausted. + */ + return *fptr == '\0'; +} + +/*....................................................................... + * Match a character range expression terminated by an unescaped close + * square bracket. + * + * Input: + * c int The character to be matched with the range + * pattern. + * pattern const char * The range pattern to be matched (ie. after the + * initiating '[' character). + * endp const char ** On output a pointer to the character following the + * range expression will be assigned to *endp. + * Output: + * return int 0 - Doesn't match. + * 1 - The character matched. + */ +static int ef_matches_range(int c, const char *pattern, const char **endp) +{ + const char *pptr = pattern; /* The pointer used to scan the pattern */ + int invert = 0; /* True to invert the sense of the match */ + int matched = 0; /* True if the character matched the pattern */ +/* + * If the first character is a caret, the sense of the match is + * inverted and only if the character isn't one of those in the + * range, do we say that it matches. + */ + if(*pptr == '^') { + pptr++; + invert = 1; + }; +/* + * The hyphen is only a special character when it follows the first + * character of the range (not including the caret). + */ + if(*pptr == '-') { + pptr++; + if(c == '-') { + *endp = pptr; + matched = 1; + }; +/* + * Skip other leading '-' characters since they make no sense. + */ + while(*pptr == '-') + pptr++; + }; +/* + * The hyphen is only a special character when it follows the first + * character of the range (not including the caret or a hyphen). + */ + if(*pptr == ']') { + pptr++; + if(c == ']') { + *endp = pptr; + matched = 1; + }; + }; +/* + * Having dealt with the characters that have special meanings at + * the beginning of a character range expression, see if the + * character matches any of the remaining characters of the range, + * up until a terminating ']' character is seen. + */ + while(!matched && *pptr && *pptr != ']') { +/* + * Is this a range of characters signaled by the two end characters + * separated by a hyphen? + */ + if(*pptr == '-') { + if(pptr[1] != ']') { + if(c >= pptr[-1] && c <= pptr[1]) + matched = 1; + pptr += 2; + }; +/* + * A normal character to be compared directly. + */ + } else if(*pptr++ == c) { + matched = 1; + }; + }; +/* + * Find the terminating ']'. + */ + while(*pptr && *pptr != ']') + pptr++; +/* + * Did we find a terminating ']'? + */ + if(*pptr == ']') { + *endp = pptr + 1; + return matched ? !invert : invert; + }; +/* + * If the pattern didn't end with a ']' then it doesn't match, regardless + * of the value of the required sense of the match. + */ + *endp = pptr; + return 0; +} + +/*....................................................................... + * This is a qsort() comparison function used to sort strings. + * + * Input: + * v1, v2 void * Pointers to the two strings to be compared. + * Output: + * return int -1 -> v1 < v2. + * 0 -> v1 == v2 + * 1 -> v1 > v2 + */ +static int ef_cmp_strings(const void *v1, const void *v2) +{ + char * const *s1 = (char * const *) v1; + char * const *s2 = (char * const *) v2; + return strcmp(*s1, *s2); +} + +/*....................................................................... + * Preprocess a path, expanding ~/, ~user/ and $envvar references, using + * ef->path as a work buffer, then copy the result into a cache entry, + * and return a pointer to this copy. + * + * Input: + * ef ExpandFile * The resource object of the file matcher. + * pathlen int The length of the prefix of path[] to be expanded. + * Output: + * return char * A pointer to a copy of the output path in the + * cache. On error NULL is returned, and a description + * of the error is left in ef->errmsg[]. + */ +static char *ef_expand_special(ExpandFile *ef, const char *path, int pathlen) +{ + int spos; /* The index of the start of the path segment that needs */ + /* to be copied from path[] to the output pathname. */ + int ppos; /* The index of a character in path[] */ + char *pptr; /* A pointer into the output path */ + int escaped; /* True if the previous character was a '\' */ + int i; +/* + * Clear the pathname buffer. + */ + _pn_clear_path(ef->path); +/* + * We need to perform two passes, one to expand environment variables + * and a second to do tilde expansion. This caters for the case + * where an initial dollar expansion yields a tilde expression. + */ + escaped = 0; + for(spos=ppos=0; ppos < pathlen; ppos++) { + int c = path[ppos]; + if(escaped) { + escaped = 0; + } else if(c == '\\') { + escaped = 1; + } else if(c == '$') { + int envlen; /* The length of the environment variable */ + char *value; /* The value of the environment variable */ +/* + * Record the preceding unrecorded part of the pathname. + */ + if(spos < ppos && _pn_append_to_path(ef->path, path + spos, ppos-spos, 0) + == NULL) { + strcpy(ef->errmsg, "Insufficient memory to expand path"); + return NULL; + }; +/* + * Skip the dollar. + */ + ppos++; +/* + * Copy the environment variable name that follows the dollar into + * ef->envnam[], stopping if a directory separator or end of string + * is seen. + */ + for(envlen=0; envlenenvnam[envlen] = path[ppos++]; +/* + * If the username overflowed the buffer, treat it as invalid (note that + * on most unix systems only 8 characters are allowed in a username, + * whereas our ENV_LEN is much bigger than that. + */ + if(envlen >= ENV_LEN) { + strcpy(ef->errmsg, "Environment variable name too long"); + return NULL; + }; +/* + * Terminate the environment variable name. + */ + ef->envnam[envlen] = '\0'; +/* + * Lookup the value of the environment variable. + */ + value = getenv(ef->envnam); + if(!value) { + const char *fmt = "No expansion found for: $%.*s"; + sprintf(ef->errmsg, fmt, ERRLEN - strlen(fmt), ef->envnam); + return NULL; + }; +/* + * Copy the value of the environment variable into the output pathname. + */ + if(_pn_append_to_path(ef->path, value, -1, 0) == NULL) { + strcpy(ef->errmsg, "Insufficient memory to expand path"); + return NULL; + }; +/* + * Record the start of the uncopied tail of the input pathname. + */ + spos = ppos; + }; + }; +/* + * Record the uncopied tail of the pathname. + */ + if(spos < ppos && _pn_append_to_path(ef->path, path + spos, ppos-spos, 0) + == NULL) { + strcpy(ef->errmsg, "Insufficient memory to expand path"); + return NULL; + }; +/* + * If the first character of the resulting pathname is a tilde, + * then attempt to substitute the home directory of the specified user. + */ + pptr = ef->path->name; + if(*pptr == '~' && path[0] != '\\') { + int usrlen; /* The length of the username following the tilde */ + const char *homedir; /* The home directory of the user */ + int homelen; /* The length of the home directory string */ + int plen; /* The current length of the path */ + int skip=0; /* The number of characters to skip after the ~user */ +/* + * Get the current length of the output path. + */ + plen = strlen(ef->path->name); +/* + * Skip the tilde. + */ + pptr++; +/* + * Copy the optional username that follows the tilde into ef->usrnam[]. + */ + for(usrlen=0; usrlenusrnam[usrlen] = *pptr++; +/* + * If the username overflowed the buffer, treat it as invalid (note that + * on most unix systems only 8 characters are allowed in a username, + * whereas our USR_LEN is much bigger than that. + */ + if(usrlen >= USR_LEN) { + strcpy(ef->errmsg, "Username too long"); + return NULL; + }; +/* + * Terminate the username string. + */ + ef->usrnam[usrlen] = '\0'; +/* + * Lookup the home directory of the user. + */ + homedir = _hd_lookup_home_dir(ef->home, ef->usrnam); + if(!homedir) { + strncpy(ef->errmsg, _hd_last_home_dir_error(ef->home), ERRLEN); + ef->errmsg[ERRLEN] = '\0'; + return NULL; + }; + homelen = strlen(homedir); +/* + * ~user and ~ are usually followed by a directory separator to + * separate them from the file contained in the home directory. + * If the home directory is the root directory, then we don't want + * to follow the home directory by a directory separator, so we must + * erase it. + */ + if(strcmp(homedir, FS_ROOT_DIR) == 0 && + strncmp(pptr, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { + skip = FS_DIR_SEP_LEN; + }; +/* + * If needed, increase the size of the pathname buffer to allow it + * to accomodate the home directory instead of the tilde expression. + * Note that pptr may not be valid after this call. + */ + if(_pn_resize_path(ef->path, plen - usrlen - 1 - skip + homelen)==NULL) { + strcpy(ef->errmsg, "Insufficient memory to expand filename"); + return NULL; + }; +/* + * Move the part of the pathname that follows the tilde expression to + * the end of where the home directory will need to be inserted. + */ + memmove(ef->path->name + homelen, + ef->path->name + 1 + usrlen + skip, plen - usrlen - 1 - skip+1); +/* + * Write the home directory at the beginning of the string. + */ + for(i=0; ipath->name[i] = homedir[i]; + }; +/* + * Copy the result into the cache, and return a pointer to the copy. + */ + return ef_cache_pathname(ef, ef->path->name, 0); +} + +/*....................................................................... + * Return a description of the last path-expansion error that occurred. + * + * Input: + * ef ExpandFile * The path-expansion resource object. + * Output: + * return char * The description of the last error. + */ +const char *ef_last_error(ExpandFile *ef) +{ + return ef ? ef->errmsg : "NULL ExpandFile argument"; +} + +/*....................................................................... + * Print out an array of matching files. + * + * Input: + * result FileExpansion * The container of the sorted array of + * expansions. + * fp FILE * The output stream to write to. + * term_width int The width of the terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int ef_list_expansions(FileExpansion *result, FILE *fp, int term_width) +{ + int maxlen; /* The length of the longest matching string */ + int width; /* The width of a column */ + int ncol; /* The number of columns to list */ + int nrow; /* The number of rows needed to list all of the expansions */ + int row,col; /* The row and column being written to */ + int i; +/* + * Check the arguments. + */ + if(!result || !fp) { + fprintf(stderr, "ef_list_expansions: NULL argument(s).\n"); + return 1; + }; +/* + * Not enough space to list anything? + */ + if(term_width < 1) + return 0; +/* + * Work out the maximum length of the matching filenames. + */ + maxlen = 0; + for(i=0; infile; i++) { + int len = strlen(result->files[i]); + if(len > maxlen) + maxlen = len; + }; +/* + * Nothing to list? + */ + if(maxlen == 0) + return 0; +/* + * Split the available terminal width into columns of maxlen + 2 characters. + */ + width = maxlen + 2; + ncol = term_width / width; +/* + * If the column width is greater than the terminal width, the matches will + * just have to overlap onto the next line. + */ + if(ncol < 1) + ncol = 1; +/* + * How many rows will be needed? + */ + nrow = (result->nfile + ncol - 1) / ncol; +/* + * Print the expansions out in ncol columns, sorted in row order within each + * column. + */ + for(row=0; row < nrow; row++) { + for(col=0; col < ncol; col++) { + int m = col*nrow + row; + if(m < result->nfile) { + const char *filename = result->files[m]; + if(fprintf(fp, "%s%-*s%s", filename, + (int) (ncol > 1 ? maxlen - strlen(filename):0), "", + col +#include + +#include "freelist.h" + +typedef struct FreeListBlock FreeListBlock; +struct FreeListBlock { + FreeListBlock *next; /* The next block in the list */ + char *nodes; /* The array of free-list nodes */ +}; + +struct FreeList { + size_t node_size; /* The size of a free-list node */ + unsigned blocking_factor; /* The number of nodes per block */ + long nbusy; /* The number of nodes that are in use */ + FreeListBlock *block; /* The head of the list of free-list blocks */ + void *free_list; /* The free-list of nodes */ +}; + +static FreeListBlock *_new_FreeListBlock(FreeList *fl); +static FreeListBlock *_del_FreeListBlock(FreeListBlock *fl); +static void _thread_FreeListBlock(FreeList *fl, FreeListBlock *block); + +/*....................................................................... + * Allocate a new free-list from blocks of 'blocking_factor' objects of size + * node_size. + * + * Input: + * caller const char * The name of the calling function, for use in + * error messages, or NULL to not report errors + * to stderr. + * node_size size_t The size of the free-list nodes to be returned + * by _new_FreeListNode(). Use sizeof() to + * determine this. + * blocking_factor unsigned The number of objects of size 'object_size' + * to allocate per block. + * Output: + * return FreeList * The new freelist, or NULL on error. + */ +FreeList *_new_FreeList(const char *caller, size_t node_size, + unsigned blocking_factor) +{ + FreeList *fl; /* The new free-list container */ +/* + * When a free-list node is on the free-list, it is used as a (void *) + * link field. Roundup node_size to a mulitple of the size of a void + * pointer. This, plus the fact that the array of nodes is obtained via + * malloc, which returns memory suitably aligned for any object, will + * ensure that the first sizeof(void *) bytes of each node will be + * suitably aligned to use as a (void *) link pointer. + */ + node_size = sizeof(void *) * + ((node_size + sizeof(void *) - 1) / sizeof(void *)); +/* + * Enfore a minimum block size. + */ + if(blocking_factor < 1) + blocking_factor = 1; +/* + * Allocate the container of the free list. + */ + fl = (FreeList *) malloc(sizeof(FreeList)); + if(!fl) { + if(caller) + fprintf(stderr, "_new_FreeList (%s): Insufficient memory.\n", caller); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_FreeList(). + */ + fl->node_size = node_size; + fl->blocking_factor = blocking_factor; + fl->nbusy = 0; + fl->block = NULL; + fl->free_list = NULL; +/* + * Allocate the first block of memory. + */ + fl->block = _new_FreeListBlock(fl); + if(!fl->block) { + if(caller) + fprintf(stderr, "_new_FreeList (%s): Insufficient memory.\n", caller); + return _del_FreeList(caller, fl, 1); + }; +/* + * Add the new list of nodes to the free-list. + */ + fl->free_list = fl->block->nodes; +/* + * Return the free-list for use. + */ + return fl; +} + +/*....................................................................... + * Re-thread a freelist to reclaim all allocated nodes. + * This function should not be called unless if it is known that none + * of the currently allocated nodes are still being used. + * + * Input: + * fl FreeList * The free-list to be reset, or NULL. + */ +void _rst_FreeList(FreeList *fl) +{ + if(fl) { + FreeListBlock *block; +/* + * Re-thread the nodes of each block into individual free-lists. + */ + for(block=fl->block; block; block=block->next) + _thread_FreeListBlock(fl, block); +/* + * Link all of the block freelists into one large freelist. + */ + fl->free_list = NULL; + for(block=fl->block; block; block=block->next) { +/* + * Locate the last node of the current block. + */ + char *last_node = block->nodes + fl->node_size * + (fl->blocking_factor - 1); +/* + * Make the link-field of the last node point to the first + * node of the current freelist, then make the first node of the + * new block the start of the freelist. + */ + *(void **)last_node = fl->free_list; + fl->free_list = block->nodes; + }; +/* + * All allocated nodes have now been returned to the freelist. + */ + fl->nbusy = 0; + }; +} + +/*....................................................................... + * Delete a free-list. + * + * Input: + * caller const char * The name of the calling function, for use in + * error messages, or NULL if error messages + * shouldn't be reported to stderr. + * fl FreeList * The free-list to be deleted, or NULL. + * force int If force==0 then _del_FreeList() will complain + * and refuse to delete the free-list if any + * of nodes have not been returned to the free-list. + * If force!=0 then _del_FreeList() will not check + * whether any nodes are still in use and will + * always delete the list. + * Output: + * return FreeList * Always NULL (even if the list couldn't be + * deleted). + */ +FreeList *_del_FreeList(const char *caller, FreeList *fl, int force) +{ + if(fl) { +/* + * Check whether any nodes are in use. + */ + if(!force && _busy_FreeListNodes(fl) != 0) { + if(caller) + fprintf(stderr, "_del_FreeList (%s): %ld nodes are still in use.\n", + caller, _busy_FreeListNodes(fl)); + return NULL; + }; +/* + * Delete the list blocks. + */ + { + FreeListBlock *next = fl->block; + while(next) { + FreeListBlock *block = next; + next = block->next; + block = _del_FreeListBlock(block); + }; + }; + fl->block = NULL; + fl->free_list = NULL; +/* + * Discard the container. + */ + free(fl); + }; + return NULL; +} + +/*....................................................................... + * Allocate a new object from a free-list. + * + * Input: + * fl FreeList * The free-list to return an object from. + * Output: + * return void * A new object of the size that was specified via + * the node_size argument of _new_FreeList() when + * the free-list was created, or NULL if there + * is insufficient memory, or 'fl' is NULL. + */ +void *_new_FreeListNode(FreeList *fl) +{ + void *node; /* The node to be returned */ +/* + * Check arguments. + */ + if(!fl) + return NULL; +/* + * If the free-list has been exhausted extend it by allocating + * another block of nodes. + */ + if(!fl->free_list) { + FreeListBlock *block = _new_FreeListBlock(fl); + if(!block) + return NULL; +/* + * Prepend the new block to the list of free-list blocks. + */ + block->next = fl->block; + fl->block = block; +/* + * Add the new list of nodes to the free-list. + */ + fl->free_list = fl->block->nodes; + }; +/* + * Remove and return a node from the front of the free list. + */ + node = fl->free_list; + fl->free_list = *(void **)node; +/* + * Record the loss of a node from the free-list. + */ + fl->nbusy++; +/* + * Return the node. + */ + return node; +} + +/*....................................................................... + * Return an object to the free-list that it was allocated from. + * + * Input: + * caller const char * The name of the calling function, for use in + * error messages, or NULL to not report errors + * to stderr. + * fl FreeList * The free-list from which the object was taken. + * object void * The node to be returned. + * Output: + * return void * Always NULL. + */ +void *_del_FreeListNode(FreeList *fl, void *object) +{ +/* + * Check arguments. + */ + if(!fl) + return NULL; +/* + * Return the node to the head of the free list. + */ + if(object) { + *(void **)object = fl->free_list; + fl->free_list = object; +/* + * Record the return of the node to the free-list. + */ + fl->nbusy--; + }; + return NULL; +} + +/*....................................................................... + * Return a count of the number of nodes that are currently allocated. + * + * Input: + * fl FreeList * The list to count wrt, or NULL. + * Output: + * return long The number of nodes (or 0 if fl==NULL). + */ +long _busy_FreeListNodes(FreeList *fl) +{ + return fl ? fl->nbusy : 0; +} + +/*....................................................................... + * Allocate a new list of free-list nodes. On return the nodes will + * be linked together as a list starting with the node at the lowest + * address and ending with a NULL next pointer. + * + * Input: + * fl FreeList * The free-list to allocate the list for. + * Output: + * return FreeListBlock * The new linked block of free-list nodes, + * or NULL on error. + */ +static FreeListBlock *_new_FreeListBlock(FreeList *fl) +{ + FreeListBlock *block; /* The new block to be returned */ +/* + * Allocate the container. + */ + block = (FreeListBlock *) malloc(sizeof(FreeListBlock)); + if(!block) + return NULL; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_FreeListBlock(). + */ + block->next = NULL; + block->nodes = NULL; +/* + * Allocate the block of nodes. + */ + block->nodes = (char *) malloc(fl->node_size * fl->blocking_factor); + if(!block->nodes) + return _del_FreeListBlock(block); +/* + * Initialize the block as a linked list of FreeListNode's. + */ + _thread_FreeListBlock(fl, block); + return block; +} + +/*....................................................................... + * Link each node of a freelist block to the node that follows it. + * + * Input: + * fl FreeList * The freelist that contains the block. + * block FreeListBlock * The block to be threaded. + */ +static void _thread_FreeListBlock(FreeList *fl, FreeListBlock *block) +{ + char *mem = block->nodes; + int i; + for(i=0; iblocking_factor - 1; i++, mem += fl->node_size) + *(void **)mem = mem + fl->node_size; /* Link to the next node */ + *(void **)mem = NULL; /* Terminate the list */ +} + +/*....................................................................... + * Delete a free-list block. + * + * Input: + * fl FreeListBlock * The block to be deleted, or NULL. + * Output: + * return FreeListBlock * Always NULL. + */ +static FreeListBlock *_del_FreeListBlock(FreeListBlock *fl) +{ + if(fl) { + fl->next = NULL; + if(fl->nodes) + free(fl->nodes); + fl->nodes = NULL; + free(fl); + }; + return NULL; +} diff --git a/libtecla-1.4.1/freelist.h b/libtecla-1.4.1/freelist.h new file mode 100644 index 0000000..84e6aef --- /dev/null +++ b/libtecla-1.4.1/freelist.h @@ -0,0 +1,82 @@ +#ifndef freelist_h +#define freelist_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * This module provides a memory allocation scheme that helps to + * prevent memory fragmentation by allocating large blocks of + * fixed sized objects and forming them into a free-list for + * subsequent allocations. The free-list is expanded as needed. + */ +typedef struct FreeList FreeList; + +/* + * Allocate a new free-list from blocks of 'blocking_factor' objects of size + * node_size. The node_size argument should be determined by applying + * the sizeof() operator to the object type that you intend to allocate from + * the freelist. + */ +FreeList *_new_FreeList(const char *caller, size_t node_size, + unsigned blocking_factor); + +/* + * If it is known that none of the nodes currently allocated from + * a freelist are still in use, the following function can be called + * to return all nodes to the freelist without the overhead of + * having to call del_FreeListNode() for every allocated node. The + * nodes of the freelist can then be reused by future callers to + * new_FreeListNode(). + */ +void _rst_FreeList(FreeList *fl); + +/* + * Delete a free-list. + */ +FreeList *_del_FreeList(const char *caller, FreeList *fl, int force); + +/* + * Determine the number of nodes that are currently allocated. + */ +long _busy_FreeListNodes(FreeList *fl); + +/* + * Allocate a new object from a free-list. + */ +void *_new_FreeListNode(FreeList *fl); + +/* + * Return an object to the free-list that it was allocated from. + */ +void *_del_FreeListNode(FreeList *fl, void *object); + +#endif diff --git a/libtecla-1.4.1/getline.c b/libtecla-1.4.1/getline.c new file mode 100644 index 0000000..242fae3 --- /dev/null +++ b/libtecla-1.4.1/getline.c @@ -0,0 +1,8346 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Standard headers. + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * UNIX headers. + */ +#include +#ifdef HAVE_SELECT +#include +#include +#endif + +/* + * Handle the different sources of terminal control string and size + * information. Note that if no terminal information database is available, + * ANSI VT100 control sequences are used. + */ +#if defined(USE_TERMINFO) || defined(USE_TERMCAP) +/* + * Include curses.h or ncurses/curses.h depending on which is available. + */ +#ifdef HAVE_CURSES_H +#include +#elif defined(HAVE_NCURSES_CURSES_H) +#include +#endif +/* + * Include term.h where available. + */ +#if defined(HAVE_TERM_H) +#include +#elif defined(HAVE_NCURSES_TERM_H) +#include +#endif +/* + * When using termcap, include termcap.h on systems that have it. + * Otherwise assume that all prototypes are provided by curses.h. + */ +#if defined(USE_TERMCAP) && defined(HAVE_TERMCAP_H) +#include +#endif +/* + * Unfortunately both terminfo and termcap require one to use the tputs() + * function to output terminal control characters, and this function + * doesn't allow one to specify a file stream. As a result, the following + * file-scope variable is used to pass the current output file stream. + * This is bad, but there doesn't seem to be any alternative. + */ +static FILE *tputs_fp = NULL; +/* + * Under Solaris default Curses the output function that tputs takes is + * declared to have a char argument. On all other systems and on Solaris + * X/Open Curses (Issue 4, Version 2) it expects an int argument (using + * c89 or options -I /usr/xpg4/include -L /usr/xpg4/lib -R /usr/xpg4/lib + * selects XPG4v2 Curses on Solaris 2.6 and later). + * + * Similarly, under Mac OS X, the return value of the tputs output + * function is declared as void, whereas it is declared as int on + * other systems. + */ +#if defined __sun && defined __SVR4 && !defined _XOPEN_CURSES +static int gl_tputs_putchar(char c) {return putc(c, tputs_fp);} +#elif defined(__APPLE__) && defined(__MACH__) +static void gl_tputs_putchar(int c) {(void) putc(c, tputs_fp);} +#else +static int gl_tputs_putchar(int c) {return putc(c, tputs_fp);} +#endif +#endif + +/* + * POSIX headers. + */ +#include +#include + +/* + * Does the system provide the signal and ioctl query facility used + * to inform the process of terminal window size changes? + */ +#if defined(SIGWINCH) && defined(TIOCGWINSZ) +#define USE_SIGWINCH 1 +#endif + +/* + * Provide typedefs for standard POSIX structures. + */ +typedef struct sigaction SigAction; +typedef struct termios Termios; + +/* + * Local headers. + */ +#include "pathutil.h" +#include "libtecla.h" +#include "keytab.h" +#include "history.h" +#include "freelist.h" +#include "stringrp.h" +#include "getline.h" + +/* + * Enumerate the available editing styles. + */ +typedef enum { + GL_EMACS_MODE, /* Emacs style editing */ + GL_VI_MODE, /* Vi style editing */ + GL_NO_EDITOR /* Fall back to the basic OS-provided editing */ +} GlEditor; + +/* + * In vi mode, the following datatype is used to implement the + * undo command. It records a copy of the input line from before + * the command-mode action which edited the input line. + */ +typedef struct { + char *line; /* A historical copy of the input line */ + int buff_curpos; /* The historical location of the cursor in */ + /* line[] when the line was modified. */ + int ntotal; /* The number of characters in line[] */ + int saved; /* True once a line has been saved after the */ + /* last call to gl_interpret_char(). */ +} ViUndo; + +/* + * In vi mode, the following datatype is used to record information + * needed by the vi-repeat-change command. + */ +typedef struct { + KtKeyFn *fn; /* The last action function that made a */ + /* change to the line. */ + int count; /* The repeat count that was passed to the */ + /* above command. */ + int input_curpos; /* Whenever vi command mode is entered, the */ + /* the position at which it was first left */ + /* is recorded here. */ + int command_curpos; /* Whenever vi command mode is entered, the */ + /* the location of the cursor is recorded */ + /* here. */ + char input_char; /* Commands that call gl_read_character() */ + /* record the character here, so that it can */ + /* used on repeating the function. */ + int saved; /* True if a function has been saved since the */ + /* last call to gl_interpret_char(). */ + int active; /* True while a function is being repeated. */ +} ViRepeat; + +/* + * The following datatype is used to encapsulate information specific + * to vi mode. + */ +typedef struct { + ViUndo undo; /* Information needed to implement the vi */ + /* undo command. */ + ViRepeat repeat; /* Information needed to implement the vi */ + /* repeat command. */ + int command; /* True in vi command-mode */ + int find_forward; /* True if the last character search was in the */ + /* forward direction. */ + int find_onto; /* True if the last character search left the */ + /* on top of the located character, as opposed */ + /* to just before or after it. */ + char find_char; /* The last character sought, or '\0' if no */ + /* searches have been performed yet. */ +} ViMode; + +#ifdef HAVE_SELECT +/* + * Define a type for recording a file-descriptor callback and its associated + * data. + */ +typedef struct { + GlFdEventFn *fn; /* The callback function */ + void *data; /* Anonymous data to pass to the callback function */ +} GlFdHandler; + +/* + * A list of nodes of the following type is used to record file-activity + * event handlers, but only on systems that have the select() system call. + */ +typedef struct GlFdNode GlFdNode; +struct GlFdNode { + GlFdNode *next; /* The next in the list of nodes */ + int fd; /* The file descriptor being watched */ + GlFdHandler rd; /* The callback to call when fd is readable */ + GlFdHandler wr; /* The callback to call when fd is writable */ + GlFdHandler ur; /* The callback to call when fd has urgent data */ +}; + +/* + * Set the number of the above structures to allocate every time that + * the freelist of GlFdNode's becomes exhausted. + */ +#define GLFD_FREELIST_BLOCKING 10 + +/* + * Listen for and handle file-descriptor events. + */ +static int gl_event_handler(GetLine *gl); + +static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd, + GlFdEvent event); +#endif + +/* + * Each signal that gl_get_line() traps is described by a list node + * of the following type. + */ +typedef struct GlSignalNode GlSignalNode; +struct GlSignalNode { + GlSignalNode *next; /* The next signal in the list */ + int signo; /* The number of the signal */ + sigset_t proc_mask; /* A process mask which only includes signo */ + SigAction original; /* The signal disposition of the calling program */ + /* for this signal. */ + unsigned flags; /* A bitwise union of GlSignalFlags enumerators */ + GlAfterSignal after; /* What to do after the signal has been handled */ + int errno_value; /* What to set errno to */ +}; + +/* + * Set the number of the above structures to allocate every time that + * the freelist of GlSignalNode's becomes exhausted. + */ +#define GLS_FREELIST_BLOCKING 30 + +/* + * Define the contents of the GetLine object. + * Note that the typedef for this object can be found in libtecla.h. + */ +struct GetLine { + GlHistory *glh; /* The line-history buffer */ + WordCompletion *cpl; /* String completion resource object */ + CplMatchFn(*cpl_fn); /* The tab completion callback function */ + void *cpl_data; /* Callback data to pass to cpl_fn() */ + ExpandFile *ef; /* ~user/, $envvar and wildcard expansion */ + /* resource object. */ + StringGroup *capmem; /* Memory for recording terminal capability */ + /* strings. */ + int input_fd; /* The file descriptor to read on */ + int output_fd; /* The file descriptor to write to */ + FILE *input_fp; /* A stream wrapper around input_fd */ + FILE *output_fp; /* A stream wrapper around output_fd */ + FILE *file_fp; /* When input is being temporarily taken from */ + /* a file, this is its file-pointer. Otherwise */ + /* it is NULL. */ + char *term; /* The terminal type specified on the last call */ + /* to gl_change_terminal(). */ + int is_term; /* True if stdin is a terminal */ + size_t linelen; /* The max number of characters per line */ + char *line; /* A line-input buffer of allocated size */ + /* linelen+2. The extra 2 characters are */ + /* reserved for "\n\0". */ + char *cutbuf; /* A cut-buffer of the same size as line[] */ + const char *prompt; /* The current prompt string */ + int prompt_len; /* The length of the prompt string */ + int prompt_changed; /* True after a callback changes the prompt */ + int prompt_style; /* How the prompt string is displayed */ + FreeList *sig_mem; /* Memory for nodes of the signal list */ + GlSignalNode *sigs; /* The head of the list of signals */ + sigset_t old_signal_set; /* The signal set on entry to gl_get_line() */ + sigset_t new_signal_set; /* The set of signals that we are trapping */ + Termios oldattr; /* Saved terminal attributes. */ + KeyTab *bindings; /* A table of key-bindings */ + int ntotal; /* The number of characters in gl->line[] */ + int buff_curpos; /* The cursor position within gl->line[] */ + int term_curpos; /* The cursor position on the terminal */ + int buff_mark; /* A marker location in the buffer */ + int insert_curpos; /* The cursor position at start of insert */ + int insert; /* True in insert mode */ + int number; /* If >= 0, a numeric argument is being read */ + int endline; /* True to tell gl_get_input_line() to return */ + /* the current contents of gl->line[] */ + KtKeyFn *current_fn; /* The action function that is currently being */ + /* invoked. */ + int current_count; /* The repeat count passed to current_fn() */ + GlhLineID preload_id; /* When not zero, this should be the ID of a */ + /* line in the history buffer for potential */ + /* recall. */ + int preload_history; /* If true, preload the above history line when */ + /* gl_get_input_line() is next called. */ + long keyseq_count; /* The number of key sequences entered by the */ + /* the user since new_GetLine() was called. */ + long last_search; /* The value of oper_count during the last */ + /* history search operation. */ + GlEditor editor; /* The style of editing, (eg. vi or emacs) */ + int silence_bell; /* True if gl_ring_bell() should do nothing. */ + ViMode vi; /* Parameters used when editing in vi mode */ + const char *left; /* The string that moves the cursor 1 character */ + /* left. */ + const char *right; /* The string that moves the cursor 1 character */ + /* right. */ + const char *up; /* The string that moves the cursor 1 character */ + /* up. */ + const char *down; /* The string that moves the cursor 1 character */ + /* down. */ + const char *home; /* The string that moves the cursor home */ + const char *bol; /* Move cursor to beginning of line */ + const char *clear_eol; /* The string that clears from the cursor to */ + /* the end of the line. */ + const char *clear_eod; /* The string that clears from the cursor to */ + /* the end of the display. */ + const char *u_arrow; /* The string returned by the up-arrow key */ + const char *d_arrow; /* The string returned by the down-arrow key */ + const char *l_arrow; /* The string returned by the left-arrow key */ + const char *r_arrow; /* The string returned by the right-arrow key */ + const char *sound_bell; /* The string needed to ring the terminal bell */ + const char *bold; /* Switch to the bold font */ + const char *underline; /* Underline subsequent characters */ + const char *standout; /* Turn on standout mode */ + const char *dim; /* Switch to a dim font */ + const char *reverse; /* Turn on reverse video */ + const char *blink; /* Switch to a blinking font */ + const char *text_attr_off; /* Turn off all text attributes */ + int nline; /* The height of the terminal in lines */ + int ncolumn; /* The width of the terminal in columns */ +#ifdef USE_TERMCAP + char *tgetent_buf; /* The buffer that is used by tgetent() to */ + /* store a terminal description. */ + char *tgetstr_buf; /* The buffer that is used by tgetstr() to */ + /* store terminal capabilities. */ +#endif +#ifdef USE_TERMINFO + const char *left_n; /* The parameter string that moves the cursor */ + /* n characters left. */ + const char *right_n; /* The parameter string that moves the cursor */ + /* n characters right. */ +#endif + char *app_file; /* The pathname of the application-specific */ + /* .teclarc configuration file, or NULL. */ + char *user_file; /* The pathname of the user-specific */ + /* .teclarc configuration file, or NULL. */ + int configured; /* True as soon as any teclarc configuration */ + /* file has been read. */ + int echo; /* True to display the line as it is being */ + /* entered. If 0, only the prompt will be */ + /* displayed, and the line will not be */ + /* archived in the history list. */ + int last_signal; /* The last signal that was caught by */ + /* the last call to gl_get_line(), or -1 */ + /* if no signal has been caught yet. */ +#ifdef HAVE_SELECT + FreeList *fd_node_mem; /* A freelist of GlFdNode structures */ + GlFdNode *fd_nodes; /* The list of fd event descriptions */ + fd_set rfds; /* The set of fds to watch for readability */ + fd_set wfds; /* The set of fds to watch for writability */ + fd_set ufds; /* The set of fds to watch for urgent data */ + int max_fd; /* The maximum file-descriptor being watched */ +#endif +}; + +/* + * Define the max amount of space needed to store a termcap terminal + * description. Unfortunately this has to be done by guesswork, so + * there is the potential for buffer overflows if we guess too small. + * Fortunately termcap has been replaced by terminfo on most + * platforms, and with terminfo this isn't an issue. The value that I + * am using here is the conventional value, as recommended by certain + * web references. + */ +#ifdef USE_TERMCAP +#define TERMCAP_BUF_SIZE 2048 +#endif + +/* + * Set the size of the string segments used to store terminal capability + * strings. + */ +#define CAPMEM_SEGMENT_SIZE 512 + +/* + * If no terminal size information is available, substitute the + * following vt100 default sizes. + */ +#define GL_DEF_NLINE 24 +#define GL_DEF_NCOLUMN 80 + +/* + * List the signals that we need to catch. In general these are + * those that by default terminate or suspend the process, since + * in such cases we need to restore terminal settings. + */ +static const struct GlDefSignal { + int signo; /* The number of the signal */ + unsigned flags; /* A bitwise union of GlSignalFlags enumerators */ + GlAfterSignal after; /* What to do after the signal has been delivered */ + int errno_value; /* What to set errno to */ +} gl_signal_list[] = { + {SIGABRT, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, + {SIGINT, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, + {SIGTERM, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, + {SIGALRM, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, + {SIGCONT, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#if defined(SIGHUP) +#ifdef ENOTTY + {SIGHUP, GLS_SUSPEND_INPUT, GLS_ABORT, ENOTTY}, +#else + {SIGHUP, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, +#endif +#endif +#if defined(SIGPIPE) +#ifdef EPIPE + {SIGPIPE, GLS_SUSPEND_INPUT, GLS_ABORT, EPIPE}, +#else + {SIGPIPE, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, +#endif +#endif +#ifdef SIGPWR + {SIGPWR, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +#ifdef SIGQUIT + {SIGQUIT, GLS_SUSPEND_INPUT, GLS_ABORT, EINTR}, +#endif +#ifdef SIGTSTP + {SIGTSTP, GLS_SUSPEND_INPUT, GLS_CONTINUE, 0}, +#endif +#ifdef SIGTTIN + {SIGTTIN, GLS_SUSPEND_INPUT, GLS_CONTINUE, 0}, +#endif +#ifdef SIGTTOU + {SIGTTOU, GLS_SUSPEND_INPUT, GLS_CONTINUE, 0}, +#endif +#ifdef SIGUSR1 + {SIGUSR1, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +#ifdef SIGUSR2 + {SIGUSR2, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +#ifdef SIGVTALRM + {SIGVTALRM, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +#ifdef SIGWINCH + {SIGWINCH, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +#ifdef SIGXCPU + {SIGXCPU, GLS_RESTORE_ENV, GLS_CONTINUE, 0}, +#endif +}; + +/* + * Define file-scope variables for use in signal handlers. + */ +static volatile sig_atomic_t gl_pending_signal = -1; +static sigjmp_buf gl_setjmp_buffer; + +static void gl_signal_handler(int signo); + +static int gl_check_caught_signal(GetLine *gl); + +/* + * Define a tab to be a string of 8 spaces. + */ +#define TAB_WIDTH 8 + +/* + * Does the system send us SIGWINCH signals when the terminal size + * changes? + */ +#ifdef USE_SIGWINCH +static int gl_resize_terminal(GetLine *gl, int redisplay); +#endif + +/* + * Getline calls this to temporarily override certain signal handlers + * of the calling program. + */ +static int gl_override_signal_handlers(GetLine *gl); + +/* + * Getline calls this to restore the signal handlers of the calling + * program. + */ +static int gl_restore_signal_handlers(GetLine *gl); + +/* + * Put the terminal into raw input mode, after saving the original + * terminal attributes in gl->oldattr. + */ +static int gl_raw_terminal_mode(GetLine *gl); + +/* + * Restore the terminal attributes from gl->oldattr. + */ +static int gl_restore_terminal_attributes(GetLine *gl); + +/* + * Read a line from the user in raw mode. + */ +static int gl_get_input_line(GetLine *gl, const char *start_line, + int start_pos); + +/* + * Set the largest key-sequence that can be handled. + */ +#define GL_KEY_MAX 64 + +/* + * Handle the receipt of the potential start of a new key-sequence from + * the user. + */ +static int gl_interpret_char(GetLine *gl, char c); + +/* + * Bind a single control or meta character to an action. + */ +static int gl_bind_control_char(GetLine *gl, KtBinder binder, + char c, const char *action); + +/* + * Set up terminal-specific key bindings. + */ +static int gl_bind_terminal_keys(GetLine *gl); + +/* + * Lookup terminal control string and size information. + */ +static int gl_control_strings(GetLine *gl, const char *term); + +/* + * Wrappers around the terminfo and termcap functions that lookup + * strings in the terminal information databases. + */ +#ifdef USE_TERMINFO +static const char *gl_tigetstr(GetLine *gl, const char *name); +#elif defined(USE_TERMCAP) +static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr); +#endif + +/* + * Output a binary string directly to the terminal. + */ +static int gl_output_raw_string(GetLine *gl, const char *string); + +/* + * Output a terminal control sequence. + */ +static int gl_output_control_sequence(GetLine *gl, int nline, + const char *string); + +/* + * Output a character or string to the terminal after converting tabs + * to spaces and control characters to a caret followed by the modified + * character. + */ +static int gl_output_char(GetLine *gl, char c, char pad); +static int gl_output_string(GetLine *gl, const char *string, char pad); + +/* + * Delete nc characters starting from the one under the cursor. + * Optionally copy the deleted characters to the cut buffer. + */ +static int gl_delete_chars(GetLine *gl, int nc, int cut); + +/* + * Add a character to the line buffer at the current cursor position, + * inserting or overwriting according the current mode. + */ +static int gl_add_char_to_line(GetLine *gl, char c); + +/* + * Insert/append a string to the line buffer and terminal at the current + * cursor position. + */ +static int gl_add_string_to_line(GetLine *gl, const char *s); + +/* + * Read a single character from the terminal. + */ +static int gl_read_character(GetLine *gl, char *c); + + +/* + * Move the terminal cursor n positions to the left or right. + */ +static int gl_terminal_move_cursor(GetLine *gl, int n); + +/* + * Move the terminal cursor to a given position. + */ +static int gl_set_term_curpos(GetLine *gl, int term_curpos); + +/* + * Set the position of the cursor both in the line input buffer and on the + * terminal. + */ +static int gl_place_cursor(GetLine *gl, int buff_curpos); + +/* + * Return the terminal cursor position that corresponds to a given + * line buffer cursor position. + */ +static int gl_buff_curpos_to_term_curpos(GetLine *gl, int buff_curpos); + +/* + * Return the number of terminal characters needed to display a + * given raw character. + */ +static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos); + +/* + * Return the number of terminal characters needed to display a + * given substring. + */ +static int gl_displayed_string_width(GetLine *gl, const char *string, int nc, + int term_curpos); +/* + * Return non-zero if 'c' is to be considered part of a word. + */ +static int gl_is_word_char(int c); + +/* + * Read a tecla configuration file. + */ +static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who); + +/* + * Read a tecla configuration string. + */ +static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who); + +/* + * Define the callback function used by _gl_parse_config_line() to + * read the next character of a configuration stream. + */ +#define GLC_GETC_FN(fn) int (fn)(void *stream) +typedef GLC_GETC_FN(GlcGetcFn); + +static GLC_GETC_FN(glc_file_getc); /* Read from a file */ +static GLC_GETC_FN(glc_buff_getc); /* Read from a string */ + +/* + * Parse a single configuration command line. + */ +static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn, + const char *origin, KtBinder who, int *lineno); + +/* + * Bind the actual arrow key bindings to match those of the symbolic + * arrow-key bindings. + */ +static int _gl_bind_arrow_keys(GetLine *gl); + +/* + * Copy the binding of the specified symbolic arrow-key binding to + * the terminal specific, and default arrow-key key-sequences. + */ +static int _gl_rebind_arrow_key(KeyTab *bindings, const char *name, + const char *term_seq, + const char *def_seq1, + const char *def_seq2); + +/* + * After the gl_read_from_file() action has been used to tell gl_get_line() + * to temporarily read input from a file, gl_revert_input() arranges + * for input to be reverted to the input stream last registered with + * gl_change_terminal(). + */ +static void gl_revert_input(GetLine *gl); + +/* + * Flush unwritten characters to the terminal. + */ +static int gl_flush_output(GetLine *gl); + +/* + * Change the editor style being emulated. + */ +static int gl_change_editor(GetLine *gl, GlEditor editor); + +/* + * Searching in a given direction, return the index of a given (or + * read) character in the input line, or the character that precedes + * it in the specified search direction. Return -1 if not found. + */ +static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c); + +/* + * Return the buffer index of the nth word ending after the cursor. + */ +static int gl_nth_word_end_forward(GetLine *gl, int n); + +/* + * Return the buffer index of the nth word start after the cursor. + */ +static int gl_nth_word_start_forward(GetLine *gl, int n); + +/* + * Return the buffer index of the nth word start before the cursor. + */ +static int gl_nth_word_start_backward(GetLine *gl, int n); + +/* + * When called when vi command mode is enabled, this function saves the + * current line and cursor position for potential restoration later + * by the vi undo command. + */ +static void gl_save_for_undo(GetLine *gl); + +/* + * If in vi mode, switch to vi command mode. + */ +static void gl_vi_command_mode(GetLine *gl); + +/* + * In vi mode this is used to delete up to or onto a given or read + * character in the input line. Also switch to insert mode if requested + * after the deletion. + */ +static int gl_delete_find(GetLine *gl, int count, char c, int forward, + int onto, int change); + +/* + * Copy the characters between the cursor and the count'th instance of + * a specified (or read) character in the input line, into the cut buffer. + */ +static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto); + +/* + * Return the line index of the parenthesis that either matches the one under + * the cursor, or not over a parenthesis character, the index of the next + * close parenthesis. Return -1 if not found. + */ +static int gl_index_of_matching_paren(GetLine *gl); + +/* + * Replace a malloc'd string (or NULL), with another malloc'd copy of + * a string (or NULL). + */ +static int gl_record_string(char **sptr, const char *string); + +/* + * Enumerate text display attributes as powers of two, suitable for + * use in a bit-mask. + */ +typedef enum { + GL_TXT_STANDOUT=1, /* Display text highlighted */ + GL_TXT_UNDERLINE=2, /* Display text underlined */ + GL_TXT_REVERSE=4, /* Display text with reverse video */ + GL_TXT_BLINK=8, /* Display blinking text */ + GL_TXT_DIM=16, /* Display text in a dim font */ + GL_TXT_BOLD=32 /* Display text using a bold font */ +} GlTextAttr; + +/* + * Display the prompt regardless of the current visibility mode. + */ +static int gl_display_prompt(GetLine *gl); + +/* + * Return the number of characters used by the prompt on the terminal. + */ +static int gl_displayed_prompt_width(GetLine *gl); + +/* + * Prepare the return the current input line to the caller of gl_get_line(). + */ +static int gl_line_ended(GetLine *gl, int newline_char, int archive); + +/* + * Set the maximum length of a line in a user's tecla configuration + * file (not counting comments). + */ +#define GL_CONF_BUFLEN 100 + +/* + * Set the maximum number of arguments supported by individual commands + * in tecla configuration files. + */ +#define GL_CONF_MAXARG 10 + +/* + * Prototype the available action functions. + */ +static KT_KEY_FN(gl_user_interrupt); +static KT_KEY_FN(gl_abort); +static KT_KEY_FN(gl_suspend); +static KT_KEY_FN(gl_stop_output); +static KT_KEY_FN(gl_start_output); +static KT_KEY_FN(gl_literal_next); +static KT_KEY_FN(gl_cursor_left); +static KT_KEY_FN(gl_cursor_right); +static KT_KEY_FN(gl_insert_mode); +static KT_KEY_FN(gl_beginning_of_line); +static KT_KEY_FN(gl_end_of_line); +static KT_KEY_FN(gl_delete_line); +static KT_KEY_FN(gl_kill_line); +static KT_KEY_FN(gl_forward_word); +static KT_KEY_FN(gl_backward_word); +static KT_KEY_FN(gl_forward_delete_char); +static KT_KEY_FN(gl_backward_delete_char); +static KT_KEY_FN(gl_forward_delete_word); +static KT_KEY_FN(gl_backward_delete_word); +static KT_KEY_FN(gl_delete_refind); +static KT_KEY_FN(gl_delete_invert_refind); +static KT_KEY_FN(gl_delete_to_column); +static KT_KEY_FN(gl_delete_to_parenthesis); +static KT_KEY_FN(gl_forward_delete_find); +static KT_KEY_FN(gl_backward_delete_find); +static KT_KEY_FN(gl_forward_delete_to); +static KT_KEY_FN(gl_backward_delete_to); +static KT_KEY_FN(gl_upcase_word); +static KT_KEY_FN(gl_downcase_word); +static KT_KEY_FN(gl_capitalize_word); +static KT_KEY_FN(gl_redisplay); +static KT_KEY_FN(gl_clear_screen); +static KT_KEY_FN(gl_transpose_chars); +static KT_KEY_FN(gl_set_mark); +static KT_KEY_FN(gl_exchange_point_and_mark); +static KT_KEY_FN(gl_kill_region); +static KT_KEY_FN(gl_copy_region_as_kill); +static KT_KEY_FN(gl_yank); +static KT_KEY_FN(gl_up_history); +static KT_KEY_FN(gl_down_history); +static KT_KEY_FN(gl_history_search_backward); +static KT_KEY_FN(gl_history_re_search_backward); +static KT_KEY_FN(gl_history_search_forward); +static KT_KEY_FN(gl_history_re_search_forward); +static KT_KEY_FN(gl_complete_word); +static KT_KEY_FN(gl_expand_filename); +static KT_KEY_FN(gl_del_char_or_list_or_eof); +static KT_KEY_FN(gl_list_or_eof); +static KT_KEY_FN(gl_read_from_file); +static KT_KEY_FN(gl_beginning_of_history); +static KT_KEY_FN(gl_end_of_history); +static KT_KEY_FN(gl_digit_argument); +static KT_KEY_FN(gl_newline); +static KT_KEY_FN(gl_repeat_history); +static KT_KEY_FN(gl_vi_insert); +static KT_KEY_FN(gl_vi_overwrite); +static KT_KEY_FN(gl_change_case); +static KT_KEY_FN(gl_vi_insert_at_bol); +static KT_KEY_FN(gl_vi_append_at_eol); +static KT_KEY_FN(gl_vi_append); +static KT_KEY_FN(gl_list_glob); +static KT_KEY_FN(gl_backward_kill_line); +static KT_KEY_FN(gl_goto_column); +static KT_KEY_FN(gl_forward_to_word); +static KT_KEY_FN(gl_vi_replace_char); +static KT_KEY_FN(gl_vi_change_rest_of_line); +static KT_KEY_FN(gl_vi_change_line); +static KT_KEY_FN(gl_vi_change_to_bol); +static KT_KEY_FN(gl_vi_change_refind); +static KT_KEY_FN(gl_vi_change_invert_refind); +static KT_KEY_FN(gl_vi_change_to_column); +static KT_KEY_FN(gl_vi_change_to_parenthesis); +static KT_KEY_FN(gl_vi_forward_change_word); +static KT_KEY_FN(gl_vi_backward_change_word); +static KT_KEY_FN(gl_vi_forward_change_find); +static KT_KEY_FN(gl_vi_backward_change_find); +static KT_KEY_FN(gl_vi_forward_change_to); +static KT_KEY_FN(gl_vi_backward_change_to); +static KT_KEY_FN(gl_vi_forward_change_char); +static KT_KEY_FN(gl_vi_backward_change_char); +static KT_KEY_FN(gl_forward_copy_char); +static KT_KEY_FN(gl_backward_copy_char); +static KT_KEY_FN(gl_forward_find_char); +static KT_KEY_FN(gl_backward_find_char); +static KT_KEY_FN(gl_forward_to_char); +static KT_KEY_FN(gl_backward_to_char); +static KT_KEY_FN(gl_repeat_find_char); +static KT_KEY_FN(gl_invert_refind_char); +static KT_KEY_FN(gl_append_yank); +static KT_KEY_FN(gl_backward_copy_word); +static KT_KEY_FN(gl_forward_copy_word); +static KT_KEY_FN(gl_copy_to_bol); +static KT_KEY_FN(gl_copy_refind); +static KT_KEY_FN(gl_copy_invert_refind); +static KT_KEY_FN(gl_copy_to_column); +static KT_KEY_FN(gl_copy_to_parenthesis); +static KT_KEY_FN(gl_copy_rest_of_line); +static KT_KEY_FN(gl_copy_line); +static KT_KEY_FN(gl_backward_copy_find); +static KT_KEY_FN(gl_forward_copy_find); +static KT_KEY_FN(gl_backward_copy_to); +static KT_KEY_FN(gl_forward_copy_to); +static KT_KEY_FN(gl_vi_undo); +static KT_KEY_FN(gl_emacs_editing_mode); +static KT_KEY_FN(gl_vi_editing_mode); +static KT_KEY_FN(gl_ring_bell); +static KT_KEY_FN(gl_vi_repeat_change); +static KT_KEY_FN(gl_find_parenthesis); +static KT_KEY_FN(gl_read_init_files); +static KT_KEY_FN(gl_list_history); + +/* + * Name the available action functions. + */ +static const struct {const char *name; KT_KEY_FN(*fn);} gl_actions[] = { + {"user-interrupt", gl_user_interrupt}, + {"abort", gl_abort}, + {"suspend", gl_suspend}, + {"stop-output", gl_stop_output}, + {"start-output", gl_start_output}, + {"literal-next", gl_literal_next}, + {"cursor-right", gl_cursor_right}, + {"cursor-left", gl_cursor_left}, + {"insert-mode", gl_insert_mode}, + {"beginning-of-line", gl_beginning_of_line}, + {"end-of-line", gl_end_of_line}, + {"delete-line", gl_delete_line}, + {"kill-line", gl_kill_line}, + {"forward-word", gl_forward_word}, + {"backward-word", gl_backward_word}, + {"forward-delete-char", gl_forward_delete_char}, + {"backward-delete-char", gl_backward_delete_char}, + {"forward-delete-word", gl_forward_delete_word}, + {"backward-delete-word", gl_backward_delete_word}, + {"delete-refind", gl_delete_refind}, + {"delete-invert-refind", gl_delete_invert_refind}, + {"delete-to-column", gl_delete_to_column}, + {"delete-to-parenthesis", gl_delete_to_parenthesis}, + {"forward-delete-find", gl_forward_delete_find}, + {"backward-delete-find", gl_backward_delete_find}, + {"forward-delete-to", gl_forward_delete_to}, + {"backward-delete-to", gl_backward_delete_to}, + {"upcase-word", gl_upcase_word}, + {"downcase-word", gl_downcase_word}, + {"capitalize-word", gl_capitalize_word}, + {"redisplay", gl_redisplay}, + {"clear-screen", gl_clear_screen}, + {"transpose-chars", gl_transpose_chars}, + {"set-mark", gl_set_mark}, + {"exchange-point-and-mark", gl_exchange_point_and_mark}, + {"kill-region", gl_kill_region}, + {"copy-region-as-kill", gl_copy_region_as_kill}, + {"yank", gl_yank}, + {"up-history", gl_up_history}, + {"down-history", gl_down_history}, + {"history-search-backward", gl_history_search_backward}, + {"history-re-search-backward", gl_history_re_search_backward}, + {"history-search-forward", gl_history_search_forward}, + {"history-re-search-forward", gl_history_re_search_forward}, + {"complete-word", gl_complete_word}, + {"expand-filename", gl_expand_filename}, + {"del-char-or-list-or-eof", gl_del_char_or_list_or_eof}, + {"read-from-file", gl_read_from_file}, + {"beginning-of-history", gl_beginning_of_history}, + {"end-of-history", gl_end_of_history}, + {"digit-argument", gl_digit_argument}, + {"newline", gl_newline}, + {"repeat-history", gl_repeat_history}, + {"vi-insert", gl_vi_insert}, + {"vi-overwrite", gl_vi_overwrite}, + {"vi-insert-at-bol", gl_vi_insert_at_bol}, + {"vi-append-at-eol", gl_vi_append_at_eol}, + {"vi-append", gl_vi_append}, + {"change-case", gl_change_case}, + {"list-glob", gl_list_glob}, + {"backward-kill-line", gl_backward_kill_line}, + {"goto-column", gl_goto_column}, + {"forward-to-word", gl_forward_to_word}, + {"vi-replace-char", gl_vi_replace_char}, + {"vi-change-rest-of-line", gl_vi_change_rest_of_line}, + {"vi-change-line", gl_vi_change_line}, + {"vi-change-to-bol", gl_vi_change_to_bol}, + {"vi-change-refind", gl_vi_change_refind}, + {"vi-change-invert-refind", gl_vi_change_invert_refind}, + {"vi-change-to-column", gl_vi_change_to_column}, + {"vi-change-to-parenthesis", gl_vi_change_to_parenthesis}, + {"forward-copy-char", gl_forward_copy_char}, + {"backward-copy-char", gl_backward_copy_char}, + {"forward-find-char", gl_forward_find_char}, + {"backward-find-char", gl_backward_find_char}, + {"forward-to-char", gl_forward_to_char}, + {"backward-to-char", gl_backward_to_char}, + {"repeat-find-char", gl_repeat_find_char}, + {"invert-refind-char", gl_invert_refind_char}, + {"append-yank", gl_append_yank}, + {"backward-copy-word", gl_backward_copy_word}, + {"forward-copy-word", gl_forward_copy_word}, + {"copy-to-bol", gl_copy_to_bol}, + {"copy-refind", gl_copy_refind}, + {"copy-invert-refind", gl_copy_invert_refind}, + {"copy-to-column", gl_copy_to_column}, + {"copy-to-parenthesis", gl_copy_to_parenthesis}, + {"copy-rest-of-line", gl_copy_rest_of_line}, + {"copy-line", gl_copy_line}, + {"backward-copy-find", gl_backward_copy_find}, + {"forward-copy-find", gl_forward_copy_find}, + {"backward-copy-to", gl_backward_copy_to}, + {"forward-copy-to", gl_forward_copy_to}, + {"list-or-eof", gl_list_or_eof}, + {"vi-undo", gl_vi_undo}, + {"vi-backward-change-word", gl_vi_backward_change_word}, + {"vi-forward-change-word", gl_vi_forward_change_word}, + {"vi-backward-change-find", gl_vi_backward_change_find}, + {"vi-forward-change-find", gl_vi_forward_change_find}, + {"vi-backward-change-to", gl_vi_backward_change_to}, + {"vi-forward-change-to", gl_vi_forward_change_to}, + {"vi-backward-change-char", gl_vi_backward_change_char}, + {"vi-forward-change-char", gl_vi_forward_change_char}, + {"emacs-mode", gl_emacs_editing_mode}, + {"vi-mode", gl_vi_editing_mode}, + {"ring-bell", gl_ring_bell}, + {"vi-repeat-change", gl_vi_repeat_change}, + {"find-parenthesis", gl_find_parenthesis}, + {"read-init-files", gl_read_init_files}, + {"list-history", gl_list_history}, +}; + +/* + * Define the default key-bindings in emacs mode. + */ +static const KtKeyBinding gl_emacs_bindings[] = { + {"right", "cursor-right"}, + {"^F", "cursor-right"}, + {"left", "cursor-left"}, + {"^B", "cursor-left"}, + {"M-i", "insert-mode"}, + {"M-I", "insert-mode"}, + {"^A", "beginning-of-line"}, + {"^E", "end-of-line"}, + {"^U", "delete-line"}, + {"^K", "kill-line"}, + {"M-f", "forward-word"}, + {"M-F", "forward-word"}, + {"M-b", "backward-word"}, + {"M-B", "backward-word"}, + {"^D", "del-char-or-list-or-eof"}, + {"^H", "backward-delete-char"}, + {"^?", "backward-delete-char"}, + {"M-d", "forward-delete-word"}, + {"M-D", "forward-delete-word"}, + {"M-^H", "backward-delete-word"}, + {"M-^?", "backward-delete-word"}, + {"M-u", "upcase-word"}, + {"M-U", "upcase-word"}, + {"M-l", "downcase-word"}, + {"M-L", "downcase-word"}, + {"M-c", "capitalize-word"}, + {"M-C", "capitalize-word"}, + {"^R", "redisplay"}, + {"^L", "clear-screen"}, + {"^T", "transpose-chars"}, + {"^@", "set-mark"}, + {"^X^X", "exchange-point-and-mark"}, + {"^W", "kill-region"}, + {"M-w", "copy-region-as-kill"}, + {"M-W", "copy-region-as-kill"}, + {"^Y", "yank"}, + {"^P", "up-history"}, + {"up", "up-history"}, + {"^N", "down-history"}, + {"down", "down-history"}, + {"M-p", "history-search-backward"}, + {"M-P", "history-search-backward"}, + {"M-n", "history-search-forward"}, + {"M-N", "history-search-forward"}, + {"\t", "complete-word"}, + {"^X*", "expand-filename"}, + {"^X^F", "read-from-file"}, + {"^X^R", "read-init-files"}, + {"^Xg", "list-glob"}, + {"^XG", "list-glob"}, + {"^Xh", "list-history"}, + {"^XH", "list-history"}, + {"M-<", "beginning-of-history"}, + {"M->", "end-of-history"}, + {"M-0", "digit-argument"}, + {"M-1", "digit-argument"}, + {"M-2", "digit-argument"}, + {"M-3", "digit-argument"}, + {"M-4", "digit-argument"}, + {"M-5", "digit-argument"}, + {"M-6", "digit-argument"}, + {"M-7", "digit-argument"}, + {"M-8", "digit-argument"}, + {"M-9", "digit-argument"}, + {"\r", "newline"}, + {"\n", "newline"}, + {"M-o", "repeat-history"}, + {"M-C-v", "vi-mode"}, +}; + +/* + * Define the default key-bindings in vi mode. Note that in vi-mode + * meta-key bindings are command-mode bindings. For example M-i first + * switches to command mode if not already in that mode, then moves + * the cursor one position right, as in vi. + */ +static const KtKeyBinding gl_vi_bindings[] = { + {"^D", "list-or-eof"}, + {"^G", "list-glob"}, + {"^H", "backward-delete-char"}, + {"\t", "complete-word"}, + {"\r", "newline"}, + {"\n", "newline"}, + {"^L", "clear-screen"}, + {"^N", "down-history"}, + {"^P", "up-history"}, + {"^R", "redisplay"}, + {"^U", "backward-kill-line"}, + {"^W", "backward-delete-word"}, + {"^X^F", "read-from-file"}, + {"^X^R", "read-init-files"}, + {"^X*", "expand-filename"}, + {"^?", "backward-delete-char"}, + {"M- ", "cursor-right"}, + {"M-$", "end-of-line"}, + {"M-*", "expand-filename"}, + {"M-+", "down-history"}, + {"M--", "up-history"}, + {"M-<", "beginning-of-history"}, + {"M->", "end-of-history"}, + {"M-^", "beginning-of-line"}, + {"M-;", "repeat-find-char"}, + {"M-,", "invert-refind-char"}, + {"M-|", "goto-column"}, + {"M-~", "change-case"}, + {"M-.", "vi-repeat-change"}, + {"M-%", "find-parenthesis"}, + {"M-0", "digit-argument"}, + {"M-1", "digit-argument"}, + {"M-2", "digit-argument"}, + {"M-3", "digit-argument"}, + {"M-4", "digit-argument"}, + {"M-5", "digit-argument"}, + {"M-6", "digit-argument"}, + {"M-7", "digit-argument"}, + {"M-8", "digit-argument"}, + {"M-9", "digit-argument"}, + {"M-a", "vi-append"}, + {"M-A", "vi-append-at-eol"}, + {"M-b", "backward-word"}, + {"M-B", "backward-word"}, + {"M-C", "vi-change-rest-of-line"}, + {"M-cb", "vi-backward-change-word"}, + {"M-cB", "vi-backward-change-word"}, + {"M-cc", "vi-change-line"}, + {"M-ce", "vi-forward-change-word"}, + {"M-cE", "vi-forward-change-word"}, + {"M-cw", "vi-forward-change-word"}, + {"M-cW", "vi-forward-change-word"}, + {"M-cF", "vi-backward-change-find"}, + {"M-cf", "vi-forward-change-find"}, + {"M-cT", "vi-backward-change-to"}, + {"M-ct", "vi-forward-change-to"}, + {"M-c;", "vi-change-refind"}, + {"M-c,", "vi-change-invert-refind"}, + {"M-ch", "vi-backward-change-char"}, + {"M-c^H", "vi-backward-change-char"}, + {"M-c^?", "vi-backward-change-char"}, + {"M-cl", "vi-forward-change-char"}, + {"M-c ", "vi-forward-change-char"}, + {"M-c^", "vi-change-to-bol"}, + {"M-c0", "vi-change-to-bol"}, + {"M-c$", "vi-change-rest-of-line"}, + {"M-c|", "vi-change-to-column"}, + {"M-c%", "vi-change-to-parenthesis"}, + {"M-dh", "backward-delete-char"}, + {"M-d^H", "backward-delete-char"}, + {"M-d^?", "backward-delete-char"}, + {"M-dl", "forward-delete-char"}, + {"M-d ", "forward-delete-char"}, + {"M-dd", "delete-line"}, + {"M-db", "backward-delete-word"}, + {"M-dB", "backward-delete-word"}, + {"M-de", "forward-delete-word"}, + {"M-dE", "forward-delete-word"}, + {"M-dw", "forward-delete-word"}, + {"M-dW", "forward-delete-word"}, + {"M-dF", "backward-delete-find"}, + {"M-df", "forward-delete-find"}, + {"M-dT", "backward-delete-to"}, + {"M-dt", "forward-delete-to"}, + {"M-d;", "delete-refind"}, + {"M-d,", "delete-invert-refind"}, + {"M-d^", "backward-kill-line"}, + {"M-d0", "backward-kill-line"}, + {"M-d$", "kill-line"}, + {"M-D", "kill-line"}, + {"M-d|", "delete-to-column"}, + {"M-d%", "delete-to-parenthesis"}, + {"M-e", "forward-word"}, + {"M-E", "forward-word"}, + {"M-f", "forward-find-char"}, + {"M-F", "backward-find-char"}, + {"M--", "up-history"}, + {"M-h", "cursor-left"}, + {"M-H", "beginning-of-history"}, + {"M-i", "vi-insert"}, + {"M-I", "vi-insert-at-bol"}, + {"M-j", "down-history"}, + {"M-J", "history-search-forward"}, + {"M-k", "up-history"}, + {"M-K", "history-search-backward"}, + {"M-l", "cursor-right"}, + {"M-L", "end-of-history"}, + {"M-n", "history-re-search-forward"}, + {"M-N", "history-re-search-backward"}, + {"M-p", "append-yank"}, + {"M-P", "yank"}, + {"M-r", "vi-replace-char"}, + {"M-R", "vi-overwrite"}, + {"M-s", "vi-forward-change-char"}, + {"M-S", "vi-change-line"}, + {"M-t", "forward-to-char"}, + {"M-T", "backward-to-char"}, + {"M-u", "vi-undo"}, + {"M-w", "forward-to-word"}, + {"M-W", "forward-to-word"}, + {"M-x", "forward-delete-char"}, + {"M-X", "backward-delete-char"}, + {"M-yh", "backward-copy-char"}, + {"M-y^H", "backward-copy-char"}, + {"M-y^?", "backward-copy-char"}, + {"M-yl", "forward-copy-char"}, + {"M-y ", "forward-copy-char"}, + {"M-ye", "forward-copy-word"}, + {"M-yE", "forward-copy-word"}, + {"M-yw", "forward-copy-word"}, + {"M-yW", "forward-copy-word"}, + {"M-yb", "backward-copy-word"}, + {"M-yB", "backward-copy-word"}, + {"M-yf", "forward-copy-find"}, + {"M-yF", "backward-copy-find"}, + {"M-yt", "forward-copy-to"}, + {"M-yT", "backward-copy-to"}, + {"M-y;", "copy-refind"}, + {"M-y,", "copy-invert-refind"}, + {"M-y^", "copy-to-bol"}, + {"M-y0", "copy-to-bol"}, + {"M-y$", "copy-rest-of-line"}, + {"M-yy", "copy-line"}, + {"M-Y", "copy-line"}, + {"M-y|", "copy-to-column"}, + {"M-y%", "copy-to-parenthesis"}, + {"M-^E", "emacs-mode"}, + {"M-^H", "cursor-left"}, + {"M-^?", "cursor-left"}, + {"M-^L", "clear-screen"}, + {"M-^N", "down-history"}, + {"M-^P", "up-history"}, + {"M-^R", "redisplay"}, + {"M-^D", "list-or-eof"}, + {"M-\r", "newline"}, + {"M-\t", "complete-word"}, + {"M-\n", "newline"}, + {"M-^X^R", "read-init-files"}, + {"M-^Xh", "list-history"}, + {"M-^XH", "list-history"}, + {"down", "down-history"}, + {"up", "up-history"}, + {"left", "cursor-left"}, + {"right", "cursor-right"}, +}; + +/*....................................................................... + * Create a new GetLine object. + * + * Input: + * linelen size_t The maximum line length to allow for. + * histlen size_t The number of bytes to allocate for recording + * a circular buffer of history lines. + * Output: + * return GetLine * The new object, or NULL on error. + */ +GetLine *new_GetLine(size_t linelen, size_t histlen) +{ + GetLine *gl; /* The object to be returned */ + int i; +/* + * Check the arguments. + */ + if(linelen < 10) { + fprintf(stderr, "new_GetLine: Line length too small.\n"); + return NULL; + }; +/* + * Allocate the container. + */ + gl = (GetLine *) malloc(sizeof(GetLine)); + if(!gl) { + fprintf(stderr, "new_GetLine: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_GetLine(). + */ + gl->glh = NULL; + gl->cpl = NULL; + gl->cpl_fn = cpl_file_completions; + gl->cpl_data = NULL; + gl->ef = NULL; + gl->capmem = NULL; + gl->term = NULL; + gl->is_term = 0; + gl->input_fd = -1; + gl->output_fd = -1; + gl->input_fp = NULL; + gl->output_fp = NULL; + gl->file_fp = NULL; + gl->linelen = linelen; + gl->line = NULL; + gl->cutbuf = NULL; + gl->linelen = linelen; + gl->prompt = ""; + gl->prompt_len = 0; + gl->prompt_changed = 0; + gl->prompt_style = GL_LITERAL_PROMPT; + gl->vi.undo.line = NULL; + gl->vi.undo.buff_curpos = 0; + gl->vi.undo.ntotal = 0; + gl->vi.undo.saved = 0; + gl->vi.repeat.fn = 0; + gl->vi.repeat.count = 0; + gl->vi.repeat.input_curpos = 0; + gl->vi.repeat.command_curpos = 0; + gl->vi.repeat.input_char = '\0'; + gl->vi.repeat.saved = 0; + gl->vi.repeat.active = 0; + gl->sig_mem = NULL; + gl->sigs = NULL; + sigemptyset(&gl->old_signal_set); + sigemptyset(&gl->new_signal_set); + gl->bindings = NULL; + gl->ntotal = 0; + gl->buff_curpos = 0; + gl->term_curpos = 0; + gl->buff_mark = 0; + gl->insert_curpos = 0; + gl->insert = 1; + gl->number = -1; + gl->endline = 0; + gl->current_fn = 0; + gl->current_count = 0; + gl->preload_id = 0; + gl->preload_history = 0; + gl->keyseq_count = 0; + gl->last_search = -1; + gl->editor = GL_EMACS_MODE; + gl->silence_bell = 0; + gl->vi.command = 0; + gl->vi.find_forward = 0; + gl->vi.find_onto = 0; + gl->vi.find_char = '\0'; + gl->left = NULL; + gl->right = NULL; + gl->up = NULL; + gl->down = NULL; + gl->home = NULL; + gl->bol = 0; + gl->clear_eol = NULL; + gl->clear_eod = NULL; + gl->u_arrow = NULL; + gl->d_arrow = NULL; + gl->l_arrow = NULL; + gl->r_arrow = NULL; + gl->sound_bell = NULL; + gl->bold = NULL; + gl->underline = NULL; + gl->standout = NULL; + gl->dim = NULL; + gl->reverse = NULL; + gl->blink = NULL; + gl->text_attr_off = NULL; + gl->nline = 0; + gl->ncolumn = 0; +#ifdef USE_TERMINFO + gl->left_n = NULL; + gl->right_n = NULL; +#elif defined(USE_TERMCAP) + gl->tgetent_buf = NULL; + gl->tgetstr_buf = NULL; +#endif + gl->app_file = NULL; + gl->user_file = NULL; + gl->configured = 0; + gl->echo = 1; + gl->last_signal = -1; +#ifdef HAVE_SELECT + gl->fd_node_mem = NULL; + gl->fd_nodes = NULL; + FD_ZERO(&gl->rfds); + FD_ZERO(&gl->wfds); + FD_ZERO(&gl->ufds); + gl->max_fd = 0; +#endif +/* + * Allocate the history buffer. + */ + gl->glh = _new_GlHistory(histlen); + if(!gl->glh) + return del_GetLine(gl); +/* + * Allocate the resource object for file-completion. + */ + gl->cpl = new_WordCompletion(); + if(!gl->cpl) + return del_GetLine(gl); +/* + * Allocate the resource object for file-completion. + */ + gl->ef = new_ExpandFile(); + if(!gl->ef) + return del_GetLine(gl); +/* + * Allocate a string-segment memory allocator for use in storing terminal + * capablity strings. + */ + gl->capmem = _new_StringGroup(CAPMEM_SEGMENT_SIZE); + if(!gl->capmem) + return del_GetLine(gl); +/* + * Allocate a line buffer, leaving 2 extra characters for the terminating + * '\n' and '\0' characters + */ + gl->line = (char *) malloc(linelen + 2); + if(!gl->line) { + fprintf(stderr, + "new_GetLine: Insufficient memory to allocate line buffer.\n"); + return del_GetLine(gl); + }; + gl->line[0] = '\0'; +/* + * Allocate a cut buffer. + */ + gl->cutbuf = (char *) malloc(linelen + 2); + if(!gl->cutbuf) { + fprintf(stderr, + "new_GetLine: Insufficient memory to allocate cut buffer.\n"); + return del_GetLine(gl); + }; + gl->cutbuf[0] = '\0'; +/* + * Allocate a vi undo buffer. + */ + gl->vi.undo.line = (char *) malloc(linelen + 2); + if(!gl->vi.undo.line) { + fprintf(stderr, + "new_GetLine: Insufficient memory to allocate undo buffer.\n"); + return del_GetLine(gl); + }; + gl->vi.undo.line[0] = '\0'; +/* + * Allocate a freelist from which to allocate nodes for the list + * of signals. + */ + gl->sig_mem = _new_FreeList("new_GetLine", sizeof(GlSignalNode), + GLS_FREELIST_BLOCKING); + if(!gl->sig_mem) + return del_GetLine(gl); +/* + * Install dispositions for the default list of signals that gl_get_line() + * traps. + */ + for(i=0; isigno, sig->flags, sig->after, + sig->errno_value)) + return del_GetLine(gl); + }; +/* + * Allocate an empty table of key bindings. + */ + gl->bindings = _new_KeyTab(); + if(!gl->bindings) + return del_GetLine(gl); +/* + * Define the available actions that can be bound to key sequences. + */ + for(i=0; ibindings, gl_actions[i].name, gl_actions[i].fn)) + return del_GetLine(gl); + }; +/* + * Set up the default bindings. + */ + if(gl_change_editor(gl, gl->editor)) + return del_GetLine(gl); +/* + * Allocate termcap buffers. + */ +#ifdef USE_TERMCAP + gl->tgetent_buf = (char *) malloc(TERMCAP_BUF_SIZE); + gl->tgetstr_buf = (char *) malloc(TERMCAP_BUF_SIZE); + if(!gl->tgetent_buf || !gl->tgetstr_buf) { + fprintf(stderr, "new_GetLine: Insufficient memory for termcap buffers.\n"); + return del_GetLine(gl); + }; +#endif +/* + * Set up for I/O assuming stdin and stdout. + */ + if(gl_change_terminal(gl, stdin, stdout, getenv("TERM"))) + return del_GetLine(gl); +/* + * Create a freelist for use in allocating GlFdNode list nodes. + */ +#ifdef HAVE_SELECT + gl->fd_node_mem = _new_FreeList("new_GetLine", sizeof(GlFdNode), + GLFD_FREELIST_BLOCKING); + if(!gl->fd_node_mem) + return del_GetLine(gl); +#endif +/* + * We are done for now. + */ + return gl; +} + +/*....................................................................... + * Delete a GetLine object. + * + * Input: + * gl GetLine * The object to be deleted. + * Output: + * return GetLine * The deleted object (always NULL). + */ +GetLine *del_GetLine(GetLine *gl) +{ + if(gl) { + gl->glh = _del_GlHistory(gl->glh); + gl->cpl = del_WordCompletion(gl->cpl); + gl->ef = del_ExpandFile(gl->ef); + gl->capmem = _del_StringGroup(gl->capmem); + if(gl->line) + free(gl->line); + if(gl->cutbuf) + free(gl->cutbuf); + if(gl->vi.undo.line) + free(gl->vi.undo.line); + gl->sig_mem = _del_FreeList(NULL, gl->sig_mem, 1); + gl->sigs = NULL; /* Already freed by freeing sig_mem */ + gl->bindings = _del_KeyTab(gl->bindings); +#ifdef USE_TERMCAP + if(gl->tgetent_buf) + free(gl->tgetent_buf); + if(gl->tgetstr_buf) + free(gl->tgetstr_buf); +#endif + if(gl->file_fp) + fclose(gl->file_fp); + if(gl->term) + free(gl->term); +#ifdef HAVE_SELECT + gl->fd_node_mem = _del_FreeList(NULL, gl->fd_node_mem, 1); +#endif + free(gl); + }; + return NULL; +} + +/*....................................................................... + * Bind a control or meta character to an action. + * + * Input: + * gl GetLine * The resource object of this program. + * binder KtBinder The source of the binding. + * c char The control or meta character. + * If this is '\0', the call is ignored. + * action const char * The action name to bind the key to. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_bind_control_char(GetLine *gl, KtBinder binder, char c, + const char *action) +{ + char keyseq[2]; +/* + * Quietly reject binding to the NUL control character, since this + * is an ambiguous prefix of all bindings. + */ + if(c == '\0') + return 0; +/* + * Making sure not to bind characters which aren't either control or + * meta characters. + */ + if(IS_CTRL_CHAR(c) || IS_META_CHAR(c)) { + keyseq[0] = c; + keyseq[1] = '\0'; + } else { + return 0; + }; +/* + * Install the binding. + */ + return _kt_set_keybinding(gl->bindings, binder, keyseq, action); +} + +/*....................................................................... + * Read a line from the user. + * + * Input: + * gl GetLine * A resource object returned by new_GetLine(). + * prompt char * The prompt to prefix the line with. + * start_line char * The initial contents of the input line, or NULL + * if it should start out empty. + * start_pos int If start_line isn't NULL, this specifies the + * index of the character over which the cursor + * should initially be positioned within the line. + * If you just want it to follow the last character + * of the line, send -1. + * Output: + * return char * An internal buffer containing the input line, or + * NULL at the end of input. If the line fitted in + * the buffer there will be a '\n' newline character + * before the terminating '\0'. If it was truncated + * there will be no newline character, and the remains + * of the line should be retrieved via further calls + * to this function. + */ +char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos) +{ + int waserr = 0; /* True if an error occurs */ +/* + * Check the arguments. + */ + if(!gl || !prompt) { + fprintf(stderr, "gl_get_line: NULL argument(s).\n"); + return NULL; + }; +/* + * If this is the first call to this function since new_GetLine(), + * complete any postponed configuration. + */ + if(!gl->configured) { + (void) gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE); + gl->configured = 1; + }; +/* + * If input is temporarily being taken from a file, return lines + * from the file until the file is exhausted, then revert to + * the normal input stream. + */ + if(gl->file_fp) { + if(fgets(gl->line, gl->linelen, gl->file_fp)) + return gl->line; + gl_revert_input(gl); + }; +/* + * Is input coming from a non-interactive source? + */ + if(!gl->is_term) + return fgets(gl->line, gl->linelen, gl->input_fp); +/* + * Record the new prompt and its displayed width. + */ + gl_replace_prompt(gl, prompt); +/* + * Before installing our signal handler functions, record the fact + * that there are no pending signals. + */ + gl_pending_signal = -1; +/* + * Temporarily override the signal handlers of the calling program, + * so that we can intercept signals that would leave the terminal + * in a bad state. + */ + waserr = gl_override_signal_handlers(gl); +/* + * After recording the current terminal settings, switch the terminal + * into raw input mode. + */ + waserr = waserr || gl_raw_terminal_mode(gl); +/* + * Attempt to read the line. + */ + waserr = waserr || gl_get_input_line(gl, start_line, start_pos); +/* + * Restore terminal settings. + */ + gl_restore_terminal_attributes(gl); +/* + * Restore the signal handlers. + */ + gl_restore_signal_handlers(gl); +/* + * Having restored the program terminal and signal environment, + * re-submit any signals that were received. + */ + if(gl_pending_signal != -1) { + raise(gl_pending_signal); + waserr = 1; + }; +/* + * If gl_get_input_line() aborted input due to the user asking to + * temporarily read lines from a file, read the first line from + * this file. + */ + if(!waserr && gl->file_fp) + return gl_get_line(gl, prompt, NULL, 0); +/* + * Return the new input line. + */ + return waserr ? NULL : gl->line; +} + +/*....................................................................... + * Record of the signal handlers of the calling program, so that they + * can be restored later. + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_override_signal_handlers(GetLine *gl) +{ + GlSignalNode *sig; /* A node in the list of signals to be caught */ +/* + * Set up our signal handler. + */ + SigAction act; + act.sa_handler = gl_signal_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; +/* + * Get the process signal mask so that we can see which signals the + * calling program currently has blocked, and so that we can restore this + * mask before returning to the calling program. + */ + if(sigprocmask(SIG_SETMASK, NULL, &gl->old_signal_set) == -1) { + fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; +/* + * Form a new process signal mask from the list of signals that we have + * been asked to trap. + */ + sigemptyset(&gl->new_signal_set); + for(sig=gl->sigs; sig; sig=sig->next) { +/* + * Trap this signal? If it is blocked by the calling program and we + * haven't been told to unblock it, don't arrange to trap this signal. + */ + if(sig->flags & GLS_UNBLOCK_SIG || + !sigismember(&gl->old_signal_set, sig->signo)) { + if(sigaddset(&gl->new_signal_set, sig->signo) == -1) { + fprintf(stderr, "gl_get_line(): sigaddset error: %s\n", + strerror(errno)); + return 1; + }; + }; + }; +/* + * Before installing our signal handlers, block all of the signals + * that we are going to be trapping. + */ + if(sigprocmask(SIG_BLOCK, &gl->new_signal_set, NULL) == -1) { + fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; +/* + * Override the actions of the signals that we are trapping. + */ + for(sig=gl->sigs; sig; sig=sig->next) { + if(sigismember(&gl->new_signal_set, sig->signo) && + sigaction(sig->signo, &act, &sig->original)) { + fprintf(stderr, "gl_get_line(): sigaction error: %s\n", strerror(errno)); + return 1; + }; + }; +/* + * Just in case a SIGWINCH signal was sent to the process while our + * SIGWINCH signal handler wasn't in place, check to see if the terminal + * size needs updating. + */ +#ifdef USE_SIGWINCH + if(gl_resize_terminal(gl, 0)) + return 1; +#endif + return 0; +} + +/*....................................................................... + * Restore the signal handlers of the calling program. + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_restore_signal_handlers(GetLine *gl) +{ + GlSignalNode *sig; /* A node in the list of signals to be caught */ +/* + * Restore application signal handlers that were overriden + * by gl_override_signal_handlers(). + */ + for(sig=gl->sigs; sig; sig=sig->next) { + if(sigismember(&gl->new_signal_set, sig->signo) && + sigaction(sig->signo, &sig->original, NULL)) { + fprintf(stderr, "gl_get_line(): sigaction error: %s\n", strerror(errno)); + return 1; + }; + }; +/* + * Restore the original signal mask. + */ + if(sigprocmask(SIG_SETMASK, &gl->old_signal_set, NULL) == -1) { + fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; + return 0; +} + +/*....................................................................... + * This signal handler simply records the fact that a given signal was + * caught in the file-scope gl_pending_signal variable. + */ +static void gl_signal_handler(int signo) +{ + gl_pending_signal = signo; + siglongjmp(gl_setjmp_buffer, 1); +} + +/*....................................................................... + * Switch the terminal into raw mode after storing the previous terminal + * settings in gl->attributes. + * + * Input: + * gl GetLine * The resource object of this program. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_raw_terminal_mode(GetLine *gl) +{ + Termios newattr; /* The new terminal attributes */ +/* + * Record the current terminal attributes. + */ + if(tcgetattr(gl->input_fd, &gl->oldattr)) { + fprintf(stderr, "getline(): tcgetattr error: %s\n", strerror(errno)); + return 1; + }; +/* + * This function shouldn't do anything but record the current terminal + * attritubes if editing has been disabled. + */ + if(gl->editor == GL_NO_EDITOR) + return 0; +/* + * Modify the existing attributes. + */ + newattr = gl->oldattr; +/* + * Turn off local echo, canonical input mode and extended input processing. + */ + newattr.c_lflag &= ~(ECHO | ICANON | IEXTEN); +/* + * Don't translate carriage return to newline, turn off input parity + * checking, don't strip off 8th bit, turn off output flow control. + */ + newattr.c_iflag &= ~(ICRNL | INPCK | ISTRIP); +/* + * Clear size bits, turn off parity checking, and allow 8-bit characters. + */ + newattr.c_cflag &= ~(CSIZE | PARENB); + newattr.c_cflag |= CS8; +/* + * Turn off output processing. + */ + newattr.c_oflag &= ~(OPOST); +/* + * Request one byte at a time, without waiting. + */ + newattr.c_cc[VMIN] = 1; + newattr.c_cc[VTIME] = 0; +/* + * Install the new terminal modes. + */ + while(tcsetattr(gl->input_fd, TCSADRAIN, &newattr)) { + if (errno != EINTR) { + fprintf(stderr, "getline(): tcsetattr error: %s\n", strerror(errno)); + return 1; + }; + }; + return 0; +} + +/*....................................................................... + * Restore the terminal attributes recorded in gl->oldattr. + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_restore_terminal_attributes(GetLine *gl) +{ + int waserr = 0; +/* + * Before changing the terminal attributes, make sure that all output + * has been passed to the terminal. + */ + if(gl_flush_output(gl)) + waserr = 1; +/* + * Reset the terminal attributes to the values that they had on + * entry to gl_get_line(). + */ + while(tcsetattr(gl->input_fd, TCSADRAIN, &gl->oldattr)) { + if(errno != EINTR) { + fprintf(stderr, "gl_get_line(): tcsetattr error: %s\n", strerror(errno)); + waserr = 1; + break; + }; + }; + return waserr; +} + +/*....................................................................... + * Read a new input line from the user. + * + * Input: + * gl GetLine * The resource object of this library. + * start_line char * The initial contents of the input line, or NULL + * if it should start out empty. + * start_pos int If start_line isn't NULL, this specifies the + * index of the character over which the cursor + * should initially be positioned within the line. + * If you just want it to follow the last character + * of the line, send -1. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_get_input_line(GetLine *gl, const char *start_line, int start_pos) +{ + char c; /* The character being read */ +/* + * Reset the properties of the line. + */ + gl->ntotal = 0; + gl->buff_curpos = 0; + gl->term_curpos = 0; + gl->insert_curpos = 0; + gl->number = -1; + gl->endline = 0; + gl->vi.command = 0; + gl->vi.undo.line[0] = '\0'; + gl->vi.undo.ntotal = 0; + gl->vi.undo.buff_curpos = 0; + gl->vi.repeat.fn = 0; + gl->last_signal = -1; +/* + * Reset the history search pointers. + */ + if(_glh_cancel_search(gl->glh)) + return 1; +/* + * Draw the prompt at the start of the line. + */ + if(gl_display_prompt(gl)) + return 1; +/* + * Present an initial line? + */ + if(start_line) { + char *cptr; /* A pointer into gl->line[] */ +/* + * Load the line into the buffer, and display it. + */ + if(start_line != gl->line) + strncpy(gl->line, start_line, gl->linelen); + gl->line[gl->linelen] = '\0'; + gl->ntotal = strlen(gl->line); +/* + * Strip off any trailing newline and carriage return characters. + */ + for(cptr=gl->line + gl->ntotal - 1; cptr >= gl->line && + (*cptr=='\n' || *cptr=='\r'); cptr--,gl->ntotal--) + ; + if(gl->ntotal < 0) + gl->ntotal = 0; + gl->line[gl->ntotal] = '\0'; +/* + * Display the string that remains. + */ + if(gl_output_string(gl, gl->line, '\0')) + return 1; +/* + * Where should the cursor be placed within the line? + */ + if(start_pos < 0 || start_pos > gl->ntotal) { + if(gl_place_cursor(gl, gl->ntotal)) + return 1; + } else { + if(gl_place_cursor(gl, start_pos)) + return 1; + }; + } else { + gl->line[0] = '\0'; + }; +/* + * Preload a history line? + */ + if(gl->preload_history) { + gl->preload_history = 0; + if(gl->preload_id) { + if(_glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen)) { + gl->ntotal = strlen(gl->line); + gl->buff_curpos = strlen(gl->line); + }; + gl->preload_id = 0; + }; + gl_redisplay(gl, 1); + }; +/* + * Read one character at a time. + */ + while(gl_read_character(gl, &c) == 0) { +/* + * Increment the count of the number of key sequences entered. + */ + gl->keyseq_count++; +/* + * Interpret the character either as the start of a new key-sequence, + * as a continuation of a repeat count, or as a printable character + * to be added to the line. + */ + if(gl_interpret_char(gl, c)) + break; +/* + * If we just ran an action function which temporarily asked for + * input to be taken from a file, abort this call. + */ + if(gl->file_fp) + return 0; +/* + * Has the line been completed? + */ + if(gl->endline) + return gl_line_ended(gl, isprint((int)(unsigned char) c) ? c : '\n', + gl->echo && (c=='\n' || c=='\r')); + }; +/* + * To get here, gl_read_character() must have returned non-zero. See + * if this was because a signal was caught that requested that the + * current line be returned. + */ + if(gl->endline) + return gl_line_ended(gl, '\n', gl->echo); + return 1; +} + +/*....................................................................... + * Add a character to the line buffer at the current cursor position, + * inserting or overwriting according the current mode. + * + * Input: + * gl GetLine * The resource object of this library. + * c char The character to be added. + * Output: + * return int 0 - OK. + * 1 - Insufficient room. + */ +static int gl_add_char_to_line(GetLine *gl, char c) +{ +/* + * Keep a record of the current cursor position. + */ + int buff_curpos = gl->buff_curpos; + int term_curpos = gl->term_curpos; +/* + * Work out the displayed width of the new character. + */ + int width = gl_displayed_char_width(gl, c, term_curpos); +/* + * If we are in insert mode, or at the end of the line, + * check that we can accomodate a new character in the buffer. + * If not, simply return, leaving it up to the calling program + * to check for the absence of a newline character. + */ + if((gl->insert || buff_curpos >= gl->ntotal) && gl->ntotal >= gl->linelen) + return 0; +/* + * Are we adding characters to the line (ie. inserting or appending)? + */ + if(gl->insert || buff_curpos >= gl->ntotal) { +/* + * If inserting, make room for the new character. + */ + if(buff_curpos < gl->ntotal) { + memmove(gl->line + buff_curpos + 1, gl->line + buff_curpos, + gl->ntotal - buff_curpos); + }; +/* + * Copy the character into the buffer. + */ + gl->line[buff_curpos] = c; + gl->buff_curpos++; +/* + * If the line was extended, update the record of the string length + * and terminate the extended string. + */ + gl->ntotal++; + gl->line[gl->ntotal] = '\0'; +/* + * Redraw the line from the cursor position to the end of the line, + * and move the cursor to just after the added character. + */ + if(gl_output_string(gl, gl->line + buff_curpos, '\0') || + gl_set_term_curpos(gl, term_curpos + width)) + return 1; +/* + * Are we overwriting an existing character? + */ + } else { +/* + * Get the widths of the character to be overwritten and the character + * that is going to replace it. + */ + int old_width = gl_displayed_char_width(gl, gl->line[buff_curpos], + term_curpos); +/* + * Overwrite the character in the buffer. + */ + gl->line[buff_curpos] = c; +/* + * If we are replacing with a narrower character, we need to + * redraw the terminal string to the end of the line, then + * overwrite the trailing old_width - width characters + * with spaces. + */ + if(old_width > width) { + if(gl_output_string(gl, gl->line + buff_curpos, '\0')) + return 1; +/* + * Clear to the end of the terminal. + */ + if(gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; +/* + * Move the cursor to the end of the new character. + */ + if(gl_set_term_curpos(gl, term_curpos + width)) + return 1; + gl->buff_curpos++; +/* + * If we are replacing with a wider character, then we will be + * inserting new characters, and thus extending the line. + */ + } else if(width > old_width) { +/* + * Redraw the line from the cursor position to the end of the line, + * and move the cursor to just after the added character. + */ + if(gl_output_string(gl, gl->line + buff_curpos, '\0') || + gl_set_term_curpos(gl, term_curpos + width)) + return 1; + gl->buff_curpos++; +/* + * The original and replacement characters have the same width, + * so simply overwrite. + */ + } else { +/* + * Copy the character into the buffer. + */ + gl->line[buff_curpos] = c; + gl->buff_curpos++; +/* + * Overwrite the original character. + */ + if(gl_output_char(gl, c, gl->line[gl->buff_curpos])) + return 1; + }; + }; + return 0; +} + +/*....................................................................... + * Insert/append a string to the line buffer and terminal at the current + * cursor position. + * + * Input: + * gl GetLine * The resource object of this library. + * s char * The string to be added. + * Output: + * return int 0 - OK. + * 1 - Insufficient room. + */ +static int gl_add_string_to_line(GetLine *gl, const char *s) +{ + int buff_slen; /* The length of the string being added to line[] */ + int term_slen; /* The length of the string being written to the terminal */ + int buff_curpos; /* The original value of gl->buff_curpos */ + int term_curpos; /* The original value of gl->term_curpos */ +/* + * Keep a record of the current cursor position. + */ + buff_curpos = gl->buff_curpos; + term_curpos = gl->term_curpos; +/* + * How long is the string to be added? + */ + buff_slen = strlen(s); + term_slen = gl_displayed_string_width(gl, s, buff_slen, term_curpos); +/* + * Check that we can accomodate the string in the buffer. + * If not, simply return, leaving it up to the calling program + * to check for the absence of a newline character. + */ + if(gl->ntotal + buff_slen > gl->linelen) + return 0; +/* + * Move the characters that follow the cursor in the buffer by + * buff_slen characters to the right. + */ + if(gl->ntotal > gl->buff_curpos) { + memmove(gl->line + gl->buff_curpos + buff_slen, gl->line + gl->buff_curpos, + gl->ntotal - gl->buff_curpos); + }; +/* + * Copy the string into the buffer. + */ + memcpy(gl->line + gl->buff_curpos, s, buff_slen); + gl->ntotal += buff_slen; + gl->buff_curpos += buff_slen; +/* + * Maintain the buffer properly terminated. + */ + gl->line[gl->ntotal] = '\0'; +/* + * Write the modified part of the line to the terminal, then move + * the terminal cursor to the end of the displayed input string. + */ + if(gl_output_string(gl, gl->line + buff_curpos, '\0') || + gl_set_term_curpos(gl, term_curpos + term_slen)) + return 1; + return 0; +} + +/*....................................................................... + * Read a single character from the terminal. + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int 0 - OK. + * 1 - Either an I/O error occurred, or a signal was + * caught who's disposition is to abort gl_get_line() + * or to have gl_get_line() return the current line + * as though the user had pressed return. In the + * latter case gl->endline will be non-zero. + */ +static int gl_read_character(GetLine *gl, char *c) +{ +/* + * Before waiting for a new character to be input, flush unwritten + * characters to the terminal. + */ + if(gl_flush_output(gl)) + return 1; +/* + * We may have to repeat the read if window change signals are received. + */ + for(;;) { +/* + * If the endline flag becomes set, don't wait for another character. + */ + if(gl->endline) + return 1; +/* + * Since the code in this function can block, trap signals. + */ + if(sigsetjmp(gl_setjmp_buffer, 1)==0) { +/* + * Unblock the signals that we are trapping. + */ + if(sigprocmask(SIG_UNBLOCK, &gl->new_signal_set, NULL) == -1) { + fprintf(stderr, "getline(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; +/* + * If select() is available, watch for activity on any file descriptors + * that the user has registered, and for data available on the terminal + * file descriptor. + */ +#ifdef HAVE_SELECT + if(gl_event_handler(gl)) + return 1; +#endif +/* + * Read one character from the terminal. This could take more + * than one call if an interrupt that we aren't trapping is + * received. + */ + while(read(gl->input_fd, (void *)c, 1) != 1) { + if(errno != EINTR) { +#ifdef EAGAIN + if(!errno) /* This can happen with SysV O_NDELAY */ + errno = EAGAIN; +#endif + return 1; + }; + }; +/* + * Block all of the signals that we are trapping. + */ + if(sigprocmask(SIG_BLOCK, &gl->new_signal_set, NULL) == -1) { + fprintf(stderr, "getline(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; + return 0; + }; +/* + * To get here, one of the signals that we are trapping must have + * been received. Note that by using sigsetjmp() instead of setjmp() + * the signal mask that was blocking these signals will have been + * reinstated, so we can be sure that no more of these signals will + * be received until we explicitly unblock them again. + */ + if(gl_check_caught_signal(gl)) + return 1; + }; +} + +/*....................................................................... + * This function is called to handle signals caught between calls to + * sigsetjmp() and siglongjmp(). + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int 0 - Signal handled internally. + * 1 - Signal requires gl_get_line() to abort. + */ +static int gl_check_caught_signal(GetLine *gl) +{ + GlSignalNode *sig; /* The signal disposition */ + SigAction keep_action; /* The signal disposition of tecla signal handlers */ +/* + * Was no signal caught? + */ + if(gl_pending_signal == -1) + return 0; +/* + * Record the signal that was caught, so that the user can query it later. + */ + gl->last_signal = gl_pending_signal; +/* + * Did we receive a terminal size signal? + */ +#ifdef USE_SIGWINCH + if(gl_pending_signal == SIGWINCH && gl_resize_terminal(gl, 1)) + return 1; +#endif +/* + * Lookup the requested disposition of this signal. + */ + for(sig=gl->sigs; sig && sig->signo != gl_pending_signal; sig=sig->next) + ; + if(!sig) + return 0; +/* + * Start a fresh line? + */ + if(sig->flags & GLS_RESTORE_LINE) { + if(gl_set_term_curpos(gl, gl_buff_curpos_to_term_curpos(gl, gl->ntotal)) || + gl_output_raw_string(gl, "\r\n")) + return 1; + }; +/* + * Restore terminal settings to how they were before gl_get_line() was + * called? + */ + if(sig->flags & GLS_RESTORE_TTY) + gl_restore_terminal_attributes(gl); +/* + * Restore signal handlers to how they were before gl_get_line() was + * called? If this hasn't been requested, only reinstate the signal + * handler of the signal that we are handling. + */ + if(sig->flags & GLS_RESTORE_SIG) { + gl_restore_signal_handlers(gl); + } else { + (void) sigaction(sig->signo, &sig->original, &keep_action); + (void) sigprocmask(SIG_UNBLOCK, &sig->proc_mask, NULL); + }; +/* + * Forward the signal to the application's signal handler. + */ + if(!(sig->flags & GLS_DONT_FORWARD)) + raise(gl_pending_signal); + gl_pending_signal = -1; +/* + * Reinstate our signal handlers. + */ + if(sig->flags & GLS_RESTORE_SIG) { + gl_override_signal_handlers(gl); + } else { + (void) sigaction(sig->signo, &keep_action, NULL); + (void) sigprocmask(SIG_BLOCK, &sig->proc_mask, NULL); + }; +/* + * Do we need to reinstate our terminal settings? + */ + if(sig->flags & GLS_RESTORE_TTY) + gl_raw_terminal_mode(gl); +/* + * Redraw the line? + */ + if(sig->flags & GLS_REDRAW_LINE && gl_redisplay(gl, 1)) + return 1; +/* + * Set errno. + */ + errno = sig->errno_value; +/* + * What next? + */ + switch(sig->after) { + case GLS_RETURN: + return gl_newline(gl, 1); + break; + case GLS_ABORT: + return 1; + break; + case GLS_CONTINUE: + return 0; + break; + }; + return 0; +} + +/*....................................................................... + * Get pertinent terminal control strings and the initial terminal size. + * + * Input: + * gl GetLine * The resource object of this library. + * term char * The type of the terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_control_strings(GetLine *gl, const char *term) +{ + int bad_term = 0; /* True if term is unusable */ +/* + * Discard any existing control strings from a previous terminal. + */ + gl->left = NULL; + gl->right = NULL; + gl->up = NULL; + gl->down = NULL; + gl->home = NULL; + gl->bol = 0; + gl->clear_eol = NULL; + gl->clear_eod = NULL; + gl->u_arrow = NULL; + gl->d_arrow = NULL; + gl->l_arrow = NULL; + gl->r_arrow = NULL; + gl->sound_bell = NULL; + gl->bold = NULL; + gl->underline = NULL; + gl->standout = NULL; + gl->dim = NULL; + gl->reverse = NULL; + gl->blink = NULL; + gl->text_attr_off = NULL; + gl->nline = 0; + gl->ncolumn = 0; +#ifdef USE_TERMINFO + gl->left_n = NULL; + gl->right_n = NULL; +#endif +/* + * If possible lookup the information in a terminal information + * database. + */ +#ifdef USE_TERMINFO + if(!term || setupterm((char *)term, gl->input_fd, NULL) == ERR) { + bad_term = 1; + } else { + _clr_StringGroup(gl->capmem); + gl->left = gl_tigetstr(gl, "cub1"); + gl->right = gl_tigetstr(gl, "cuf1"); + gl->up = gl_tigetstr(gl, "cuu1"); + gl->down = gl_tigetstr(gl, "cud1"); + gl->home = gl_tigetstr(gl, "home"); + gl->clear_eol = gl_tigetstr(gl, "el"); + gl->clear_eod = gl_tigetstr(gl, "ed"); + gl->u_arrow = gl_tigetstr(gl, "kcuu1"); + gl->d_arrow = gl_tigetstr(gl, "kcud1"); + gl->l_arrow = gl_tigetstr(gl, "kcub1"); + gl->r_arrow = gl_tigetstr(gl, "kcuf1"); + gl->left_n = gl_tigetstr(gl, "cub"); + gl->right_n = gl_tigetstr(gl, "cuf"); + gl->sound_bell = gl_tigetstr(gl, "bel"); + gl->bold = gl_tigetstr(gl, "bold"); + gl->underline = gl_tigetstr(gl, "smul"); + gl->standout = gl_tigetstr(gl, "smso"); + gl->dim = gl_tigetstr(gl, "dim"); + gl->reverse = gl_tigetstr(gl, "rev"); + gl->blink = gl_tigetstr(gl, "blink"); + gl->text_attr_off = gl_tigetstr(gl, "sgr0"); + }; +#elif defined(USE_TERMCAP) + if(!term || tgetent(gl->tgetent_buf, (char *)term) < 0) { + bad_term = 1; + } else { + char *tgetstr_buf_ptr = gl->tgetstr_buf; + _clr_StringGroup(gl->capmem); + gl->left = gl_tgetstr(gl, "le", &tgetstr_buf_ptr); + gl->right = gl_tgetstr(gl, "nd", &tgetstr_buf_ptr); + gl->up = gl_tgetstr(gl, "up", &tgetstr_buf_ptr); + gl->down = gl_tgetstr(gl, "do", &tgetstr_buf_ptr); + gl->home = gl_tgetstr(gl, "ho", &tgetstr_buf_ptr); + gl->clear_eol = gl_tgetstr(gl, "ce", &tgetstr_buf_ptr); + gl->clear_eod = gl_tgetstr(gl, "cd", &tgetstr_buf_ptr); + gl->u_arrow = gl_tgetstr(gl, "ku", &tgetstr_buf_ptr); + gl->d_arrow = gl_tgetstr(gl, "kd", &tgetstr_buf_ptr); + gl->l_arrow = gl_tgetstr(gl, "kl", &tgetstr_buf_ptr); + gl->r_arrow = gl_tgetstr(gl, "kr", &tgetstr_buf_ptr); + gl->sound_bell = gl_tgetstr(gl, "bl", &tgetstr_buf_ptr); + gl->bold = gl_tgetstr(gl, "md", &tgetstr_buf_ptr); + gl->underline = gl_tgetstr(gl, "us", &tgetstr_buf_ptr); + gl->standout = gl_tgetstr(gl, "so", &tgetstr_buf_ptr); + gl->dim = gl_tgetstr(gl, "mh", &tgetstr_buf_ptr); + gl->reverse = gl_tgetstr(gl, "mr", &tgetstr_buf_ptr); + gl->blink = gl_tgetstr(gl, "mb", &tgetstr_buf_ptr); + gl->text_attr_off = gl_tgetstr(gl, "me", &tgetstr_buf_ptr); + }; +#endif +/* + * Report term being unusable. + */ + if(bad_term) { + fprintf(stderr, "Bad terminal type: \"%s\". Will assume vt100.\n", + term ? term : "(null)"); + }; +/* + * Fill in missing information with ANSI VT100 strings. + */ + if(!gl->left) + gl->left = "\b"; /* ^H */ + if(!gl->right) + gl->right = GL_ESC_STR "[C"; + if(!gl->up) + gl->up = GL_ESC_STR "[A"; + if(!gl->down) + gl->down = "\n"; + if(!gl->home) + gl->home = GL_ESC_STR "[H"; + if(!gl->bol) + gl->bol = "\r"; + if(!gl->clear_eol) + gl->clear_eol = GL_ESC_STR "[K"; + if(!gl->clear_eod) + gl->clear_eod = GL_ESC_STR "[J"; + if(!gl->u_arrow) + gl->u_arrow = GL_ESC_STR "[A"; + if(!gl->d_arrow) + gl->d_arrow = GL_ESC_STR "[B"; + if(!gl->l_arrow) + gl->l_arrow = GL_ESC_STR "[D"; + if(!gl->r_arrow) + gl->r_arrow = GL_ESC_STR "[C"; + if(!gl->sound_bell) + gl->sound_bell = "\a"; + if(!gl->bold) + gl->bold = GL_ESC_STR "[1m"; + if(!gl->underline) + gl->underline = GL_ESC_STR "[4m"; + if(!gl->standout) + gl->standout = GL_ESC_STR "[1;7m"; + if(!gl->dim) + gl->dim = ""; /* Not available */ + if(!gl->reverse) + gl->reverse = GL_ESC_STR "[7m"; + if(!gl->blink) + gl->blink = GL_ESC_STR "[5m"; + if(!gl->text_attr_off) + gl->text_attr_off = GL_ESC_STR "[m"; +/* + * Find out the current terminal size. + */ + (void) gl_terminal_size(gl, GL_DEF_NCOLUMN, GL_DEF_NLINE); + return 0; +} + +#ifdef USE_TERMINFO +/*....................................................................... + * This is a private function of gl_control_strings() used to look up + * a termninal capability string from the terminfo database and make + * a private copy of it. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * name const char * The name of the terminfo string to look up. + * Output: + * return const char * The local copy of the capability, or NULL + * if not available. + */ +static const char *gl_tigetstr(GetLine *gl, const char *name) +{ + const char *value = tigetstr((char *)name); + if(!value || value == (char *) -1) + return NULL; + return _sg_store_string(gl->capmem, value, 0); +} +#elif defined(USE_TERMCAP) +/*....................................................................... + * This is a private function of gl_control_strings() used to look up + * a termninal capability string from the termcap database and make + * a private copy of it. Note that some emulations of tgetstr(), such + * as that used by Solaris, ignores the buffer pointer that is past to + * it, so we can't assume that a private copy has been made that won't + * be trashed by another call to gl_control_strings() by another + * GetLine object. So we make what may be a redundant private copy + * of the string in gl->capmem. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * name const char * The name of the terminfo string to look up. + * Input/Output: + * bufptr char ** On input *bufptr points to the location in + * gl->tgetstr_buf at which to record the + * capability string. On output *bufptr is + * incremented over the stored string. + * Output: + * return const char * The local copy of the capability, or NULL + * on error. + */ +static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr) +{ + const char *value = tgetstr((char *)name, bufptr); + if(!value || value == (char *) -1) + return NULL; + return _sg_store_string(gl->capmem, value, 0); +} +#endif + +/*....................................................................... + * This is an action function that implements a user interrupt (eg. ^C). + */ +static KT_KEY_FN(gl_user_interrupt) +{ + raise(SIGINT); + return 1; +} + +/*....................................................................... + * This is an action function that implements the abort signal. + */ +static KT_KEY_FN(gl_abort) +{ + raise(SIGABRT); + return 1; +} + +/*....................................................................... + * This is an action function that sends a suspend signal (eg. ^Z) to the + * the parent process. + */ +static KT_KEY_FN(gl_suspend) +{ + raise(SIGTSTP); + return 0; +} + +/*....................................................................... + * This is an action function that halts output to the terminal. + */ +static KT_KEY_FN(gl_stop_output) +{ + tcflow(gl->output_fd, TCOOFF); + return 0; +} + +/*....................................................................... + * This is an action function that resumes halted terminal output. + */ +static KT_KEY_FN(gl_start_output) +{ + tcflow(gl->output_fd, TCOON); + return 0; +} + +/*....................................................................... + * This is an action function that allows the next character to be accepted + * without any interpretation as a special character. + */ +static KT_KEY_FN(gl_literal_next) +{ + char c; /* The character to be added to the line */ + int i; +/* + * Get the character to be inserted literally. + */ + if(gl_read_character(gl, &c)) + return 1; +/* + * Add the character to the line 'count' times. + */ + for(i=0; incolumn) % TAB_WIDTH); + if(IS_CTRL_CHAR(c)) + return 2; + if(!isprint((int)(unsigned char) c)) { + char string[TAB_WIDTH + 4]; + sprintf(string, "\\%o", (int)(unsigned char)c); + return strlen(string); + }; + return 1; +} + +/*....................................................................... + * Work out the length of given string of characters on the terminal. + * + * Input: + * gl GetLine * The resource object of this library. + * string char * The string to be measured. + * nc int The number of characters to be measured, or -1 + * to measure the whole string. + * term_curpos int The destination terminal location of the character. + * This is needed because the width of tab characters + * depends on where they are, relative to the + * preceding tab stops. + * Output: + * return int The number of displayed characters. + */ +static int gl_displayed_string_width(GetLine *gl, const char *string, int nc, + int term_curpos) +{ + int slen=0; /* The displayed number of characters */ + int i; +/* + * How many characters are to be measured? + */ + if(nc < 0) + nc = strlen(string); +/* + * Add up the length of the displayed string. + */ + for(i=0; iecho) { + int ndone = 0; /* The number of characters written so far */ +/* + * How long is the string to be written? + */ + int slen = strlen(string); +/* + * Attempt to write the string to the terminal, restarting the + * write if a signal is caught. + */ + while(ndone < slen) { + int nnew = fwrite(string + ndone, sizeof(char), slen-ndone, + gl->output_fp); + if(nnew > 0) + ndone += nnew; + else if(errno != EINTR) + return 1; + }; + }; + return 0; +} + +/*....................................................................... + * Output a terminal control sequence. When using terminfo, + * this must be a sequence returned by tgetstr() or tigetstr() + * respectively. + * + * Input: + * gl GetLine * The resource object of this library. + * nline int The number of lines affected by the operation, + * or 1 if not relevant. + * string char * The control sequence to be sent. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_output_control_sequence(GetLine *gl, int nline, + const char *string) +{ + if(gl->echo) { +#if defined(USE_TERMINFO) || defined(USE_TERMCAP) + tputs_fp = gl->output_fp; + errno = 0; + tputs((char *)string, nline, gl_tputs_putchar); + return errno != 0; +#else + return gl_output_raw_string(gl, string); +#endif + }; + return 0; +} + +/*....................................................................... + * Move the terminal cursor n characters to the left or right. + * + * Input: + * gl GetLine * The resource object of this program. + * n int number of positions to the right (> 0) or left (< 0). + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_terminal_move_cursor(GetLine *gl, int n) +{ + int cur_row, cur_col; /* The current terminal row and column index of */ + /* the cursor wrt the start of the input line. */ + int new_row, new_col; /* The target terminal row and column index of */ + /* the cursor wrt the start of the input line. */ +/* + * How far can we move left? + */ + if(gl->term_curpos + n < 0) + n = gl->term_curpos; +/* + * Break down the current and target cursor locations into rows and columns. + */ + cur_row = gl->term_curpos / gl->ncolumn; + cur_col = gl->term_curpos % gl->ncolumn; + new_row = (gl->term_curpos + n) / gl->ncolumn; + new_col = (gl->term_curpos + n) % gl->ncolumn; +/* + * Move down to the next line. + */ + for(; cur_row < new_row; cur_row++) { + if(gl_output_control_sequence(gl, 1, gl->down)) + return 1; + }; +/* + * Move up to the previous line. + */ + for(; cur_row > new_row; cur_row--) { + if(gl_output_control_sequence(gl, 1, gl->up)) + return 1; + }; +/* + * Move to the right within the target line? + */ + if(cur_col < new_col) { +#ifdef USE_TERMINFO +/* + * Use a parameterized control sequence if it generates less control + * characters (guess based on ANSI terminal termcap entry). + */ + if(gl->right_n != NULL && new_col - cur_col > 1) { + if(gl_output_control_sequence(gl, 1, tparm((char *)gl->right_n, + (long)(new_col - cur_col), 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l))) + return 1; + } else +#endif + { + for(; cur_col < new_col; cur_col++) { + if(gl_output_control_sequence(gl, 1, gl->right)) + return 1; + }; + }; +/* + * Move to the left within the target line? + */ + } else if(cur_col > new_col) { +#ifdef USE_TERMINFO +/* + * Use a parameterized control sequence if it generates less control + * characters (guess based on ANSI terminal termcap entry). + */ + if(gl->left_n != NULL && cur_col - new_col > 3) { + if(gl_output_control_sequence(gl, 1, tparm((char *)gl->left_n, + (long)(cur_col - new_col), 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l))) + return 1; + } else +#endif + { + for(; cur_col > new_col; cur_col--) { + if(gl_output_control_sequence(gl, 1, gl->left)) + return 1; + }; + }; + } +/* + * Update the recorded position of the terminal cursor. + */ + gl->term_curpos += n; + return 0; +} + +/*....................................................................... + * Write a character to the terminal after expanding tabs and control + * characters to their multi-character representations. + * + * Input: + * gl GetLine * The resource object of this program. + * c char The character to be output. + * pad char Many terminals have the irritating feature that + * when one writes a character in the last column of + * of the terminal, the cursor isn't wrapped to the + * start of the next line until one more character + * is written. Some terminals don't do this, so + * after such a write, we don't know where the + * terminal is unless we output an extra character. + * This argument specifies the character to write. + * If at the end of the input line send '\0' or a + * space, and a space will be written. Otherwise, + * pass the next character in the input line + * following the one being written. + * Output: + * return int 0 - OK. + */ +static int gl_output_char(GetLine *gl, char c, char pad) +{ + char string[TAB_WIDTH + 4]; /* A work area for composing compound strings */ + int nchar; /* The number of terminal characters */ + int i; +/* + * Check for special characters. + */ + if(c == '\t') { +/* + * How many spaces do we need to represent a tab at the current terminal + * column? + */ + nchar = gl_displayed_char_width(gl, '\t', gl->term_curpos); +/* + * Compose the tab string. + */ + for(i=0; iterm_curpos += nchar; +/* + * If the new character ended exactly at the end of a line, + * most terminals won't move the cursor onto the next line until we + * have written a character on the next line, so append an extra + * space then move the cursor back. + */ + if(gl->term_curpos % gl->ncolumn == 0) { + int term_curpos = gl->term_curpos; + if(gl_output_char(gl, pad ? pad : ' ', ' ') || + gl_set_term_curpos(gl, term_curpos)) + return 1; + }; + return 0; +} + +/*....................................................................... + * Write a string to the terminal after expanding tabs and control + * characters to their multi-character representations. + * + * Input: + * gl GetLine * The resource object of this program. + * string char * The string to be output. + * pad char Many terminals have the irritating feature that + * when one writes a character in the last column of + * of the terminal, the cursor isn't wrapped to the + * start of the next line until one more character + * is written. Some terminals don't do this, so + * after such a write, we don't know where the + * terminal is unless we output an extra character. + * This argument specifies the character to write. + * If at the end of the input line send '\0' or a + * space, and a space will be written. Otherwise, + * pass the next character in the input line + * following the one being written. + * Output: + * return int 0 - OK. + */ +static int gl_output_string(GetLine *gl, const char *string, char pad) +{ + const char *cptr; /* A pointer into string[] */ + for(cptr=string; *cptr; cptr++) { + char nextc = cptr[1]; + if(gl_output_char(gl, *cptr, nextc ? nextc : pad)) + return 1; + }; + return 0; +} + +/*....................................................................... + * Given a character position within gl->line[], work out the + * corresponding gl->term_curpos position on the terminal. + * + * Input: + * gl GetLine * The resource object of this library. + * buff_curpos int The position within gl->line[]. + * + * Output: + * return int The gl->term_curpos position on the terminal. + */ +static int gl_buff_curpos_to_term_curpos(GetLine *gl, int buff_curpos) +{ + return gl->prompt_len + gl_displayed_string_width(gl, gl->line, buff_curpos, + gl->prompt_len); +} + +/*....................................................................... + * Move the terminal cursor position. + * + * Input: + * gl GetLine * The resource object of this library. + * term_curpos int The destination terminal cursor position. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_set_term_curpos(GetLine *gl, int term_curpos) +{ + return gl_terminal_move_cursor(gl, term_curpos - gl->term_curpos); +} + +/*....................................................................... + * This is an action function that moves the buffer cursor one character + * left, and updates the terminal cursor to match. + */ +static KT_KEY_FN(gl_cursor_left) +{ + return gl_place_cursor(gl, gl->buff_curpos - count); +} + +/*....................................................................... + * This is an action function that moves the buffer cursor one character + * right, and updates the terminal cursor to match. + */ +static KT_KEY_FN(gl_cursor_right) +{ + return gl_place_cursor(gl, gl->buff_curpos + count); +} + +/*....................................................................... + * This is an action function that toggles between overwrite and insert + * mode. + */ +static KT_KEY_FN(gl_insert_mode) +{ + gl->insert = !gl->insert; + return 0; +} + +/*....................................................................... + * This is an action function which moves the cursor to the beginning of + * the line. + */ +static KT_KEY_FN(gl_beginning_of_line) +{ + return gl_place_cursor(gl, 0); +} + +/*....................................................................... + * This is an action function which moves the cursor to the end of + * the line. + */ +static KT_KEY_FN(gl_end_of_line) +{ + return gl_place_cursor(gl, gl->ntotal); +} + +/*....................................................................... + * This is an action function which deletes the entire contents of the + * current line. + */ +static KT_KEY_FN(gl_delete_line) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Copy the contents of the line to the cut buffer. + */ + strcpy(gl->cutbuf, gl->line); +/* + * Clear the buffer. + */ + gl->ntotal = 0; + gl->line[0] = '\0'; +/* + * Move the terminal cursor to just after the prompt. + */ + if(gl_place_cursor(gl, 0)) + return 1; +/* + * Clear from the end of the prompt to the end of the terminal. + */ + if(gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; + return 0; +} + +/*....................................................................... + * This is an action function which deletes all characters between the + * current cursor position and the end of the line. + */ +static KT_KEY_FN(gl_kill_line) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Copy the part of the line that is about to be deleted to the cut buffer. + */ + strcpy(gl->cutbuf, gl->line + gl->buff_curpos); +/* + * Terminate the buffered line at the current cursor position. + */ + gl->ntotal = gl->buff_curpos; + gl->line[gl->ntotal] = '\0'; +/* + * Clear the part of the line that follows the cursor. + */ + if(gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; +/* + * Explicitly reset the cursor position to allow vi command mode + * constraints on its position to be set. + */ + return gl_place_cursor(gl, gl->buff_curpos); +} + +/*....................................................................... + * This is an action function which deletes all characters between the + * start of the line and the current cursor position. + */ +static KT_KEY_FN(gl_backward_kill_line) +{ +/* + * How many characters are to be deleted from before the cursor? + */ + int nc = gl->buff_curpos - gl->insert_curpos; + if (!nc) + return 0; +/* + * Move the cursor to the start of the line, or in vi input mode, + * the start of the sub-line at which insertion started, and delete + * up to the old cursor position. + */ + return gl_place_cursor(gl, gl->insert_curpos) || + gl_delete_chars(gl, nc, gl->editor == GL_EMACS_MODE || gl->vi.command); +} + +/*....................................................................... + * This is an action function which moves the cursor forward by a word. + */ +static KT_KEY_FN(gl_forward_word) +{ + return gl_place_cursor(gl, gl_nth_word_end_forward(gl, count) + + (gl->editor==GL_EMACS_MODE)); +} + +/*....................................................................... + * This is an action function which moves the cursor forward to the start + * of the next word. + */ +static KT_KEY_FN(gl_forward_to_word) +{ + return gl_place_cursor(gl, gl_nth_word_start_forward(gl, count)); +} + +/*....................................................................... + * This is an action function which moves the cursor backward by a word. + */ +static KT_KEY_FN(gl_backward_word) +{ + return gl_place_cursor(gl, gl_nth_word_start_backward(gl, count)); +} + +/*....................................................................... + * Delete one or more characters, starting with the one under the cursor. + * + * Input: + * gl GetLine * The resource object of this library. + * nc int The number of characters to delete. + * cut int If true, copy the characters to the cut buffer. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_delete_chars(GetLine *gl, int nc, int cut) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * If there are fewer than nc characters following the cursor, limit + * nc to the number available. + */ + if(gl->buff_curpos + nc > gl->ntotal) + nc = gl->ntotal - gl->buff_curpos; +/* + * Copy the about to be deleted region to the cut buffer. + */ + if(cut) { + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, nc); + gl->cutbuf[nc] = '\0'; + } +/* + * Nothing to delete? + */ + if(nc <= 0) + return 0; +/* + * In vi overwrite mode, restore any previously overwritten characters + * from the undo buffer. + */ + if(gl->editor == GL_VI_MODE && !gl->vi.command && !gl->insert) { +/* + * How many of the characters being deleted can be restored from the + * undo buffer? + */ + int nrestore = gl->buff_curpos + nc <= gl->vi.undo.ntotal ? + nc : gl->vi.undo.ntotal - gl->buff_curpos; +/* + * Restore any available characters. + */ + if(nrestore > 0) + memcpy(gl->line + gl->buff_curpos, gl->vi.undo.line + gl->buff_curpos, + nrestore); +/* + * If their were insufficient characters in the undo buffer, then this + * implies that we are deleting from the end of the line, so we need + * to terminate the line either where the undo buffer ran out, or if + * we are deleting from beyond the end of the undo buffer, at the current + * cursor position. + */ + if(nc != nrestore) { + gl->ntotal = gl->vi.undo.ntotal > gl->buff_curpos ? gl->vi.undo.ntotal : + gl->buff_curpos; + gl->line[gl->ntotal] = '\0'; + }; + } else { +/* + * Copy the remaining part of the line back over the deleted characters. + */ + memmove(gl->line + gl->buff_curpos, gl->line + gl->buff_curpos + nc, + gl->ntotal - gl->buff_curpos - nc + 1); + gl->ntotal -= nc; + }; +/* + * Redraw the remaining characters following the cursor. + */ + if(gl_output_string(gl, gl->line + gl->buff_curpos, '\0')) + return 1; +/* + * Clear to the end of the terminal. + */ + if(gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; +/* + * Place the cursor at the start of where the deletion was performed. + */ + return gl_place_cursor(gl, gl->buff_curpos); +} + +/*....................................................................... + * This is an action function which deletes character(s) under the + * cursor without moving the cursor. + */ +static KT_KEY_FN(gl_forward_delete_char) +{ +/* + * Delete 'count' characters. + */ + return gl_delete_chars(gl, count, gl->vi.command); +} + +/*....................................................................... + * This is an action function which deletes character(s) under the + * cursor and moves the cursor back one character. + */ +static KT_KEY_FN(gl_backward_delete_char) +{ +/* + * Restrict the deletion count to the number of characters that + * precede the insertion point. + */ + if(count > gl->buff_curpos - gl->insert_curpos) + count = gl->buff_curpos - gl->insert_curpos; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); + return gl_cursor_left(gl, count) || + gl_delete_chars(gl, count, gl->vi.command); +} + +/*....................................................................... + * Starting from the cursor position delete to the specified column. + */ +static KT_KEY_FN(gl_delete_to_column) +{ + if (--count >= gl->buff_curpos) + return gl_forward_delete_char(gl, count - gl->buff_curpos); + else + return gl_backward_delete_char(gl, gl->buff_curpos - count); +} + +/*....................................................................... + * Starting from the cursor position delete characters to a matching + * parenthesis. + */ +static KT_KEY_FN(gl_delete_to_parenthesis) +{ + int curpos = gl_index_of_matching_paren(gl); + if(curpos >= 0) { + gl_save_for_undo(gl); + if(curpos >= gl->buff_curpos) + return gl_forward_delete_char(gl, curpos - gl->buff_curpos + 1); + else + return gl_backward_delete_char(gl, ++gl->buff_curpos - curpos + 1); + }; + return 0; +} + +/*....................................................................... + * This is an action function which deletes from the cursor to the end + * of the word that the cursor is either in or precedes. + */ +static KT_KEY_FN(gl_forward_delete_word) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * In emacs mode delete to the end of the word. In vi mode delete to the + * start of the net word. + */ + if(gl->editor == GL_EMACS_MODE) { + return gl_delete_chars(gl, + gl_nth_word_end_forward(gl,count) - gl->buff_curpos + 1, 1); + } else { + return gl_delete_chars(gl, + gl_nth_word_start_forward(gl,count) - gl->buff_curpos, + gl->vi.command); + }; +} + +/*....................................................................... + * This is an action function which deletes the word that precedes the + * cursor. + */ +static KT_KEY_FN(gl_backward_delete_word) +{ +/* + * Keep a record of the current cursor position. + */ + int buff_curpos = gl->buff_curpos; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Move back 'count' words. + */ + if(gl_backward_word(gl, count)) + return 1; +/* + * Delete from the new cursor position to the original one. + */ + return gl_delete_chars(gl, buff_curpos - gl->buff_curpos, + gl->editor == GL_EMACS_MODE || gl->vi.command); +} + +/*....................................................................... + * Searching in a given direction, delete to the count'th + * instance of a specified or queried character, in the input line. + * + * Input: + * gl GetLine * The getline resource object. + * count int The number of times to search. + * c char The character to be searched for, or '\0' if + * the character should be read from the user. + * forward int True if searching forward. + * onto int True if the search should end on top of the + * character, false if the search should stop + * one character before the character in the + * specified search direction. + * change int If true, this function is being called upon + * to do a vi change command, in which case the + * user will be left in insert mode after the + * deletion. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_delete_find(GetLine *gl, int count, char c, int forward, + int onto, int change) +{ +/* + * Search for the character, and abort the deletion if not found. + */ + int pos = gl_find_char(gl, count, forward, onto, c); + if(pos < 0) + return 0; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Allow the cursor to be at the end of the line if this is a change + * command. + */ + if(change) + gl->vi.command = 0; +/* + * Delete the appropriate span of characters. + */ + if(forward) { + if(gl_delete_chars(gl, pos - gl->buff_curpos + 1, 1)) + return 1; + } else { + int buff_curpos = gl->buff_curpos; + if(gl_place_cursor(gl, pos) || + gl_delete_chars(gl, buff_curpos - gl->buff_curpos, 1)) + return 1; + }; +/* + * If this is a change operation, switch the insert mode. + */ + if(change && gl_vi_insert(gl, 0)) + return 1; + return 0; +} + +/*....................................................................... + * This is an action function which deletes forward from the cursor up to and + * including a specified character. + */ +static KT_KEY_FN(gl_forward_delete_find) +{ + return gl_delete_find(gl, count, '\0', 1, 1, 0); +} + +/*....................................................................... + * This is an action function which deletes backward from the cursor back to + * and including a specified character. + */ +static KT_KEY_FN(gl_backward_delete_find) +{ + return gl_delete_find(gl, count, '\0', 0, 1, 0); +} + +/*....................................................................... + * This is an action function which deletes forward from the cursor up to but + * not including a specified character. + */ +static KT_KEY_FN(gl_forward_delete_to) +{ + return gl_delete_find(gl, count, '\0', 1, 0, 0); +} + +/*....................................................................... + * This is an action function which deletes backward from the cursor back to + * but not including a specified character. + */ +static KT_KEY_FN(gl_backward_delete_to) +{ + return gl_delete_find(gl, count, '\0', 0, 0, 0); +} + +/*....................................................................... + * This is an action function which deletes to a character specified by a + * previous search. + */ +static KT_KEY_FN(gl_delete_refind) +{ + return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward, + gl->vi.find_onto, 0); +} + +/*....................................................................... + * This is an action function which deletes to a character specified by a + * previous search, but in the opposite direction. + */ +static KT_KEY_FN(gl_delete_invert_refind) +{ + return gl_delete_find(gl, count, gl->vi.find_char, + !gl->vi.find_forward, gl->vi.find_onto, 0); +} + +/*....................................................................... + * This is an action function which converts the characters in the word + * following the cursor to upper case. + */ +static KT_KEY_FN(gl_upcase_word) +{ +/* + * Locate the count'th word ending after the cursor. + */ + int last = gl_nth_word_end_forward(gl, count); +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Upcase characters from the current cursor position to 'last'. + */ + while(gl->buff_curpos <= last) { + char *cptr = gl->line + gl->buff_curpos++; +/* + * Convert the character to upper case? + */ + if(islower((int)(unsigned char) *cptr)) + *cptr = toupper((int) *cptr); +/* + * Write the possibly modified character back. Note that for non-modified + * characters we want to do this as well, so as to advance the cursor. + */ + if(gl_output_char(gl, *cptr, cptr[1])) + return 1; + }; + return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ +} + +/*....................................................................... + * This is an action function which converts the characters in the word + * following the cursor to lower case. + */ +static KT_KEY_FN(gl_downcase_word) +{ +/* + * Locate the count'th word ending after the cursor. + */ + int last = gl_nth_word_end_forward(gl, count); +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Upcase characters from the current cursor position to 'last'. + */ + while(gl->buff_curpos <= last) { + char *cptr = gl->line + gl->buff_curpos++; +/* + * Convert the character to upper case? + */ + if(isupper((int)(unsigned char) *cptr)) + *cptr = tolower((int) *cptr); +/* + * Write the possibly modified character back. Note that for non-modified + * characters we want to do this as well, so as to advance the cursor. + */ + if(gl_output_char(gl, *cptr, cptr[1])) + return 1; + }; + return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ +} + +/*....................................................................... + * This is an action function which converts the first character of the + * following word to upper case, in order to capitalize the word, and + * leaves the cursor at the end of the word. + */ +static KT_KEY_FN(gl_capitalize_word) +{ + char *cptr; /* &gl->line[gl->buff_curpos] */ + int first; /* True for the first letter of the word */ + int i; +/* + * Keep a record of the current insert mode and the cursor position. + */ + int insert = gl->insert; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * We want to overwrite the modified word. + */ + gl->insert = 0; +/* + * Capitalize 'count' words. + */ + for(i=0; ibuff_curpos < gl->ntotal; i++) { + int pos = gl->buff_curpos; +/* + * If we are not already within a word, skip to the start of the word. + */ + for(cptr = gl->line + pos ; posntotal && !gl_is_word_char((int) *cptr); + pos++, cptr++) + ; +/* + * Move the cursor to the new position. + */ + if(gl_place_cursor(gl, pos)) + return 1; +/* + * While searching for the end of the word, change lower case letters + * to upper case. + */ + for(first=1; gl->buff_curposntotal && gl_is_word_char((int) *cptr); + gl->buff_curpos++, cptr++) { +/* + * Convert the character to upper case? + */ + if(first) { + if(islower((int)(unsigned char) *cptr)) + *cptr = toupper((int) *cptr); + } else { + if(isupper((int)(unsigned char) *cptr)) + *cptr = tolower((int) *cptr); + }; + first = 0; +/* + * Write the possibly modified character back. Note that for non-modified + * characters we want to do this as well, so as to advance the cursor. + */ + if(gl_output_char(gl, *cptr, cptr[1])) + return 1; + }; + }; +/* + * Restore the insertion mode. + */ + gl->insert = insert; + return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ +} + +/*....................................................................... + * This is an action function which redraws the current line. + */ +static KT_KEY_FN(gl_redisplay) +{ +/* + * Keep a record of the current cursor position. + */ + int buff_curpos = gl->buff_curpos; +/* + * Move the cursor to the start of the terminal line, and clear from there + * to the end of the display. + */ + if(gl_set_term_curpos(gl, 0) || + gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; +/* + * Display the current prompt. + */ + if(gl_display_prompt(gl)) + return 1; +/* + * Render the part of the line that the user has typed in so far. + */ + if(gl_output_string(gl, gl->line, '\0')) + return 1; +/* + * Restore the cursor position. + */ + if(gl_place_cursor(gl, buff_curpos)) + return 1; +/* + * Flush the redisplayed line to the terminal. + */ + return gl_flush_output(gl); +} + +/*....................................................................... + * This is an action function which clears the display and redraws the + * input line from the home position. + */ +static KT_KEY_FN(gl_clear_screen) +{ +/* + * Record the current cursor position. + */ + int buff_curpos = gl->buff_curpos; +/* + * Home the cursor and clear from there to the end of the display. + */ + if(gl_output_control_sequence(gl, gl->nline, gl->home) || + gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; +/* + * Redisplay the line. + */ + gl->term_curpos = 0; + gl->buff_curpos = 0; + if(gl_redisplay(gl,1)) + return 1; +/* + * Restore the cursor position. + */ + return gl_place_cursor(gl, buff_curpos); +} + +/*....................................................................... + * This is an action function which swaps the character under the cursor + * with the character to the left of the cursor. + */ +static KT_KEY_FN(gl_transpose_chars) +{ + char from[3]; /* The original string of 2 characters */ + char swap[3]; /* The swapped string of two characters */ +/* + * If we are at the beginning or end of the line, there aren't two + * characters to swap. + */ + if(gl->buff_curpos < 1 || gl->buff_curpos >= gl->ntotal) + return 0; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Get the original and swapped strings of the two characters. + */ + from[0] = gl->line[gl->buff_curpos - 1]; + from[1] = gl->line[gl->buff_curpos]; + from[2] = '\0'; + swap[0] = gl->line[gl->buff_curpos]; + swap[1] = gl->line[gl->buff_curpos - 1]; + swap[2] = '\0'; +/* + * Move the cursor to the start of the two characters. + */ + if(gl_place_cursor(gl, gl->buff_curpos-1)) + return 1; +/* + * Swap the two characters in the buffer. + */ + gl->line[gl->buff_curpos] = swap[0]; + gl->line[gl->buff_curpos+1] = swap[1]; +/* + * If the sum of the displayed width of the two characters + * in their current and final positions is the same, swapping can + * be done by just overwriting with the two swapped characters. + */ + if(gl_displayed_string_width(gl, from, -1, gl->term_curpos) == + gl_displayed_string_width(gl, swap, -1, gl->term_curpos)) { + int insert = gl->insert; + gl->insert = 0; + if(gl_output_char(gl, swap[0], swap[1]) || + gl_output_char(gl, swap[1], gl->line[gl->buff_curpos+2])) + return 1; + gl->insert = insert; +/* + * If the swapped substring has a different displayed size, we need to + * redraw everything after the first of the characters. + */ + } else { + if(gl_output_string(gl, gl->line + gl->buff_curpos, '\0') || + gl_output_control_sequence(gl, gl->nline, gl->clear_eod)) + return 1; + }; +/* + * Advance the cursor to the character after the swapped pair. + */ + return gl_place_cursor(gl, gl->buff_curpos + 2); +} + +/*....................................................................... + * This is an action function which sets a mark at the current cursor + * location. + */ +static KT_KEY_FN(gl_set_mark) +{ + gl->buff_mark = gl->buff_curpos; + return 0; +} + +/*....................................................................... + * This is an action function which swaps the mark location for the + * cursor location. + */ +static KT_KEY_FN(gl_exchange_point_and_mark) +{ +/* + * Get the old mark position, and limit to the extent of the input + * line. + */ + int old_mark = gl->buff_mark <= gl->ntotal ? gl->buff_mark : gl->ntotal; +/* + * Make the current cursor position the new mark. + */ + gl->buff_mark = gl->buff_curpos; +/* + * Move the cursor to the old mark position. + */ + return gl_place_cursor(gl, old_mark); +} + +/*....................................................................... + * This is an action function which deletes the characters between the + * mark and the cursor, recording them in gl->cutbuf for later pasting. + */ +static KT_KEY_FN(gl_kill_region) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Limit the mark to be within the line. + */ + if(gl->buff_mark > gl->ntotal) + gl->buff_mark = gl->ntotal; +/* + * If there are no characters between the cursor and the mark, simply clear + * the cut buffer. + */ + if(gl->buff_mark == gl->buff_curpos) { + gl->cutbuf[0] = '\0'; + return 0; + }; +/* + * If the mark is before the cursor, swap the cursor and the mark. + */ + if(gl->buff_mark < gl->buff_curpos && gl_exchange_point_and_mark(gl,1)) + return 1; +/* + * Delete the characters. + */ + if(gl_delete_chars(gl, gl->buff_mark - gl->buff_curpos, 1)) + return 1; +/* + * Make the mark the same as the cursor position. + */ + gl->buff_mark = gl->buff_curpos; + return 0; +} + +/*....................................................................... + * This is an action function which records the characters between the + * mark and the cursor, in gl->cutbuf for later pasting. + */ +static KT_KEY_FN(gl_copy_region_as_kill) +{ + int ca, cb; /* The indexes of the first and last characters in the region */ + int mark; /* The position of the mark */ +/* + * Get the position of the mark, limiting it to lie within the line. + */ + mark = gl->buff_mark > gl->ntotal ? gl->ntotal : gl->buff_mark; +/* + * If there are no characters between the cursor and the mark, clear + * the cut buffer. + */ + if(mark == gl->buff_curpos) { + gl->cutbuf[0] = '\0'; + return 0; + }; +/* + * Get the line indexes of the first and last characters in the region. + */ + if(mark < gl->buff_curpos) { + ca = mark; + cb = gl->buff_curpos - 1; + } else { + ca = gl->buff_curpos; + cb = mark - 1; + }; +/* + * Copy the region to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line + ca, cb + 1 - ca); + gl->cutbuf[cb + 1 - ca] = '\0'; + return 0; +} + +/*....................................................................... + * This is an action function which inserts the contents of the cut + * buffer at the current cursor location. + */ +static KT_KEY_FN(gl_yank) +{ + int i; +/* + * Set the mark at the current location. + */ + gl->buff_mark = gl->buff_curpos; +/* + * Do nothing else if the cut buffer is empty. + */ + if(gl->cutbuf[0] == '\0') + return gl_ring_bell(gl, 1); +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Insert the string count times. + */ + for(i=0; icutbuf)) + return 1; + }; +/* + * gl_add_string_to_line() leaves the cursor after the last character that + * was pasted, whereas vi leaves the cursor over the last character pasted. + */ + if(gl->editor == GL_VI_MODE && gl_cursor_left(gl, 1)) + return 1; + return 0; +} + +/*....................................................................... + * This is an action function which inserts the contents of the cut + * buffer one character beyond the current cursor location. + */ +static KT_KEY_FN(gl_append_yank) +{ + int was_command = gl->vi.command; + int i; +/* + * If the cut buffer is empty, ring the terminal bell. + */ + if(gl->cutbuf[0] == '\0') + return gl_ring_bell(gl, 1); +/* + * Set the mark at the current location + 1. + */ + gl->buff_mark = gl->buff_curpos + 1; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Arrange to paste the text in insert mode after the current character. + */ + if(gl_vi_append(gl, 0)) + return 1; +/* + * Insert the string count times. + */ + for(i=0; icutbuf)) + return 1; + }; +/* + * Switch back to command mode if necessary. + */ + if(was_command) + gl_vi_command_mode(gl); + return 0; +} + +#ifdef USE_SIGWINCH +/*....................................................................... + * Respond to the receipt of a window change signal. + * + * Input: + * gl GetLine * The resource object of this library. + * redisplay int If true redisplay the current line after + * getting the new window size. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_resize_terminal(GetLine *gl, int redisplay) +{ + int lines_used; /* The number of lines currently in use */ + struct winsize size; /* The new size information */ + int i; +/* + * Record the fact that the sigwinch signal has been noted. + */ + if(gl_pending_signal == SIGWINCH) + gl_pending_signal = -1; +/* + * Query the new terminal window size. Ignore invalid responses. + */ + if(ioctl(gl->output_fd, TIOCGWINSZ, &size) == 0 && + size.ws_row > 0 && size.ws_col > 0) { +/* + * Redisplay the input line? + */ + if(redisplay) { +/* + * How many lines are currently displayed. + */ + lines_used = (gl_displayed_string_width(gl,gl->line,-1,gl->prompt_len) + + gl->prompt_len + gl->ncolumn - 1) / gl->ncolumn; +/* + * Move to the cursor to the start of the line. + */ + for(i=1; iup)) + return 1; + }; + if(gl_output_control_sequence(gl, 1, gl->bol)) + return 1; +/* + * Clear to the end of the terminal. + */ + if(gl_output_control_sequence(gl, size.ws_row, gl->clear_eod)) + return 1; +/* + * Record the fact that the cursor is now at the beginning of the line. + */ + gl->term_curpos = 0; + }; +/* + * Update the recorded window size. + */ + gl->nline = size.ws_row; + gl->ncolumn = size.ws_col; + }; +/* + * Redisplay the line? + */ + return redisplay ? gl_redisplay(gl,1) : 0; +} +#endif + +/*....................................................................... + * This is the action function that recalls the previous line in the + * history buffer. + */ +static KT_KEY_FN(gl_up_history) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * Forget any previous recall session. + */ + gl->preload_id = 0; +/* + * We don't want a search prefix for this function. + */ + if(_glh_search_prefix(gl->glh, gl->line, 0)) + return 1; +/* + * Recall the count'th next older line in the history list. If the first one + * fails we can return since nothing has changed otherwise we must continue + * and update the line state. + */ + if(_glh_find_backwards(gl->glh, gl->line, gl->linelen) == NULL) + return 0; + while(--count && _glh_find_backwards(gl->glh, gl->line, gl->linelen)) + ; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange to have the cursor placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * This is the action function that recalls the next line in the + * history buffer. + */ +static KT_KEY_FN(gl_down_history) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * If no search is currently in progress continue a previous recall + * session from a previous entered line if possible. + */ + if(_glh_line_id(gl->glh, 0) == 0 && gl->preload_id) { + _glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen); + gl->preload_id = 0; + } else { +/* + * We don't want a search prefix for this function. + */ + if(_glh_search_prefix(gl->glh, gl->line, 0)) + return 1; +/* + * Recall the count'th next newer line in the history list. If the first one + * fails we can return since nothing has changed otherwise we must continue + * and update the line state. + */ + if(_glh_find_forwards(gl->glh, gl->line, gl->linelen) == NULL) + return 0; + while(--count && _glh_find_forwards(gl->glh, gl->line, gl->linelen)) + ; + }; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange to have the cursor placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * This is the action function that recalls the previous line in the + * history buffer whos prefix matches the characters that currently + * precede the cursor. By setting count=-1, this can be used internally + * to force searching for the prefix used in the last search. + */ +static KT_KEY_FN(gl_history_search_backward) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * Forget any previous recall session. + */ + gl->preload_id = 0; +/* + * If the previous thing that the user did wasn't to execute a history + * search function, set the search prefix equal to the string that + * precedes the cursor. In vi command mode include the character that + * is under the cursor in the string. If count<0 force a repeat search + * even if the last command wasn't a history command. + */ + if(gl->last_search != gl->keyseq_count - 1 && count>=0 && + _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + + (gl->editor==GL_VI_MODE && gl->ntotal>0))) + return 1; +/* + * Record the key sequence number in which this search function is + * being executed, so that the next call to this function or + * gl_history_search_forward() knows if any other operations + * were performed in between. + */ + gl->last_search = gl->keyseq_count; +/* + * Search backwards for a match to the part of the line which precedes the + * cursor. + */ + if(_glh_find_backwards(gl->glh, gl->line, gl->linelen) == NULL) + return 0; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange to have the cursor placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * This is the action function that recalls the previous line in the + * history buffer who's prefix matches that specified in an earlier call + * to gl_history_search_backward() or gl_history_search_forward(). + */ +static KT_KEY_FN(gl_history_re_search_backward) +{ + return gl_history_search_backward(gl, -1); +} + +/*....................................................................... + * This is the action function that recalls the next line in the + * history buffer who's prefix matches that specified in the earlier call + * to gl_history_search_backward) which started the history search. + * By setting count=-1, this can be used internally to force searching + * for the prefix used in the last search. + */ +static KT_KEY_FN(gl_history_search_forward) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * If the previous thing that the user did wasn't to execute a history + * search function, set the search prefix equal to the string that + * precedes the cursor. In vi command mode include the character that + * is under the cursor in the string. If count<0 force a repeat search + * even if the last command wasn't a history command. + */ + if(gl->last_search != gl->keyseq_count - 1 && count>=0 && + _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos + + (gl->editor==GL_VI_MODE && gl->ntotal>0))) + return 1; +/* + * Record the key sequence number in which this search function is + * being executed, so that the next call to this function or + * gl_history_search_backward() knows if any other operations + * were performed in between. + */ + gl->last_search = gl->keyseq_count; +/* + * Search forwards for the next matching line. + */ + if(_glh_find_forwards(gl->glh, gl->line, gl->linelen) == NULL) + return 0; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange for the cursor to be placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * This is the action function that recalls the next line in the + * history buffer who's prefix matches that specified in an earlier call + * to gl_history_search_backward() or gl_history_search_forward(). + */ +static KT_KEY_FN(gl_history_re_search_forward) +{ + return gl_history_search_forward(gl, -1); +} + +/*....................................................................... + * This is the tab completion function that completes the filename that + * precedes the cursor position. + */ +static KT_KEY_FN(gl_complete_word) +{ + CplMatches *matches; /* The possible completions */ + int redisplay=0; /* True if the whole line needs to be redrawn */ + int suffix_len; /* The length of the completion extension */ + int cont_len; /* The length of any continuation suffix */ + int nextra; /* The number of characters being added to the */ + /* total length of the line. */ + int buff_pos; /* The buffer index at which the completion is */ + /* to be inserted. */ +/* + * In vi command mode, switch to append mode so that the character below + * the character is included in the completion (otherwise people can't + * complete at the end of the line). + */ + if(gl->vi.command && gl_vi_append(gl, 0)) + return 1; +/* + * Get the cursor position at which the completion is to be inserted. + */ + buff_pos = gl->buff_curpos; +/* + * Perform the completion. + */ + matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, gl->cpl_data, + gl->cpl_fn); + if(!matches) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", cpl_last_error(gl->cpl)) < 0) + return 1; + gl->term_curpos = 0; + redisplay = 1; +/* + * Are there any completions? + */ + } else if(matches->nmatch >= 1) { +/* + * If there any ambiguous matches, report them, starting on a new line. + */ + if(matches->nmatch > 1 && gl->echo) { + if(fprintf(gl->output_fp, "\r\n") < 0) + return 1; + cpl_list_completions(matches, gl->output_fp, gl->ncolumn); + redisplay = 1; + }; +/* + * If the callback called gl_change_prompt(), we will need to redisplay + * the whole line. + */ + if(gl->prompt_changed) + redisplay = 1; +/* + * Get the length of the suffix and any continuation suffix to add to it. + */ + suffix_len = strlen(matches->suffix); + cont_len = strlen(matches->cont_suffix); +/* + * If there is an unambiguous match, and the continuation suffix ends in + * a newline, strip that newline and arrange to have getline return + * after this action function returns. + */ + if(matches->nmatch==1 && cont_len > 0 && + matches->cont_suffix[cont_len - 1] == '\n') { + cont_len--; + if(gl_newline(gl, 1)) + return 1; + }; +/* + * Work out the number of characters that are to be added. + */ + nextra = suffix_len + cont_len; +/* + * Is there anything to be added? + */ + if(nextra) { +/* + * Will there be space for the expansion in the line buffer? + */ + if(gl->ntotal + nextra < gl->linelen) { +/* + * Make room to insert the filename extension. + */ + memmove(gl->line + gl->buff_curpos + nextra, gl->line + gl->buff_curpos, + gl->ntotal - gl->buff_curpos); +/* + * Insert the filename extension. + */ + memcpy(gl->line + gl->buff_curpos, matches->suffix, suffix_len); +/* + * Add the terminating characters. + */ + memcpy(gl->line + gl->buff_curpos + suffix_len, matches->cont_suffix, + cont_len); +/* + * Record the increased length of the line. + */ + gl->ntotal += nextra; +/* + * Place the cursor position at the end of the completion. + */ + gl->buff_curpos += nextra; +/* + * Terminate the extended line. + */ + gl->line[gl->ntotal] = '\0'; +/* + * If we don't have to redisplay the whole line, redisplay the part + * of the line which follows the original cursor position, and place + * the cursor at the end of the completion. + */ + if(!redisplay) { + if(gl_output_control_sequence(gl, gl->nline, gl->clear_eod) || + gl_output_string(gl, gl->line + buff_pos, '\0') || + gl_place_cursor(gl, gl->buff_curpos)) + return 1; + }; + } else { + fprintf(stderr, + "\r\nInsufficient room in line for file completion.\r\n"); + redisplay = 1; + }; + }; + }; +/* + * Redisplay the whole line? + */ + if(redisplay) { + gl->term_curpos = 0; + if(gl_redisplay(gl,1)) + return 1; + }; + return 0; +} + +/*....................................................................... + * This is the function that expands the filename that precedes the + * cursor position. It expands ~user/ expressions, $envvar expressions, + * and wildcards. + */ +static KT_KEY_FN(gl_expand_filename) +{ + char *start_path; /* The pointer to the start of the pathname in */ + /* gl->line[]. */ + FileExpansion *result; /* The results of the filename expansion */ + int pathlen; /* The length of the pathname being expanded */ + int redisplay=0; /* True if the whole line needs to be redrawn */ + int length; /* The number of characters needed to display the */ + /* expanded files. */ + int nextra; /* The number of characters to be added */ + int i,j; +/* + * In vi command mode, switch to append mode so that the character below + * the character is included in the completion (otherwise people can't + * complete at the end of the line). + */ + if(gl->vi.command && gl_vi_append(gl, 0)) + return 1; +/* + * Locate the start of the filename that precedes the cursor position. + */ + start_path = _pu_start_of_path(gl->line, + gl->buff_curpos > 0 ? gl->buff_curpos : 0); + if(!start_path) + return 1; +/* + * Get the length of the string that is to be expanded. + */ + pathlen = gl->buff_curpos - (start_path - gl->line); +/* + * Attempt to expand it. + */ + result = ef_expand_file(gl->ef, start_path, pathlen); +/* + * If there was an error, report the error on a new line, then redraw + * the original line. + */ + if(!result) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", ef_last_error(gl->ef)) < 0) + return 1; + gl->term_curpos = 0; + return gl_redisplay(gl,1); + }; +/* + * If no files matched, report this as well. + */ + if(result->nfile == 0 || !result->exists) { + if(gl->echo && fprintf(gl->output_fp, "\r\nNo files match.\n") < 0) + return 1; + gl->term_curpos = 0; + return gl_redisplay(gl,1); + }; +/* + * If in vi command mode, preserve the current line for potential use by + * vi-undo. + */ + gl_save_for_undo(gl); +/* + * Work out how much space we will need to display all of the matching + * filenames, taking account of the space that we need to place between + * them, and the number of additional '\' characters needed to escape + * spaces, tabs and backslash characters in the individual filenames. + */ + length = 0; + for(i=0; infile; i++) { + char *file = result->files[i]; + while(*file) { + int c = *file++; + switch(c) { + case ' ': case '\t': case '\\': case '*': case '?': case '[': + length++; /* Count extra backslash characters */ + }; + length++; /* Count the character itself */ + }; + length++; /* Count the space that follows each filename */ + }; +/* + * Work out the number of characters that are to be added. + */ + nextra = length - pathlen; +/* + * Will there be space for the expansion in the line buffer? + */ + if(gl->ntotal + nextra >= gl->linelen) { + fprintf(stderr, "\r\nInsufficient room in line for file expansion.\r\n"); + redisplay = 1; + } else { +/* + * Do we need to move the part of the line that followed the unexpanded + * filename? + */ + if(nextra != 0) { + memmove(gl->line + gl->buff_curpos + nextra, gl->line + gl->buff_curpos, + gl->ntotal - gl->buff_curpos); + }; +/* + * Insert the filenames, separated by spaces, and with internal spaces, + * tabs and backslashes escaped with backslashes. + */ + for(i=0,j=start_path - gl->line; infile; i++) { + char *file = result->files[i]; + while(*file) { + int c = *file++; + switch(c) { + case ' ': case '\t': case '\\': case '*': case '?': case '[': + gl->line[j++] = '\\'; + }; + gl->line[j++] = c; + }; + gl->line[j++] = ' '; + }; +/* + * Record the increased length of the line. + */ + gl->ntotal += nextra; +/* + * Place the cursor position at the end of the expansion. + */ + gl->buff_curpos += nextra; +/* + * Terminate the extended line. + */ + gl->line[gl->ntotal] = '\0'; + }; +/* + * Display the whole line on a new line? + */ + if(redisplay) { + gl->term_curpos = 0; + return gl_redisplay(gl,1); + }; +/* + * Otherwise redisplay the part of the line which follows the start of + * the original filename. + */ + if(gl_set_term_curpos(gl, gl_buff_curpos_to_term_curpos(gl, start_path - gl->line)) || + gl_output_control_sequence(gl, gl->nline, gl->clear_eod) || + gl_output_string(gl, start_path, gl->line[gl->buff_curpos])) + return 1; +/* + * Restore the cursor position to the end of the expansion. + */ + return gl_place_cursor(gl, gl->buff_curpos); +} + +/*....................................................................... + * This is the action function that lists glob expansions of the + * filename that precedes the cursor position. It expands ~user/ + * expressions, $envvar expressions, and wildcards. + */ +static KT_KEY_FN(gl_list_glob) +{ + char *start_path; /* The pointer to the start of the pathname in */ + /* gl->line[]. */ + FileExpansion *result; /* The results of the filename expansion */ + int pathlen; /* The length of the pathname being expanded */ +/* + * Locate the start of the filename that precedes the cursor position. + */ + start_path = _pu_start_of_path(gl->line, + gl->buff_curpos > 0 ? gl->buff_curpos : 0); + if(!start_path) + return 1; +/* + * Get the length of the string that is to be expanded. + */ + pathlen = gl->buff_curpos - (start_path - gl->line); +/* + * Attempt to expand it. + */ + result = ef_expand_file(gl->ef, start_path, pathlen); +/* + * If there was an error, report the error. + */ + if(!result) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", ef_last_error(gl->ef)) < 0) + return 1; +/* + * If no files matched, report this as well. + */ + } else if(result->nfile == 0 || !result->exists) { + if(gl->echo && fprintf(gl->output_fp, "\r\nNo files match.\n") < 0) + return 1; +/* + * List the matching expansions. + */ + } else if(gl->echo) { + if(fprintf(gl->output_fp, "\r\n") < 0) + return 1; + ef_list_expansions(result, gl->output_fp, gl->ncolumn); + }; +/* + * Redisplay the line being edited. + */ + gl->term_curpos = 0; + return gl_redisplay(gl,1); +} + +/*....................................................................... + * Return non-zero if a character should be considered a part of a word. + * + * Input: + * c int The character to be tested. + * Output: + * return int True if the character should be considered part of a word. + */ +static int gl_is_word_char(int c) +{ + return isalnum((int)(unsigned char)c) || strchr(GL_WORD_CHARS, c) != NULL; +} + +/*....................................................................... + * Override the builtin file-completion callback that is bound to the + * "complete_word" action function. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * data void * This is passed to match_fn() whenever it is + * called. It could, for example, point to a + * symbol table where match_fn() could look + * for possible completions. + * match_fn CplMatchFn * The function that will identify the prefix + * to be completed from the input line, and + * report matching symbols. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_customize_completion(GetLine *gl, void *data, CplMatchFn *match_fn) +{ +/* + * Check the arguments. + */ + if(!gl || !match_fn) { + fprintf(stderr, "gl_customize_completion: NULL argument(s).\n"); + return 1; + }; +/* + * Record the new completion function and its callback data. + */ + gl->cpl_fn = match_fn; + gl->cpl_data = data; + return 0; +} + +/*....................................................................... + * Change the terminal (or stream) that getline interacts with. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * input_fp FILE * The stdio stream to read from. + * output_fp FILE * The stdio stream to write to. + * term char * The terminal type. This can be NULL if + * either or both of input_fp and output_fp don't + * refer to a terminal. Otherwise it should refer + * to an entry in the terminal information database. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, + const char *term) +{ + int is_term = 0; /* True if both input_fd and output_fd are associated */ + /* with a terminal. */ +/* + * Require that input_fp and output_fp both be valid. + */ + if(!input_fp || !output_fp) { + fprintf(stderr, "\r\ngl_change_terminal: Bad input/output stream(s).\n"); + return 1; + }; +/* + * If we are displacing a previous terminal, remove it from the list + * of fds being watched. + */ +#ifdef HAVE_SELECT + if(gl->input_fd >= 0) + FD_CLR(gl->input_fd, &gl->rfds); +#endif +/* + * Record the file descriptors and streams. + */ + gl->input_fp = input_fp; + gl->input_fd = fileno(input_fp); + gl->output_fp = output_fp; + gl->output_fd = fileno(output_fp); +/* + * Make sure that the file descriptor will be visible in the set to + * be watched. + */ +#ifdef HAVE_SELECT + FD_SET(gl->input_fd, &gl->rfds); + if(gl->input_fd > gl->max_fd) + gl->max_fd = gl->input_fd; +#endif +/* + * Disable terminal interaction until we have enough info to interact + * with the terminal. + */ + gl->is_term = 0; +/* + * For terminal editing, we need both output_fd and input_fd to refer to + * a terminal. While we can't verify that they both point to the same + * terminal, we can verify that they point to terminals. + */ + is_term = isatty(gl->input_fd) && isatty(gl->output_fd); +/* + * If we are interacting with a terminal and no terminal type has been + * specified, treat it as a generic ANSI terminal. + */ + if(is_term && !term) + term = "ansi"; +/* + * Make a copy of the terminal type string. + */ + if(term != gl->term) { +/* + * Delete any old terminal type string. + */ + if(gl->term) { + free(gl->term); + gl->term = NULL; + }; +/* + * Make a copy of the new terminal-type string, if any. + */ + if(term) { + gl->term = (char *) malloc(strlen(term)+1); + if(gl->term) + strcpy(gl->term, term); + }; + }; +/* + * Clear any terminal-specific key bindings that were taken from the + * settings of the last terminal. + */ + _kt_clear_bindings(gl->bindings, KTB_TERM); +/* + * If we have a terminal install new bindings for it. + */ + if(is_term) { +/* + * Get the current settings of the terminal. + */ + if(tcgetattr(gl->input_fd, &gl->oldattr)) { + fprintf(stderr, "\r\ngl_change_terminal: tcgetattr error: %s\n", + strerror(errno)); + return 1; + }; +/* + * Lookup the terminal control string and size information. + */ + if(gl_control_strings(gl, term)) + return 1; +/* + * We now have enough info to interact with the terminal. + */ + gl->is_term = 1; +/* + * Bind terminal-specific keys. + */ + if(gl_bind_terminal_keys(gl)) + return 1; + }; + return 0; +} + +/*....................................................................... + * Set up terminal-specific key bindings. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_bind_terminal_keys(GetLine *gl) +{ +/* + * Install key-bindings for the special terminal characters. + */ + if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VINTR], + "user-interrupt") || + gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VQUIT], "abort") || + gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VSUSP], "suspend")) + return 1; +/* + * In vi-mode, arrange for the above characters to be seen in command + * mode. + */ + if(gl->editor == GL_VI_MODE) { + if(gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VINTR]), + "user-interrupt") || + gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VQUIT]), + "abort") || + gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VSUSP]), + "suspend")) + return 1; + }; +/* + * Non-universal special keys. + */ +#ifdef VLNEXT + if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VLNEXT], + "literal-next")) + return 1; +#else + if(_kt_set_keybinding(gl->bindings, KTB_TERM, "^V", "literal-next")) + return 1; +#endif +/* + * Bind action functions to the terminal-specific arrow keys + * looked up by gl_control_strings(). + */ + if(_gl_bind_arrow_keys(gl)) + return 1; + return 0; +} + +/*....................................................................... + * This function is normally bound to control-D. When it is invoked within + * a line it deletes the character which follows the cursor. When invoked + * at the end of the line it lists possible file completions, and when + * invoked on an empty line it causes gl_get_line() to return EOF. This + * function emulates the one that is normally bound to control-D by tcsh. + */ +static KT_KEY_FN(gl_del_char_or_list_or_eof) +{ +/* + * If we have an empty line arrange to return EOF. + */ + if(gl->ntotal < 1) { + return 1; +/* + * If we are at the end of the line list possible completions. + */ + } else if(gl->buff_curpos >= gl->ntotal) { +/* + * Get the list of possible completions. + */ + CplMatches *matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, + gl->cpl_data, gl->cpl_fn); + if(!matches) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", cpl_last_error(gl->cpl)) < 0) + return 1; + gl->term_curpos = 0; +/* + * List the matches. + */ + } else if(matches->nmatch > 0 && gl->echo) { + if(fprintf(gl->output_fp, "\r\n") < 0) + return 1; + cpl_list_completions(matches, gl->output_fp, gl->ncolumn); + }; +/* + * Redisplay the line unchanged. + */ + return gl_redisplay(gl,1); +/* + * Within the line delete the character that follows the cursor. + */ + } else { +/* + * If in vi command mode, first preserve the current line for potential use + * by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Delete 'count' characters. + */ + return gl_forward_delete_char(gl, count); + }; +} + +/*....................................................................... + * This function is normally bound to control-D in vi mode. When it is + * invoked within a line it lists possible file completions, and when + * invoked on an empty line it causes gl_get_line() to return EOF. This + * function emulates the one that is normally bound to control-D by tcsh. + */ +static KT_KEY_FN(gl_list_or_eof) +{ +/* + * If we have an empty line arrange to return EOF. + */ + if(gl->ntotal < 1) { + return 1; +/* + * Otherwise list possible completions. + */ + } else { +/* + * Get the list of possible completions. + */ + CplMatches *matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, + gl->cpl_data, gl->cpl_fn); + if(!matches) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", cpl_last_error(gl->cpl)) < 0) + return 1; + gl->term_curpos = 0; +/* + * List the matches. + */ + } else if(matches->nmatch > 0 && gl->echo) { + if(fprintf(gl->output_fp, "\r\n") < 0) + return 1; + cpl_list_completions(matches, gl->output_fp, gl->ncolumn); + }; +/* + * Redisplay the line unchanged. + */ + return gl_redisplay(gl,1); + }; +} + +/*....................................................................... + * Where the user has used the symbolic arrow-key names to specify + * arrow key bindings, bind the specified action functions to the default + * and terminal specific arrow key sequences. + * + * Input: + * gl GetLine * The getline resource object. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _gl_bind_arrow_keys(GetLine *gl) +{ +/* + * Process each of the arrow keys. + */ + if(_gl_rebind_arrow_key(gl->bindings, "up", gl->u_arrow, "^[[A", "^[OA") || + _gl_rebind_arrow_key(gl->bindings, "down", gl->d_arrow, "^[[B", "^[OB") || + _gl_rebind_arrow_key(gl->bindings, "left", gl->l_arrow, "^[[D", "^[OD") || + _gl_rebind_arrow_key(gl->bindings, "right", gl->r_arrow, "^[[C", "^[OC")) + return 1; + return 0; +} + +/*....................................................................... + * Lookup the action function of a symbolic arrow-key binding, and bind + * it to the terminal-specific and default arrow-key sequences. Note that + * we don't trust the terminal-specified key sequences to be correct. + * The main reason for this is that on some machines the xterm terminfo + * entry is for hardware X-terminals, rather than xterm terminal emulators + * and the two terminal types emit different character sequences when the + * their cursor keys are pressed. As a result we also supply a couple + * of default key sequences. + * + * Input: + * bindings KeyTab * The table of key bindings. + * name char * The symbolic name of the arrow key. + * term_seq char * The terminal-specific arrow-key sequence. + * def_seq1 char * The first default arrow-key sequence. + * def_seq2 char * The second arrow-key sequence. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _gl_rebind_arrow_key(KeyTab *bindings, const char *name, + const char *term_seq, const char *def_seq1, + const char *def_seq2) +{ + int first,last; /* The indexes of the first and last matching entries */ +/* + * Lookup the key binding for the symbolic name of the arrow key. This + * will either be the default action, or a user provided one. + */ + if(_kt_lookup_keybinding(bindings, name, strlen(name), &first, &last) + == KT_EXACT_MATCH) { +/* + * Get the action function. + */ + KtKeyFn *key_fn = bindings->table[first].keyfn; +/* + * Bind this to each of the specified key sequences. + */ + if((term_seq && _kt_set_keyfn(bindings, KTB_TERM, term_seq, key_fn)) || + (def_seq1 && _kt_set_keyfn(bindings, KTB_NORM, def_seq1, key_fn)) || + (def_seq2 && _kt_set_keyfn(bindings, KTB_NORM, def_seq2, key_fn))) + return 1; + }; + return 0; +} + +/*....................................................................... + * Read getline configuration information from a given file. + * + * Input: + * gl GetLine * The getline resource object. + * filename const char * The name of the file to read configuration + * information from. The contents of this file + * are as described in the gl_get_line(3) man + * page for the default ~/.teclarc configuration + * file. + * who KtBinder Who bindings are to be installed for. + * Output: + * return int 0 - OK. + * 1 - Irrecoverable error. + */ +static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who) +{ + FileExpansion *expansion; /* The expansion of the filename */ + FILE *fp; /* The opened file */ + int waserr = 0; /* True if an error occurred while reading */ + int lineno = 1; /* The line number being processed */ +/* + * Check the arguments. + */ + if(!gl || !filename) { + fprintf(stderr, "_gl_read_config_file: Invalid arguments.\n"); + return 1; + }; +/* + * Expand the filename. + */ + expansion = ef_expand_file(gl->ef, filename, -1); + if(!expansion) { + fprintf(stderr, "Unable to expand %s (%s).\n", filename, + ef_last_error(gl->ef)); + return 1; + }; +/* + * Attempt to open the file. + */ + fp = fopen(expansion->files[0], "r"); +/* + * It isn't an error for there to be no configuration file. + */ + if(!fp) + return 0; +/* + * Parse the contents of the file. + */ + while(!waserr && !feof(fp)) + waserr = _gl_parse_config_line(gl, fp, glc_file_getc, filename, who, + &lineno); +/* + * Bind action functions to the terminal-specific arrow keys. + */ + if(_gl_bind_arrow_keys(gl)) + return 1; +/* + * Clean up. + */ + (void) fclose(fp); + return waserr; +} + +/*....................................................................... + * Read GetLine configuration information from a string. The contents of + * the string are the same as those described in the gl_get_line(3) + * man page for the contents of the ~/.teclarc configuration file. + */ +static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who) +{ + const char *bptr; /* A pointer into buffer[] */ + int waserr = 0; /* True if an error occurred while reading */ + int lineno = 1; /* The line number being processed */ +/* + * Check the arguments. + */ + if(!gl || !buffer) { + fprintf(stderr, "_gl_read_config_string: Invalid arguments.\n"); + return 1; + }; +/* + * Get a pointer to the start of the buffer. + */ + bptr = buffer; +/* + * Parse the contents of the buffer. + */ + while(!waserr && *bptr) + waserr = _gl_parse_config_line(gl, &bptr, glc_buff_getc, "", who, &lineno); +/* + * Bind action functions to the terminal-specific arrow keys. + */ + if(_gl_bind_arrow_keys(gl)) + return 1; + return waserr; +} + +/*....................................................................... + * Parse the next line of a getline configuration file. + * + * Input: + * gl GetLine * The getline resource object. + * stream void * The pointer representing the stream to be read + * by getc_fn(). + * getc_fn GlcGetcFn * A callback function which when called with + * 'stream' as its argument, returns the next + * unread character from the stream. + * origin const char * The name of the entity being read (eg. a + * file name). + * who KtBinder Who bindings are to be installed for. + * Input/Output: + * lineno int * The line number being processed is to be + * maintained in *lineno. + * Output: + * return int 0 - OK. + * 1 - Irrecoverable error. + */ +static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn, + const char *origin, KtBinder who, int *lineno) +{ + char buffer[GL_CONF_BUFLEN+1]; /* The input line buffer */ + char *argv[GL_CONF_MAXARG]; /* The argument list */ + int argc = 0; /* The number of arguments in argv[] */ + int c; /* A character from the file */ + int escaped = 0; /* True if the next character is escaped */ + int i; +/* + * Skip spaces and tabs. + */ + do c = getc_fn(stream); while(c==' ' || c=='\t'); +/* + * Comments extend to the end of the line. + */ + if(c=='#') + do c = getc_fn(stream); while(c != '\n' && c != EOF); +/* + * Ignore empty lines. + */ + if(c=='\n' || c==EOF) { + (*lineno)++; + return 0; + }; +/* + * Record the buffer location of the start of the first argument. + */ + argv[argc] = buffer; +/* + * Read the rest of the line, stopping early if a comment is seen, or + * the buffer overflows, and replacing sequences of spaces with a + * '\0', and recording the thus terminated string as an argument. + */ + i = 0; + while(i= GL_CONF_MAXARG) { + fprintf(stderr, "%s:%d: Too many arguments.\n", origin, *lineno); + do c = getc_fn(stream); while(c != '\n' && c != EOF); /* Skip past eol */ + return 0; + }; + argv[argc] = buffer + i; +/* + * The next character was preceded by spaces, so it isn't escaped. + */ + escaped = 0; + } else { +/* + * If we hit an unescaped backslash, this means that we should arrange + * to treat the next character like a simple alphabetical character. + */ + if(c=='\\' && !escaped) { + escaped = 1; +/* + * Splice lines where the newline is escaped. + */ + } else if(c=='\n' && escaped) { + (*lineno)++; +/* + * Record a normal character, preserving any preceding backslash. + */ + } else { + if(escaped) + buffer[i++] = '\\'; + if(i>=GL_CONF_BUFLEN) + break; + escaped = 0; + buffer[i++] = c; + }; +/* + * Get the next character. + */ + c = getc_fn(stream); + }; + }; +/* + * Did the buffer overflow? + */ + if(i>=GL_CONF_BUFLEN) { + fprintf(stderr, "%s:%d: Line too long.\n", origin, *lineno); + return 0; + }; +/* + * The first argument should be a command name. + */ + if(strcmp(argv[0], "bind") == 0) { + const char *action = NULL; /* A NULL action removes a keybinding */ + const char *keyseq = NULL; + switch(argc) { + case 3: + action = argv[2]; + case 2: /* Note the intentional fallthrough */ + keyseq = argv[1]; +/* + * Attempt to record the new keybinding. + */ + if(_kt_set_keybinding(gl->bindings, who, keyseq, action)) { + fprintf(stderr, "The error occurred at line %d of %s.\n", *lineno, + origin); + }; + break; + default: + fprintf(stderr, "%s:%d: Wrong number of arguments.\n", origin, *lineno); + }; + } else if(strcmp(argv[0], "edit-mode") == 0) { + if(argc == 2 && strcmp(argv[1], "emacs") == 0) { + gl_change_editor(gl, GL_EMACS_MODE); + } else if(argc == 2 && strcmp(argv[1], "vi") == 0) { + gl_change_editor(gl, GL_VI_MODE); + } else if(argc == 2 && strcmp(argv[1], "none") == 0) { + gl_change_editor(gl, GL_NO_EDITOR); + } else { + fprintf(stderr, "%s:%d: The argument of editor should be vi or emacs.\n", + origin, *lineno); + }; + } else if(strcmp(argv[0], "nobeep") == 0) { + gl->silence_bell = 1; + } else { + fprintf(stderr, "%s:%d: Unknown command name '%s'.\n", origin, *lineno, + argv[0]); + }; +/* + * Skip any trailing comment. + */ + while(c != '\n' && c != EOF) + c = getc_fn(stream); + (*lineno)++; + return 0; +} + +/*....................................................................... + * This is the _gl_parse_config_line() callback function which reads the + * next character from a configuration file. + */ +static GLC_GETC_FN(glc_file_getc) +{ + return fgetc((FILE *) stream); +} + +/*....................................................................... + * This is the _gl_parse_config_line() callback function which reads the + * next character from a buffer. Its stream argument is a pointer to a + * variable which is, in turn, a pointer into the buffer being read from. + */ +static GLC_GETC_FN(glc_buff_getc) +{ + const char **lptr = (char const **) stream; + return **lptr ? *(*lptr)++ : EOF; +} + +/*....................................................................... + * When this action is triggered, it arranges to temporarily read command + * lines from the regular file whos name precedes the cursor. + * The current line is first discarded. + */ +static KT_KEY_FN(gl_read_from_file) +{ + char *start_path; /* The pointer to the start of the pathname in */ + /* gl->line[]. */ + FileExpansion *result; /* The results of the filename expansion */ + int pathlen; /* The length of the pathname being expanded */ + int error_reported = 0; /* True after an error has been reported */ +/* + * Locate the start of the filename that precedes the cursor position. + */ + start_path = _pu_start_of_path(gl->line, + gl->buff_curpos > 0 ? gl->buff_curpos : 0); + if(!start_path) + return 1; +/* + * Get the length of the pathname string. + */ + pathlen = gl->buff_curpos - (start_path - gl->line); +/* + * Attempt to expand the pathname. + */ + result = ef_expand_file(gl->ef, start_path, pathlen); +/* + * If there was an error, report the error on a new line, then redraw + * the original line. + */ + if(!result) { + if(gl->echo && + fprintf(gl->output_fp, "\r\n%s\n", ef_last_error(gl->ef)) < 0) + return 1; + error_reported = 1; +/* + * If no files matched, report this as well. + */ + } else if(result->nfile == 0 || !result->exists) { + if(gl->echo && fprintf(gl->output_fp, "\r\nNo files match.\n") < 0) + return 1; + error_reported = 1; +/* + * Complain if more than one file matches. + */ + } else if(result->nfile > 1) { + if(gl->echo && + fprintf(gl->output_fp, "\r\nMore than one file matches.\n") < 0) + return 1; + error_reported = 1; +/* + * Disallow input from anything but normal files. In principle we could + * also support input from named pipes. Terminal files would be a problem + * since we wouldn't know the terminal type, and other types of files + * might cause the library to lock up. + */ + } else if(!_pu_path_is_file(result->files[0])) { + if(gl->echo && fprintf(gl->output_fp, "\r\nNot a normal file.\n") < 0) + return 1; + error_reported = 1; + } else { +/* + * Attempt to open and install the specified file for reading. + */ + gl->file_fp = fopen(result->files[0], "r"); + if(!gl->file_fp) { + if(gl->echo && fprintf(gl->output_fp, "\r\nUnable to open: %s\n", + result->files[0]) < 0) + return 1; + error_reported = 1; + }; +/* + * Inform the user what is happening. + */ + if(gl->echo && fprintf(gl->output_fp, "\r\n\n", + result->files[0]) < 0) + return 1; + }; +/* + * If an error was reported, redisplay the current line. + */ + if(error_reported) { + gl->term_curpos = 0; + return gl_redisplay(gl,1); + }; + return 0; +} + +/*....................................................................... + * Close any temporary file that is being used for input. + * + * Input: + * gl GetLine * The getline resource object. + */ +static void gl_revert_input(GetLine *gl) +{ + if(gl->file_fp) + fclose(gl->file_fp); + gl->file_fp = NULL; +} + +/*....................................................................... + * This is the action function that recalls the oldest line in the + * history buffer. + */ +static KT_KEY_FN(gl_beginning_of_history) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * Forget any previous recall session. + */ + gl->preload_id = 0; +/* + * Recall the next oldest line in the history list. + */ + if(_glh_oldest_line(gl->glh, gl->line, gl->linelen) == NULL) + return 0; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange to have the cursor placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * If a history session is currently in progress, this action function + * recalls the line that was being edited when the session started. If + * no history session is in progress, it does nothing. + */ +static KT_KEY_FN(gl_end_of_history) +{ +/* + * In vi mode, switch to command mode, since the user is very + * likely to want to move around newly recalled lines. + */ + gl_vi_command_mode(gl); +/* + * Forget any previous recall session. + */ + gl->preload_id = 0; +/* + * Recall the next oldest line in the history list. + */ + if(_glh_current_line(gl->glh, gl->line, gl->linelen) == NULL) + return 0; +/* + * Record the number of characters in the new string. + */ + gl->ntotal = strlen(gl->line); +/* + * Arrange to have the cursor placed at the end of the new line. + */ + gl->buff_curpos = strlen(gl->line); +/* + * Erase and display the new line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * This action function is treated specially, in that its count argument + * is set to the end keystroke of the keysequence that activated it. + * It accumulates a numeric argument, adding one digit on each call in + * which the last keystroke was a numeric digit. + */ +static KT_KEY_FN(gl_digit_argument) +{ +/* + * Was the last keystroke a digit? + */ + int is_digit = isdigit((int)(unsigned char) count); +/* + * In vi command mode, a lone '0' means goto-start-of-line. + */ + if(gl->vi.command && gl->number < 0 && count == '0') + return gl_beginning_of_line(gl, count); +/* + * Are we starting to accumulate a new number? + */ + if(gl->number < 0 || !is_digit) + gl->number = 0; +/* + * Was the last keystroke a digit? + */ + if(is_digit) { +/* + * Read the numeric value of the digit, without assuming ASCII. + */ + int n; + char s[2]; s[0] = count; s[1] = '\0'; + n = atoi(s); +/* + * Append the new digit. + */ + gl->number = gl->number * 10 + n; + }; + return 0; +} + +/*....................................................................... + * The newline action function sets gl->endline to tell + * gl_get_input_line() that the line is now complete. + */ +static KT_KEY_FN(gl_newline) +{ + GlhLineID id; /* The last history line recalled while entering this line */ +/* + * Flag the line as ended. + */ + gl->endline = 1; +/* + * Record the next position in the history buffer, for potential + * recall by an action function on the next call to gl_get_line(). + */ + id = _glh_line_id(gl->glh, 1); + if(id) + gl->preload_id = id; + return 0; +} + +/*....................................................................... + * The 'repeat' action function sets gl->endline to tell + * gl_get_input_line() that the line is now complete, and records the + * ID of the next history line in gl->preload_id so that the next call + * to gl_get_input_line() will preload the line with that history line. + */ +static KT_KEY_FN(gl_repeat_history) +{ + gl->endline = 1; + gl->preload_id = _glh_line_id(gl->glh, 1); + gl->preload_history = 1; + return 0; +} + +/*....................................................................... + * Flush unwritten characters to the terminal. + * + * Input: + * gl GetLine * The getline resource object. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_flush_output(GetLine *gl) +{ +/* + * Attempt to flush output to the terminal, restarting the output + * if a signal is caught. + */ + while(fflush(gl->output_fp) != 0) { + if(errno!=EINTR) + return 1; + }; + return 0; +} + +/*....................................................................... + * Change the style of editing to emulate a given editor. + * + * Input: + * gl GetLine * The getline resource object. + * editor GlEditor The type of editor to emulate. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_change_editor(GetLine *gl, GlEditor editor) +{ +/* + * Install the default key-bindings of the requested editor. + */ + switch(editor) { + case GL_EMACS_MODE: + _kt_clear_bindings(gl->bindings, KTB_NORM); + _kt_clear_bindings(gl->bindings, KTB_TERM); + (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_emacs_bindings, + sizeof(gl_emacs_bindings)/sizeof(gl_emacs_bindings[0])); + break; + case GL_VI_MODE: + _kt_clear_bindings(gl->bindings, KTB_NORM); + _kt_clear_bindings(gl->bindings, KTB_TERM); + (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_vi_bindings, + sizeof(gl_vi_bindings)/sizeof(gl_vi_bindings[0])); + break; + case GL_NO_EDITOR: + break; + default: + fprintf(stderr, "gl_change_editor: Unknown editor.\n"); + return 1; + }; +/* + * Record the new editing mode. + */ + gl->editor = editor; + gl->vi.command = 0; /* Start in input mode */ + gl->insert_curpos = 0; +/* + * Reinstate terminal-specific bindings. + */ + if(gl->editor != GL_NO_EDITOR && gl->input_fp) + (void) gl_bind_terminal_keys(gl); + return 0; +} + +/*....................................................................... + * This is an action function that switches to editing using emacs bindings + */ +static KT_KEY_FN(gl_emacs_editing_mode) +{ + return gl_change_editor(gl, GL_EMACS_MODE); +} + +/*....................................................................... + * This is an action function that switches to editing using vi bindings + */ +static KT_KEY_FN(gl_vi_editing_mode) +{ + return gl_change_editor(gl, GL_VI_MODE); +} + +/*....................................................................... + * This is the action function that switches to insert mode. + */ +static KT_KEY_FN(gl_vi_insert) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Switch to vi insert mode. + */ + gl->insert = 1; + gl->vi.command = 0; + gl->insert_curpos = gl->buff_curpos; + return 0; +} + +/*....................................................................... + * This is an action function that switches to overwrite mode. + */ +static KT_KEY_FN(gl_vi_overwrite) +{ +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Switch to vi overwrite mode. + */ + gl->insert = 0; + gl->vi.command = 0; + gl->insert_curpos = gl->buff_curpos; + return 0; +} + +/*....................................................................... + * This action function toggles the case of the character under the + * cursor. + */ +static KT_KEY_FN(gl_change_case) +{ + int i; +/* + * Keep a record of the current insert mode and the cursor position. + */ + int insert = gl->insert; +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * We want to overwrite the modified word. + */ + gl->insert = 0; +/* + * Toggle the case of 'count' characters. + */ + for(i=0; ibuff_curpos < gl->ntotal; i++) { + char *cptr = gl->line + gl->buff_curpos++; +/* + * Convert the character to upper case? + */ + if(islower((int)(unsigned char) *cptr)) + *cptr = toupper((int) *cptr); + else if(isupper((int)(unsigned char) *cptr)) + *cptr = tolower((int) *cptr); +/* + * Write the possibly modified character back. Note that for non-modified + * characters we want to do this as well, so as to advance the cursor. + */ + if(gl_output_char(gl, *cptr, cptr[1])) + return 1; + }; +/* + * Restore the insertion mode. + */ + gl->insert = insert; + return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ +} + +/*....................................................................... + * This is the action function which implements the vi-style action which + * moves the cursor to the start of the line, then switches to insert mode. + */ +static KT_KEY_FN(gl_vi_insert_at_bol) +{ + gl_save_for_undo(gl); + return gl_beginning_of_line(gl, 0) || + gl_vi_insert(gl, 0); + +} + +/*....................................................................... + * This is the action function which implements the vi-style action which + * moves the cursor to the end of the line, then switches to insert mode + * to allow text to be appended to the line. + */ +static KT_KEY_FN(gl_vi_append_at_eol) +{ + gl_save_for_undo(gl); + gl->vi.command = 0; /* Allow cursor at EOL */ + return gl_end_of_line(gl, 0) || + gl_vi_insert(gl, 0); +} + +/*....................................................................... + * This is the action function which implements the vi-style action which + * moves the cursor to right one then switches to insert mode, thus + * allowing text to be appended after the next character. + */ +static KT_KEY_FN(gl_vi_append) +{ + gl_save_for_undo(gl); + gl->vi.command = 0; /* Allow cursor at EOL */ + return gl_cursor_right(gl, 1) || + gl_vi_insert(gl, 0); +} + +/*....................................................................... + * This action function moves the cursor to the column specified by the + * numeric argument. Column indexes start at 1. + */ +static KT_KEY_FN(gl_goto_column) +{ + return gl_place_cursor(gl, count - 1); +} + +/*....................................................................... + * Starting with the character under the cursor, replace 'count' + * characters with the next character that the user types. + */ +static KT_KEY_FN(gl_vi_replace_char) +{ + char c; /* The replacement character */ + int i; +/* + * Keep a record of the current insert mode. + */ + int insert = gl->insert; +/* + * Get the replacement character. + */ + if(gl->vi.repeat.active) { + c = gl->vi.repeat.input_char; + } else { + if(gl_read_character(gl, &c)) + return 1; + gl->vi.repeat.input_char = c; + }; +/* + * Are there 'count' characters to be replaced? + */ + if(gl->ntotal - gl->buff_curpos >= count) { +/* + * If in vi command mode, preserve the current line for potential + * use by vi-undo. + */ + gl_save_for_undo(gl); +/* + * Temporarily switch to overwrite mode. + */ + gl->insert = 0; +/* + * Overwrite the current character plus count-1 subsequent characters + * with the replacement character. + */ + for(i=0; iinsert = insert; + }; + return gl_place_cursor(gl, gl->buff_curpos); /* bounds check */ +} + +/*....................................................................... + * This is an action function which changes all characters between the + * current cursor position and the end of the line. + */ +static KT_KEY_FN(gl_vi_change_rest_of_line) +{ + gl_save_for_undo(gl); + gl->vi.command = 0; /* Allow cursor at EOL */ + return gl_kill_line(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * This is an action function which changes all characters between the + * start of the line and the current cursor position. + */ +static KT_KEY_FN(gl_vi_change_to_bol) +{ + return gl_backward_kill_line(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * This is an action function which deletes the entire contents of the + * current line and switches to insert mode. + */ +static KT_KEY_FN(gl_vi_change_line) +{ + return gl_delete_line(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * Starting from the cursor position and looking towards the end of the + * line, copy 'count' characters to the cut buffer. + */ +static KT_KEY_FN(gl_forward_copy_char) +{ +/* + * Limit the count to the number of characters available. + */ + if(gl->buff_curpos + count >= gl->ntotal) + count = gl->ntotal - gl->buff_curpos; + if(count < 0) + count = 0; +/* + * Copy the characters to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count); + gl->cutbuf[count] = '\0'; + return 0; +} + +/*....................................................................... + * Starting from the character before the cursor position and looking + * backwards towards the start of the line, copy 'count' characters to + * the cut buffer. + */ +static KT_KEY_FN(gl_backward_copy_char) +{ +/* + * Limit the count to the number of characters available. + */ + if(count > gl->buff_curpos) + count = gl->buff_curpos; + if(count < 0) + count = 0; + gl_place_cursor(gl, gl->buff_curpos - count); +/* + * Copy the characters to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count); + gl->cutbuf[count] = '\0'; + return 0; +} + +/*....................................................................... + * Starting from the cursor position copy to the specified column into the + * cut buffer. + */ +static KT_KEY_FN(gl_copy_to_column) +{ + if (--count >= gl->buff_curpos) + return gl_forward_copy_char(gl, count - gl->buff_curpos); + else + return gl_backward_copy_char(gl, gl->buff_curpos - count); +} + +/*....................................................................... + * Starting from the cursor position copy characters up to a matching + * parenthesis into the cut buffer. + */ +static KT_KEY_FN(gl_copy_to_parenthesis) +{ + int curpos = gl_index_of_matching_paren(gl); + if(curpos >= 0) { + gl_save_for_undo(gl); + if(curpos >= gl->buff_curpos) + return gl_forward_copy_char(gl, curpos - gl->buff_curpos + 1); + else + return gl_backward_copy_char(gl, ++gl->buff_curpos - curpos + 1); + }; + return 0; +} + +/*....................................................................... + * Starting from the cursor position copy the rest of the line into the + * cut buffer. + */ +static KT_KEY_FN(gl_copy_rest_of_line) +{ +/* + * Copy the characters to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->ntotal - gl->buff_curpos); + gl->cutbuf[gl->ntotal - gl->buff_curpos] = '\0'; + return 0; +} + +/*....................................................................... + * Copy from the beginning of the line to the cursor position into the + * cut buffer. + */ +static KT_KEY_FN(gl_copy_to_bol) +{ +/* + * Copy the characters to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line, gl->buff_curpos); + gl->cutbuf[gl->buff_curpos] = '\0'; + gl_place_cursor(gl, 0); + return 0; +} + +/*....................................................................... + * Copy the entire line into the cut buffer. + */ +static KT_KEY_FN(gl_copy_line) +{ +/* + * Copy the characters to the cut buffer. + */ + memcpy(gl->cutbuf, gl->line, gl->ntotal); + gl->cutbuf[gl->ntotal] = '\0'; + return 0; +} + +/*....................................................................... + * Search forwards for the next character that the user enters. + */ +static KT_KEY_FN(gl_forward_find_char) +{ + int pos = gl_find_char(gl, count, 1, 1, '\0'); + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Search backwards for the next character that the user enters. + */ +static KT_KEY_FN(gl_backward_find_char) +{ + int pos = gl_find_char(gl, count, 0, 1, '\0'); + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Search forwards for the next character that the user enters. Move up to, + * but not onto, the found character. + */ +static KT_KEY_FN(gl_forward_to_char) +{ + int pos = gl_find_char(gl, count, 1, 0, '\0'); + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Search backwards for the next character that the user enters. Move back to, + * but not onto, the found character. + */ +static KT_KEY_FN(gl_backward_to_char) +{ + int pos = gl_find_char(gl, count, 0, 0, '\0'); + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Searching in a given direction, return the index of a given (or + * read) character in the input line, or the character that precedes + * it in the specified search direction. Return -1 if not found. + * + * Input: + * gl GetLine * The getline resource object. + * count int The number of times to search. + * forward int True if searching forward. + * onto int True if the search should end on top of the + * character, false if the search should stop + * one character before the character in the + * specified search direction. + * c char The character to be sought, or '\0' if the + * character should be read from the user. + * Output: + * return int The index of the character in gl->line[], or + * -1 if not found. + */ +static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c) +{ + int pos; /* The index reached in searching the input line */ + int i; +/* + * Get a character from the user? + */ + if(!c) { +/* + * If we are in the process of repeating a previous change command, substitute + * the last find character. + */ + if(gl->vi.repeat.active) { + c = gl->vi.find_char; + } else { + if(gl_read_character(gl, &c)) + return -1; +/* + * Record the details of the new search, for use by repeat finds. + */ + gl->vi.find_forward = forward; + gl->vi.find_onto = onto; + gl->vi.find_char = c; + }; + }; +/* + * Which direction should we search? + */ + if(forward) { +/* + * Search forwards 'count' times for the character, starting with the + * character that follows the cursor. + */ + for(i=0, pos=gl->buff_curpos; intotal; i++) { +/* + * Advance past the last match (or past the current cursor position + * on the first search). + */ + pos++; +/* + * Search for the next instance of c. + */ + for( ; posntotal && c!=gl->line[pos]; pos++) + ; + }; +/* + * If the character was found and we have been requested to return the + * position of the character that precedes the desired character, then + * we have gone one character too far. + */ + if(!onto && posntotal) + pos--; + } else { +/* + * Search backwards 'count' times for the character, starting with the + * character that precedes the cursor. + */ + for(i=0, pos=gl->buff_curpos; i= gl->insert_curpos; i++) { +/* + * Step back one from the last match (or from the current cursor + * position on the first search). + */ + pos--; +/* + * Search for the next instance of c. + */ + for( ; pos>=gl->insert_curpos && c!=gl->line[pos]; pos--) + ; + }; +/* + * If the character was found and we have been requested to return the + * position of the character that precedes the desired character, then + * we have gone one character too far. + */ + if(!onto && pos>=gl->insert_curpos) + pos++; + }; +/* + * If found, return the cursor position of the count'th match. + * Otherwise ring the terminal bell. + */ + if(pos >= gl->insert_curpos && pos < gl->ntotal) { + return pos; + } else { + (void) gl_ring_bell(gl, 1); + return -1; + } +} + +/*....................................................................... + * Repeat the last character search in the same direction as the last + * search. + */ +static KT_KEY_FN(gl_repeat_find_char) +{ + int pos = gl->vi.find_char ? + gl_find_char(gl, count, gl->vi.find_forward, gl->vi.find_onto, + gl->vi.find_char) : -1; + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Repeat the last character search in the opposite direction as the last + * search. + */ +static KT_KEY_FN(gl_invert_refind_char) +{ + int pos = gl->vi.find_char ? + gl_find_char(gl, count, !gl->vi.find_forward, gl->vi.find_onto, + gl->vi.find_char) : -1; + return pos >= 0 && gl_place_cursor(gl, pos); +} + +/*....................................................................... + * Search forward from the current position of the cursor for 'count' + * word endings, returning the index of the last one found, or the end of + * the line if there were less than 'count' words. + * + * Input: + * gl GetLine * The getline resource object. + * n int The number of word boundaries to search for. + * Output: + * return int The buffer index of the located position. + */ +static int gl_nth_word_end_forward(GetLine *gl, int n) +{ + int bufpos; /* The buffer index being checked. */ + int i; +/* + * In order to guarantee forward motion to the next word ending, + * we need to start from one position to the right of the cursor + * position, since this may already be at the end of a word. + */ + bufpos = gl->buff_curpos + 1; +/* + * If we are at the end of the line, return the index of the last + * real character on the line. Note that this will be -1 if the line + * is empty. + */ + if(bufpos >= gl->ntotal) + return gl->ntotal - 1; +/* + * Search 'n' times, unless the end of the input line is reached first. + */ + for(i=0; intotal; i++) { +/* + * If we are not already within a word, skip to the start of the next word. + */ + for( ; bufposntotal && !gl_is_word_char((int)gl->line[bufpos]); + bufpos++) + ; +/* + * Find the end of the next word. + */ + for( ; bufposntotal && gl_is_word_char((int)gl->line[bufpos]); + bufpos++) + ; + }; +/* + * We will have overshot. + */ + return bufpos > 0 ? bufpos-1 : bufpos; +} + +/*....................................................................... + * Search forward from the current position of the cursor for 'count' + * word starts, returning the index of the last one found, or the end of + * the line if there were less than 'count' words. + * + * Input: + * gl GetLine * The getline resource object. + * n int The number of word boundaries to search for. + * Output: + * return int The buffer index of the located position. + */ +static int gl_nth_word_start_forward(GetLine *gl, int n) +{ + int bufpos; /* The buffer index being checked. */ + int i; +/* + * Get the current cursor position. + */ + bufpos = gl->buff_curpos; +/* + * Search 'n' times, unless the end of the input line is reached first. + */ + for(i=0; intotal; i++) { +/* + * Find the end of the current word. + */ + for( ; bufposntotal && gl_is_word_char((int)gl->line[bufpos]); + bufpos++) + ; +/* + * Skip to the start of the next word. + */ + for( ; bufposntotal && !gl_is_word_char((int)gl->line[bufpos]); + bufpos++) + ; + }; + return bufpos; +} + +/*....................................................................... + * Search backward from the current position of the cursor for 'count' + * word starts, returning the index of the last one found, or the start + * of the line if there were less than 'count' words. + * + * Input: + * gl GetLine * The getline resource object. + * n int The number of word boundaries to search for. + * Output: + * return int The buffer index of the located position. + */ +static int gl_nth_word_start_backward(GetLine *gl, int n) +{ + int bufpos; /* The buffer index being checked. */ + int i; +/* + * Get the current cursor position. + */ + bufpos = gl->buff_curpos; +/* + * Search 'n' times, unless the beginning of the input line (or vi insertion + * point) is reached first. + */ + for(i=0; i gl->insert_curpos; i++) { +/* + * Starting one character back from the last search, so as not to keep + * settling on the same word-start, search backwards until finding a + * word character. + */ + while(--bufpos >= gl->insert_curpos && + !gl_is_word_char((int)gl->line[bufpos])) + ; +/* + * Find the start of the word. + */ + while(--bufpos >= gl->insert_curpos && + gl_is_word_char((int)gl->line[bufpos])) + ; +/* + * We will have gone one character too far. + */ + bufpos++; + }; + return bufpos >= gl->insert_curpos ? bufpos : gl->insert_curpos; +} + +/*....................................................................... + * Copy one or more words into the cut buffer without moving the cursor + * or deleting text. + */ +static KT_KEY_FN(gl_forward_copy_word) +{ +/* + * Find the location of the count'th start or end of a word + * after the cursor, depending on whether in emacs or vi mode. + */ + int next = gl->editor == GL_EMACS_MODE ? + gl_nth_word_end_forward(gl, count) : + gl_nth_word_start_forward(gl, count); +/* + * How many characters are to be copied into the cut buffer? + */ + int n = next - gl->buff_curpos; +/* + * Copy the specified segment and terminate the string. + */ + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n); + gl->cutbuf[n] = '\0'; + return 0; +} + +/*....................................................................... + * Copy one or more words preceding the cursor into the cut buffer, + * without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_backward_copy_word) +{ +/* + * Find the location of the count'th start of word before the cursor. + */ + int next = gl_nth_word_start_backward(gl, count); +/* + * How many characters are to be copied into the cut buffer? + */ + int n = gl->buff_curpos - next; + gl_place_cursor(gl, next); +/* + * Copy the specified segment and terminate the string. + */ + memcpy(gl->cutbuf, gl->line + next, n); + gl->cutbuf[n] = '\0'; + return 0; +} + +/*....................................................................... + * Copy the characters between the cursor and the count'th instance of + * a specified character in the input line, into the cut buffer. + * + * Input: + * gl GetLine * The getline resource object. + * count int The number of times to search. + * c char The character to be searched for, or '\0' if + * the character should be read from the user. + * forward int True if searching forward. + * onto int True if the search should end on top of the + * character, false if the search should stop + * one character before the character in the + * specified search direction. + * Output: + * return int 0 - OK. + * 1 - Error. + * + */ +static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto) +{ + int n; /* The number of characters in the cut buffer */ +/* + * Search for the character, and abort the operation if not found. + */ + int pos = gl_find_char(gl, count, forward, onto, c); + if(pos < 0) + return 0; +/* + * Copy the specified segment. + */ + if(forward) { + n = pos + 1 - gl->buff_curpos; + memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n); + } else { + n = gl->buff_curpos - pos; + memcpy(gl->cutbuf, gl->line + pos, n); + if(gl->editor == GL_VI_MODE) + gl_place_cursor(gl, pos); + } +/* + * Terminate the copy. + */ + gl->cutbuf[n] = '\0'; + return 0; +} + +/*....................................................................... + * Copy a section up to and including a specified character into the cut + * buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_forward_copy_find) +{ + return gl_copy_find(gl, count, '\0', 1, 1); +} + +/*....................................................................... + * Copy a section back to and including a specified character into the cut + * buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_backward_copy_find) +{ + return gl_copy_find(gl, count, '\0', 0, 1); +} + +/*....................................................................... + * Copy a section up to and not including a specified character into the cut + * buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_forward_copy_to) +{ + return gl_copy_find(gl, count, '\0', 1, 0); +} + +/*....................................................................... + * Copy a section back to and not including a specified character into the cut + * buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_backward_copy_to) +{ + return gl_copy_find(gl, count, '\0', 0, 0); +} + +/*....................................................................... + * Copy to a character specified in a previous search into the cut + * buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_copy_refind) +{ + return gl_copy_find(gl, count, gl->vi.find_char, gl->vi.find_forward, + gl->vi.find_onto); +} + +/*....................................................................... + * Copy to a character specified in a previous search, but in the opposite + * direction, into the cut buffer without moving the cursor or deleting text. + */ +static KT_KEY_FN(gl_copy_invert_refind) +{ + return gl_copy_find(gl, count, gl->vi.find_char, !gl->vi.find_forward, + gl->vi.find_onto); +} + +/*....................................................................... + * Set the position of the cursor in the line input buffer and the + * terminal. + * + * Input: + * gl GetLine * The getline resource object. + * buff_curpos int The new buffer cursor position. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_place_cursor(GetLine *gl, int buff_curpos) +{ +/* + * Don't allow the cursor position to go out of the bounds of the input + * line. + */ + if(buff_curpos >= gl->ntotal) + buff_curpos = gl->vi.command ? gl->ntotal-1 : gl->ntotal; + if(buff_curpos < 0) + buff_curpos = 0; +/* + * Record the new buffer position. + */ + gl->buff_curpos = buff_curpos; +/* + * Move the terminal cursor to the corresponding character. + */ + return gl_set_term_curpos(gl, gl_buff_curpos_to_term_curpos(gl, buff_curpos)); +} + +/*....................................................................... + * In vi command mode, this function saves the current line to the + * historical buffer needed by the undo command. In emacs mode it does + * nothing. In order to allow action functions to call other action + * functions, gl_interpret_char() sets gl->vi.undo.saved to 0 before + * invoking an action, and thereafter once any call to this function + * has set it to 1, further calls are ignored. + * + * Input: + * gl GetLine * The getline resource object. + */ +static void gl_save_for_undo(GetLine *gl) +{ + if(gl->vi.command && !gl->vi.undo.saved) { + strcpy(gl->vi.undo.line, gl->line); + gl->vi.undo.buff_curpos = gl->buff_curpos; + gl->vi.undo.ntotal = gl->ntotal; + gl->vi.undo.saved = 1; + }; + if(gl->vi.command && !gl->vi.repeat.saved && + gl->current_fn != gl_vi_repeat_change) { + gl->vi.repeat.fn = gl->current_fn; + gl->vi.repeat.count = gl->current_count; + gl->vi.repeat.saved = 1; + }; + return; +} + +/*....................................................................... + * In vi mode, restore the line to the way it was before the last command + * mode operation, storing the current line in the buffer so that the + * undo operation itself can subsequently be undone. + */ +static KT_KEY_FN(gl_vi_undo) +{ +/* + * Get pointers into the two lines. + */ + char *undo_ptr = gl->vi.undo.line; + char *line_ptr = gl->line; +/* + * Swap the characters of the two buffers up to the length of the shortest + * line. + */ + while(*undo_ptr && *line_ptr) { + char c = *undo_ptr; + *undo_ptr++ = *line_ptr; + *line_ptr++ = c; + }; +/* + * Copy the rest directly. + */ + if(gl->ntotal > gl->vi.undo.ntotal) { + strcpy(undo_ptr, line_ptr); + *line_ptr = '\0'; + } else { + strcpy(line_ptr, undo_ptr); + *undo_ptr = '\0'; + }; +/* + * Swap the length information. + */ + { + int ntotal = gl->ntotal; + gl->ntotal = gl->vi.undo.ntotal; + gl->vi.undo.ntotal = ntotal; + }; +/* + * Set both cursor positions to the leftmost of the saved and current + * cursor positions to emulate what vi does. + */ + if(gl->buff_curpos < gl->vi.undo.buff_curpos) + gl->vi.undo.buff_curpos = gl->buff_curpos; + else + gl->buff_curpos = gl->vi.undo.buff_curpos; +/* + * Since we have bipassed calling gl_save_for_undo(), record repeat + * information inline. + */ + gl->vi.repeat.fn = gl_vi_undo; + gl->vi.repeat.count = 1; +/* + * Display the restored line. + */ + return gl_redisplay(gl,1); +} + +/*....................................................................... + * Delete the following word and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_forward_change_word) +{ + gl_save_for_undo(gl); + gl->vi.command = 0; /* Allow cursor at EOL */ + return gl_forward_delete_word(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * Delete the preceding word and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_backward_change_word) +{ + return gl_backward_delete_word(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * Delete the following section and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_forward_change_find) +{ + return gl_delete_find(gl, count, '\0', 1, 1, 1); +} + +/*....................................................................... + * Delete the preceding section and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_backward_change_find) +{ + return gl_delete_find(gl, count, '\0', 0, 1, 1); +} + +/*....................................................................... + * Delete the following section and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_forward_change_to) +{ + return gl_delete_find(gl, count, '\0', 1, 0, 1); +} + +/*....................................................................... + * Delete the preceding section and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_backward_change_to) +{ + return gl_delete_find(gl, count, '\0', 0, 0, 1); +} + +/*....................................................................... + * Delete to a character specified by a previous search and leave the user + * in vi insert mode. + */ +static KT_KEY_FN(gl_vi_change_refind) +{ + return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward, + gl->vi.find_onto, 1); +} + +/*....................................................................... + * Delete to a character specified by a previous search, but in the opposite + * direction, and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_change_invert_refind) +{ + return gl_delete_find(gl, count, gl->vi.find_char, !gl->vi.find_forward, + gl->vi.find_onto, 1); +} + +/*....................................................................... + * Delete the following character and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_forward_change_char) +{ + gl_save_for_undo(gl); + gl->vi.command = 0; /* Allow cursor at EOL */ + return gl_delete_chars(gl, count, 1) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * Delete the preceding character and leave the user in vi insert mode. + */ +static KT_KEY_FN(gl_vi_backward_change_char) +{ + return gl_backward_delete_char(gl, count) || gl_vi_insert(gl, 0); +} + +/*....................................................................... + * Starting from the cursor position change characters to the specified column. + */ +static KT_KEY_FN(gl_vi_change_to_column) +{ + if (--count >= gl->buff_curpos) + return gl_vi_forward_change_char(gl, count - gl->buff_curpos); + else + return gl_vi_backward_change_char(gl, gl->buff_curpos - count); +} + +/*....................................................................... + * Starting from the cursor position change characters to a matching + * parenthesis. + */ +static KT_KEY_FN(gl_vi_change_to_parenthesis) +{ + int curpos = gl_index_of_matching_paren(gl); + if(curpos >= 0) { + gl_save_for_undo(gl); + if(curpos >= gl->buff_curpos) + return gl_vi_forward_change_char(gl, curpos - gl->buff_curpos + 1); + else + return gl_vi_backward_change_char(gl, ++gl->buff_curpos - curpos + 1); + }; + return 0; +} + +/*....................................................................... + * If in vi mode, switch to vi command mode. + * + * Input: + * gl GetLine * The getline resource object. + */ +static void gl_vi_command_mode(GetLine *gl) +{ + if(gl->editor == GL_VI_MODE && !gl->vi.command) { + gl->insert = 1; + gl->vi.command = 1; + gl->vi.repeat.input_curpos = gl->insert_curpos; + gl->vi.repeat.command_curpos = gl->buff_curpos; + gl->insert_curpos = 0; /* unrestrict left motion boundary */ + gl_cursor_left(gl, 1); /* Vi moves left one on entering command mode */ + }; +} + +/*....................................................................... + * This is an action function which rings the terminal bell. + */ +static KT_KEY_FN(gl_ring_bell) +{ + return gl->silence_bell ? 0 : + gl_output_control_sequence(gl, 1, gl->sound_bell); +} + +/*....................................................................... + * This is the action function which implements the vi-repeat-change + * action. + */ +static KT_KEY_FN(gl_vi_repeat_change) +{ + int status; /* The return status of the repeated action function */ + int i; +/* + * Nothing to repeat? + */ + if(!gl->vi.repeat.fn) + return gl_ring_bell(gl, 1); +/* + * Provide a way for action functions to know whether they are being + * called by us. + */ + gl->vi.repeat.active = 1; +/* + * Re-run the recorded function. + */ + status = gl->vi.repeat.fn(gl, gl->vi.repeat.count); +/* + * Mark the repeat as completed. + */ + gl->vi.repeat.active = 0; +/* + * Is we are repeating a function that has just switched to input + * mode to allow the user to type, re-enter the text that the user + * previously entered. + */ + if(status==0 && !gl->vi.command) { +/* + * Make sure that the current line has been saved. + */ + gl_save_for_undo(gl); +/* + * Repeat a previous insertion or overwrite? + */ + if(gl->vi.repeat.input_curpos >= 0 && + gl->vi.repeat.input_curpos <= gl->vi.repeat.command_curpos && + gl->vi.repeat.command_curpos <= gl->vi.undo.ntotal) { +/* + * Using the current line which is saved in the undo buffer, plus + * the range of characters therein, as recorded by gl_vi_command_mode(), + * add the characters that the user previously entered, to the input + * line. + */ + for(i=gl->vi.repeat.input_curpos; ivi.repeat.command_curpos; i++) { + if(gl_add_char_to_line(gl, gl->vi.undo.line[i])) + return 1; + }; + }; +/* + * Switch back to command mode, now that the insertion has been repeated. + */ + gl_vi_command_mode(gl); + }; + return status; +} + +/*....................................................................... + * If the cursor is currently over a parenthesis character, return the + * index of its matching parenthesis. If not currently over a parenthesis + * character, return the next close parenthesis character to the right of + * the cursor. If the respective parenthesis character isn't found, + * ring the terminal bell and return -1. + * + * Input: + * gl GetLine * The getline resource object. + * Output: + * return int Either the index of the matching parenthesis, + * or -1 if not found. + */ +static int gl_index_of_matching_paren(GetLine *gl) +{ + int i; +/* + * List the recognized parentheses, and their matches. + */ + const char *o_paren = "([{"; + const char *c_paren = ")]}"; + const char *cptr; +/* + * Get the character that is currently under the cursor. + */ + char c = gl->line[gl->buff_curpos]; +/* + * If the character under the cursor is an open parenthesis, look forward + * for the matching close parenthesis. + */ + if((cptr=strchr(o_paren, c))) { + char match = c_paren[cptr - o_paren]; + int matches_needed = 1; + for(i=gl->buff_curpos+1; intotal; i++) { + if(gl->line[i] == c) + matches_needed++; + else if(gl->line[i] == match && --matches_needed==0) + return i; + }; +/* + * If the character under the cursor is an close parenthesis, look forward + * for the matching open parenthesis. + */ + } else if((cptr=strchr(c_paren, c))) { + char match = o_paren[cptr - c_paren]; + int matches_needed = 1; + for(i=gl->buff_curpos-1; i>=0; i--) { + if(gl->line[i] == c) + matches_needed++; + else if(gl->line[i] == match && --matches_needed==0) + return i; + }; +/* + * If not currently over a parenthesis character, search forwards for + * the first close parenthesis (this is what the vi % binding does). + */ + } else { + for(i=gl->buff_curpos+1; intotal; i++) + if(strchr(c_paren, gl->line[i]) != NULL) + return i; + }; +/* + * Not found. + */ + (void) gl_ring_bell(gl, 1); + return -1; +} + +/*....................................................................... + * If the cursor is currently over a parenthesis character, this action + * function moves the cursor to its matching parenthesis. + */ +static KT_KEY_FN(gl_find_parenthesis) +{ + int curpos = gl_index_of_matching_paren(gl); + if(curpos >= 0) + return gl_place_cursor(gl, curpos); + return 0; +} + +/*....................................................................... + * Handle the receipt of the potential start of a new key-sequence from + * the user. + * + * Input: + * gl GetLine * The resource object of this library. + * first_char char The first character of the sequence. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_interpret_char(GetLine *gl, char first_char) +{ + KtKeyFn *keyfn; /* An action function */ + char keyseq[GL_KEY_MAX+1]; /* A special key sequence being read */ + int nkey=0; /* The number of characters in the key sequence */ + int count; /* The repeat count of an action function */ + int ret; /* The return value of an action function */ + int i; +/* + * Get the first character. + */ + char c = first_char; +/* + * If editting is disabled, just add newly entered characters to the + * input line buffer, and watch for the end of the line. + */ + if(gl->editor == GL_NO_EDITOR) { + if(gl->ntotal >= gl->linelen) + return 0; + if(c == '\n' || c == '\r') + return gl_newline(gl, 1); + gl->line[gl->ntotal++] = c; + return 0; + }; +/* + * If the user is in the process of specifying a repeat count and the + * new character is a digit, increment the repeat count accordingly. + */ + if(gl->number >= 0 && isdigit((int)(unsigned char) c)) + return gl_digit_argument(gl, c); +/* + * In vi command mode, all key-sequences entered need to be + * either implicitly or explicitly prefixed with an escape character. + */ + else if(gl->vi.command && c != GL_ESC_CHAR) + keyseq[nkey++] = GL_ESC_CHAR; +/* + * If the first character of the sequence is a printable character, + * then to avoid confusion with the special "up", "down", "left" + * or "right" cursor key bindings, we need to prefix the + * printable character with a backslash escape before looking it up. + */ + else if(!IS_META_CHAR(c) && !IS_CTRL_CHAR(c)) + keyseq[nkey++] = '\\'; +/* + * Compose a potentially multiple key-sequence in gl->keyseq. + */ + while(nkey < GL_KEY_MAX) { + int first, last; /* The matching entries in gl->keys */ +/* + * If the character is an unprintable meta character, split it + * into two characters, an escape character and the character + * that was modified by the meta key. + */ + if(IS_META_CHAR(c)) { + keyseq[nkey++] = GL_ESC_CHAR; + c = META_TO_CHAR(c); + continue; + }; +/* + * Append the latest character to the key sequence. + */ + keyseq[nkey++] = c; +/* + * When doing vi-style editing, an escape at the beginning of any binding + * switches to command mode. + */ + if(keyseq[0] == GL_ESC_CHAR && !gl->vi.command) + gl_vi_command_mode(gl); +/* + * Lookup the key sequence. + */ + switch(_kt_lookup_keybinding(gl->bindings, keyseq, nkey, &first, &last)) { + case KT_EXACT_MATCH: +/* + * Get the matching action function. + */ + keyfn = gl->bindings->table[first].keyfn; +/* + * Get the repeat count, passing the last keystroke if executing the + * digit-argument action. + */ + if(keyfn == gl_digit_argument) { + count = c; + } else { + count = gl->number >= 0 ? gl->number : 1; + }; +/* + * Record the function that is being invoked. + */ + gl->current_fn = keyfn; + gl->current_count = count; +/* + * Mark the current line as not yet preserved for use by the vi undo command. + */ + gl->vi.undo.saved = 0; + gl->vi.repeat.saved = 0; +/* + * Execute the action function. Note the action function can tell + * whether the provided repeat count was defaulted or specified + * explicitly by looking at whether gl->number is -1 or not. If + * it is negative, then no repeat count was specified by the user. + */ + ret = keyfn(gl, count); +/* + * Reset the repeat count after running action functions (other + * than digit-argument). + */ + if(keyfn != gl_digit_argument) + gl->number = -1; + if(ret) + return 1; + return 0; + break; + case KT_AMBIG_MATCH: /* Ambiguous match - so look ahead */ + if(gl_read_character(gl, &c)) /* Get the next character */ + return 1; + break; + case KT_NO_MATCH: +/* + * If the first character looked like it might be a prefix of a key-sequence + * but it turned out not to be, ring the bell to tell the user that it + * wasn't recognised. + */ + if(keyseq[0] != '\\' && keyseq[0] != '\t') { + gl_ring_bell(gl, 0); + } else { +/* + * The user typed a single printable character that doesn't match + * the start of any keysequence, so add it to the line in accordance + * with the current repeat count. + */ + count = gl->number >= 0 ? gl->number : 1; + for(i=0; inumber = -1; + }; + return 0; + break; + case KT_BAD_MATCH: + return 1; + break; + }; + }; +/* + * Key sequence too long to match. + */ + return 0; +} + +/*....................................................................... + * Configure the application and/or user-specific behavior of + * gl_get_line(). + * + * Note that calling this function between calling new_GetLine() and + * the first call to new_GetLine(), disables the otherwise automatic + * reading of ~/.teclarc on the first call to gl_get_line(). + * + * Input: + * gl GetLine * The resource object of this library. + * app_string const char * Either NULL, or a string containing one + * or more .teclarc command lines, separated + * by newline characters. This can be used to + * establish an application-specific + * configuration, without the need for an external + * file. This is particularly useful in embedded + * environments where there is no filesystem. + * app_file const char * Either NULL, or the pathname of an + * application-specific .teclarc file. The + * contents of this file, if provided, are + * read after the contents of app_string[]. + * user_file const char * Either NULL, or the pathname of a + * user-specific .teclarc file. Except in + * embedded applications, this should + * usually be "~/.teclarc". + * Output: + * return int 0 - OK. + * 1 - Bad argument(s). + */ +int gl_configure_getline(GetLine *gl, const char *app_string, + const char *app_file, const char *user_file) +{ +/* + * Check the arguments. + */ + if(!gl) { + fprintf(stderr, "gl_configure_getline: NULL gl argument.\n"); + return 1; + }; +/* + * Mark getline as having been explicitly configured. + */ + gl->configured = 1; +/* + * Start by parsing the configuration string, if provided. + */ + if(app_string) + (void) _gl_read_config_string(gl, app_string, KTB_NORM); +/* + * Now parse the application-specific configuration file, if provided. + */ + if(app_file) + (void) _gl_read_config_file(gl, app_file, KTB_NORM); +/* + * Finally, parse the user-specific configuration file, if provided. + */ + if(user_file) + (void) _gl_read_config_file(gl, user_file, KTB_USER); +/* + * Record the names of the configuration files to allow them to + * be re-read if requested at a later time. + */ + if(gl_record_string(&gl->app_file, app_file) || + gl_record_string(&gl->user_file, user_file)) { + fprintf(stderr, + "Insufficient memory to record tecla configuration file names.\n"); + return 1; + }; + return 0; +} + +/*....................................................................... + * Replace a malloc'd string (or NULL), with another malloc'd copy of + * a string (or NULL). + * + * Input: + * sptr char ** On input if *sptr!=NULL, *sptr will be + * free'd and *sptr will be set to NULL. Then, + * on output, if string!=NULL a malloc'd copy + * of this string will be assigned to *sptr. + * string const char * The string to be copied, or NULL to simply + * discard any existing string. + * Output: + * return int 0 - OK. + * 1 - Malloc failure (no error message is generated). + */ +static int gl_record_string(char **sptr, const char *string) +{ +/* + * If the original string is the same string, don't do anything. + */ + if(*sptr == string || (*sptr && string && strcmp(*sptr, string)==0)) + return 0; +/* + * Discard any existing cached string. + */ + if(*sptr) { + free(*sptr); + *sptr = NULL; + }; +/* + * Allocate memory for a copy of the specified string. + */ + if(string) { + *sptr = (char *) malloc(strlen(string) + 1); + if(!*sptr) + return 1; +/* + * Copy the string. + */ + strcpy(*sptr, string); + }; + return 0; +} + +/*....................................................................... + * Re-read any application-specific and user-specific files previously + * specified via the gl_configure_getline() function. + */ +static KT_KEY_FN(gl_read_init_files) +{ + return gl_configure_getline(gl, NULL, gl->app_file, gl->user_file); +} + +/*....................................................................... + * Save the contents of the history buffer to a given new file. + * + * Input: + * gl GetLine * The resource object of this library. + * filename const char * The name of the new file to write to. + * comment const char * Extra information such as timestamps will + * be recorded on a line started with this + * string, the idea being that the file can + * double as a command file. Specify "" if + * you don't care. + * max_lines int The maximum number of lines to save, or -1 + * to save all of the lines in the history + * list. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_save_history(GetLine *gl, const char *filename, const char *comment, + int max_lines) +{ + FileExpansion *expansion; /* The expansion of the filename */ +/* + * Check the arguments. + */ + if(!gl || !filename || !comment) { + fprintf(stderr, "gl_save_history: NULL argument(s).\n"); + return 1; + }; +/* + * Expand the filename. + */ + expansion = ef_expand_file(gl->ef, filename, -1); + if(!expansion) { + fprintf(stderr, "Unable to expand %s (%s).\n", filename, + ef_last_error(gl->ef)); + return 1; + }; +/* + * Attempt to save to the specified file. + */ + return _glh_save_history(gl->glh, expansion->files[0], comment, max_lines); +} + +/*....................................................................... + * Restore the contents of the history buffer from a given new file. + * + * Input: + * gl GetLine * The resource object of this library. + * filename const char * The name of the new file to write to. + * comment const char * This must be the same string that was + * passed to gl_save_history() when the file + * was written. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_load_history(GetLine *gl, const char *filename, const char *comment) +{ + FileExpansion *expansion; /* The expansion of the filename */ +/* + * Check the arguments. + */ + if(!gl || !filename || !comment) { + fprintf(stderr, "gl_load_history: NULL argument(s).\n"); + return 1; + }; +/* + * Expand the filename. + */ + expansion = ef_expand_file(gl->ef, filename, -1); + if(!expansion) { + fprintf(stderr, "Unable to expand %s (%s).\n", filename, + ef_last_error(gl->ef)); + return 1; + }; +/* + * Attempt to load from the specified file. + */ + if(_glh_load_history(gl->glh, expansion->files[0], comment, + gl->cutbuf, gl->linelen)) { + gl->cutbuf[0] = '\0'; + return 1; + }; + gl->cutbuf[0] = '\0'; + return 0; +} + +/*....................................................................... + * Where possible, register a function and associated data to be called + * whenever a specified event is seen on a file descriptor. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * fd int The file descriptor to watch. + * event GlFdEvent The type of activity to watch for. + * callback GlFdEventFn * The function to call when the specified + * event occurs. Setting this to 0 removes + * any existing callback. + * data void * A pointer to arbitrary data to pass to the + * callback function. + * Output: + * return int 0 - OK. + * 1 - Either gl==NULL, or this facility isn't + * available on the the host system + * (ie. select() isn't available). No + * error message is generated in the latter + * case. + */ +int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data) +#if !defined(HAVE_SELECT) +{return 1;} /* The facility isn't supported on this system */ +#else +{ + GlFdNode *prev; /* The node that precedes 'node' in gl->fd_nodes */ + GlFdNode *node; /* The file-descriptor node being checked */ +/* + * Check the arguments. + */ + if(!gl) { + fprintf(stderr, "gl_watch_fd: NULL gl argument.\n"); + return 1; + }; + if(fd < 0) { + fprintf(stderr, "gl_watch_fd: Error fd < 0.\n"); + return 1; + }; +/* + * Search the list of already registered fd activity nodes for the specified + * file descriptor. + */ + for(prev=NULL,node=gl->fd_nodes; node && node->fd != fd; + prev=node, node=node->next) + ; +/* + * Hasn't a node been allocated for this fd yet? + */ + if(!node) { +/* + * If there is no callback to record, just ignore the call. + */ + if(!callback) + return 0; +/* + * Allocate the new node. + */ + node = (GlFdNode *) _new_FreeListNode(gl->fd_node_mem); + if(!node) { + fprintf(stderr, "gl_watch_fd: Insufficient memory.\n"); + return 1; + }; +/* + * Prepend the node to the list. + */ + node->next = gl->fd_nodes; + gl->fd_nodes = node; +/* + * Initialize the node. + */ + node->fd = fd; + node->rd.fn = 0; + node->rd.data = NULL; + node->ur = node->wr = node->rd; + }; +/* + * Record the new callback. + */ + switch(event) { + case GLFD_READ: + node->rd.fn = callback; + node->rd.data = data; + if(callback) + FD_SET(fd, &gl->rfds); + else + FD_CLR(fd, &gl->rfds); + break; + case GLFD_WRITE: + node->wr.fn = callback; + node->wr.data = data; + if(callback) + FD_SET(fd, &gl->wfds); + else + FD_CLR(fd, &gl->wfds); + break; + case GLFD_URGENT: + node->ur.fn = callback; + node->ur.data = data; + if(callback) + FD_SET(fd, &gl->ufds); + else + FD_CLR(fd, &gl->ufds); + break; + }; +/* + * Keep a record of the largest file descriptor being watched. + */ + if(fd > gl->max_fd) + gl->max_fd = fd; +/* + * If we are deleting an existing callback, also delete the parent + * activity node if no callbacks are registered to the fd anymore. + */ + if(!callback) { + if(!node->rd.fn && !node->wr.fn && !node->ur.fn) { + if(prev) + prev->next = node->next; + else + gl->fd_nodes = node->next; + node = (GlFdNode *) _del_FreeListNode(gl->fd_node_mem, node); + }; + }; + return 0; +} + +/*....................................................................... + * When select() is available, this function is called by + * gl_read_character() to respond to file-descriptor events registered by + * the caller. + * + * Input: + * gl GetLine * The resource object of this module. + * Output: + * return int 0 - A character is waiting to be read from the + * terminal. + * 1 - An error occurred. + */ +static int gl_event_handler(GetLine *gl) +{ +/* + * If at any time no external callbacks remain, quit the loop return, + * so that we can simply wait in read(). This is designed as an + * optimization for when no callbacks have been registered on entry to + * this function, but since callbacks can delete themselves, it can + * also help later. + */ + while(gl->fd_nodes) { +/* + * Get the set of descriptors to be watched. + */ + fd_set rfds = gl->rfds; + fd_set wfds = gl->wfds; + fd_set ufds = gl->ufds; +/* + * Wait for activity on any of the file descriptors. + */ + int nready = select(gl->max_fd+1, &rfds, &wfds, &ufds, NULL); +/* + * If select() returns but none of the file descriptors are reported + * to have activity, then select() timed out. + */ + if(nready == 0) { + fprintf(stdout, "\r\nUnexpected select() timeout\r\n"); + return 1; +/* + * If nready < 0, this means an error occurred. + */ + } else if(nready < 0) { + if(errno != EINTR) { +#ifdef EAGAIN + if(!errno) /* This can happen with SysV O_NDELAY */ + errno = EAGAIN; +#endif + return 1; + }; +/* + * If the terminal input file descriptor has data available, return. + */ + } else if(FD_ISSET(gl->input_fd, &rfds)) { + return 0; +/* + * Check for activity on any of the file descriptors registered by the + * calling application, and call the associated callback functions. + */ + } else { + GlFdNode *node; /* The fd event node being checked */ +/* + * Search the list for the file descriptor that caused select() to return. + */ + for(node=gl->fd_nodes; node; node=node->next) { +/* + * Is there urgent out of band data waiting to be read on fd? + */ + if(node->ur.fn && FD_ISSET(node->fd, &ufds)) { + if(gl_call_fd_handler(gl, &node->ur, node->fd, GLFD_URGENT)) + return 1; + break; /* The callback may have changed the list of nodes */ +/* + * Is the fd readable? + */ + } else if(node->rd.fn && FD_ISSET(node->fd, &rfds)) { + if(gl_call_fd_handler(gl, &node->rd, node->fd, GLFD_READ)) + return 1; + break; /* The callback may have changed the list of nodes */ +/* + * Is the fd writable? + */ + } else if(node->wr.fn && FD_ISSET(node->fd, &rfds)) { + if(gl_call_fd_handler(gl, &node->wr, node->fd, GLFD_WRITE)) + return 1; + break; /* The callback may have changed the list of nodes */ + }; + }; + }; + }; + return 0; +} + +/*....................................................................... + * This is a private function of gl_event_handler(), used to call a + * file-descriptor callback. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * gfh GlFdHandler * The I/O handler. + * fd int The file-descriptor being reported. + * event GlFdEvent The I/O event being reported. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd, + GlFdEvent event) +{ + Termios attr; /* The terminal attributes */ + int redisplay = 0; /* True to have the input line redisplayed */ + int waserr = 0; /* True after any error */ +/* + * We don't want to do a longjmp in the middle of a callback that + * might be modifying global or heap data, so block all the signals + * that we are trapping. + */ + if(sigprocmask(SIG_BLOCK, &gl->new_signal_set, NULL) == -1) { + fprintf(stderr, "getline(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; +/* + * Re-enable conversion of newline characters to carriage-return/linefeed, + * so that the callback can write to the terminal without having to do + * anything special. + */ + if(tcgetattr(gl->input_fd, &attr)) { + fprintf(stderr, "\r\ngetline(): tcgetattr error: %s\r\n", strerror(errno)); + return 1; + }; + attr.c_oflag |= OPOST; + while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) { + if (errno != EINTR) { + fprintf(stderr, "\r\ngetline(): tcsetattr error: %s\r\n", + strerror(errno)); + return 1; + }; + }; +/* + * Invoke the application's callback function. + */ + switch(gfh->fn(gl, gfh->data, fd, event)) { + default: + case GLFD_ABORT: + waserr = 1; + break; + case GLFD_REFRESH: + redisplay = 1; + break; + case GLFD_CONTINUE: + redisplay = gl->prompt_changed; + break; + }; +/* + * Disable conversion of newline characters to carriage-return/linefeed. + */ + attr.c_oflag &= ~(OPOST); + while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) { + if(errno != EINTR) { + fprintf(stderr, "\ngetline(): tcsetattr error: %s\n", strerror(errno)); + return 1; + }; + }; +/* + * If requested, redisplay the input line. + */ + if(redisplay && gl_redisplay(gl, 1)) + return 1; +/* + * Unblock the signals that we were trapping before this function + * was called. + */ + if(sigprocmask(SIG_UNBLOCK, &gl->new_signal_set, NULL) == -1) { + fprintf(stderr, "getline(): sigprocmask error: %s\n", strerror(errno)); + return 1; + }; + return waserr; +} +#endif /* HAVE_SELECT */ + +/*....................................................................... + * Switch history groups. History groups represent separate history + * lists recorded within a single history buffer. Different groups + * are distinguished by integer identifiers chosen by the calling + * appplicaton. Initially new_GetLine() sets the group identifier to + * 0. Whenever a new line is appended to the history list, the current + * group identifier is recorded with it, and history lookups only + * consider lines marked with the current group identifier. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * id unsigned The new history group identifier. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_group_history(GetLine *gl, unsigned id) +{ +/* + * Check the arguments. + */ + if(!gl) { + fprintf(stderr, "gl_group_history: NULL argument(s).\n"); + return 1; + }; +/* + * If the group isn't being changed, do nothing. + */ + if(_glh_get_group(gl->glh) == id) + return 0; +/* + * Establish the new group. + */ + if(_glh_set_group(gl->glh, id)) + return 1; +/* + * Prevent history information from the previous group being + * inappropriately used by the next call to gl_get_line(). + */ + gl->preload_history = 0; + gl->last_search = -1; + return 0; +} + +/*....................................................................... + * Display the contents of the history list. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * fp FILE * The stdio output stream to write to. + * fmt const char * A format string. This containing characters to be + * written verbatim, plus any of the following + * format directives: + * %D - The date, formatted like 2001-11-20 + * %T - The time of day, formatted like 23:59:59 + * %N - The sequential entry number of the + * line in the history buffer. + * %G - The number of the history group that + * the line belongs to. + * %% - A literal % character. + * %H - The history line itself. + * Note that a '\n' newline character is not + * appended by default. + * all_groups int If true, display history lines from all + * history groups. Otherwise only display + * those of the current history group. + * max_lines int If max_lines is < 0, all available lines + * are displayed. Otherwise only the most + * recent max_lines lines will be displayed. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_show_history(GetLine *gl, FILE *fp, const char *fmt, int all_groups, + int max_lines) +{ +/* + * Check the arguments. + */ + if(!gl || !fp || !fmt) { + fprintf(stderr, "gl_show_history: NULL argument(s).\n"); + return 1; + }; + return _glh_show_history(gl->glh, fp, fmt, all_groups, max_lines); +} + +/*....................................................................... + * Update if necessary, and return the current size of the terminal. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * def_ncolumn int If the number of columns in the terminal + * can't be determined, substitute this number. + * def_nline int If the number of lines in the terminal can't + * be determined, substitute this number. + * Output: + * return GlTerminalSize The current terminal size. + */ +GlTerminalSize gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline) +{ + GlTerminalSize size; /* The return value */ + const char *env; /* The value of an environment variable */ + int n; /* A number read from env[] */ +/* + * Set the number of lines and columns to non-sensical values so that + * we know later if they have been set. + */ + gl->nline = 0; + gl->ncolumn = 0; +/* + * Are we reading from a terminal? + */ + if(gl->is_term) { +/* + * Ask the terminal directly if possible. + */ +#ifdef USE_SIGWINCH + (void) gl_resize_terminal(gl, 0); +#endif +/* + * If gl_resize_terminal() couldn't be used, or it returned non-sensical + * values for the number of lines, see if the LINES environment variable + * exists and specifies a believable number. If this doesn't work, + * look up the default size in the terminal information database, + * where available. + */ + if(gl->nline < 1) { + if((env = getenv("LINES")) && (n=atoi(env)) > 0) + gl->nline = n; +#ifdef USE_TERMINFO + else + gl->nline = tigetnum((char *)"lines"); +#elif defined(USE_TERMCAP) + else + gl->nline = tgetnum("li"); +#endif + }; +/* + * If gl_resize_terminal() couldn't be used, or it returned non-sensical + * values for the number of columns, see if the COLUMNS environment variable + * exists and specifies a believable number. If this doesn't work, fall + * lookup the default size in the terminal information database, + * where available. + */ + if(gl->ncolumn < 1) { + if((env = getenv("COLUMNS")) && (n=atoi(env)) > 0) + gl->ncolumn = n; +#ifdef USE_TERMINFO + else + gl->ncolumn = tigetnum((char *)"cols"); +#elif defined(USE_TERMCAP) + else + gl->ncolumn = tgetnum("co"); +#endif + }; + }; +/* + * If we still haven't been able to acquire reasonable values, substitute + * the default values specified by the caller. + */ + if(gl->nline <= 0) + gl->nline = def_nline; + if(gl->ncolumn <= 0) + gl->ncolumn = def_ncolumn; +/* + * Copy the new size into the return value. + */ + size.nline = gl->nline; + size.ncolumn = gl->ncolumn; + return size; +} + +/*....................................................................... + * Resize or delete the history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * bufsize size_t The number of bytes in the history buffer, or 0 + * to delete the buffer completely. + * Output: + * return int 0 - OK. + * 1 - Insufficient memory (the previous buffer + * will have been retained). No error message + * will be displayed. + */ +int gl_resize_history(GetLine *gl, size_t bufsize) +{ + return gl ? _glh_resize_history(gl->glh, bufsize) : 1; +} + +/*....................................................................... + * Set an upper limit to the number of lines that can be recorded in the + * history list, or remove a previously specified limit. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * max_lines int The maximum number of lines to allow, or -1 to + * cancel a previous limit and allow as many lines + * as will fit in the current history buffer size. + */ +void gl_limit_history(GetLine *gl, int max_lines) +{ + if(gl) + _glh_limit_history(gl->glh, max_lines); +} + +/*....................................................................... + * Discard either all historical lines, or just those associated with the + * current history group. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * all_groups int If true, clear all of the history. If false, + * clear only the stored lines associated with the + * currently selected history group. + */ +void gl_clear_history(GetLine *gl, int all_groups) +{ + if(gl) + _glh_clear_history(gl->glh, all_groups); +} + +/*....................................................................... + * Temporarily enable or disable the gl_get_line() history mechanism. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * enable int If true, turn on the history mechanism. If + * false, disable it. + */ +void gl_toggle_history(GetLine *gl, int enable) +{ + if(gl) + _glh_toggle_history(gl->glh, enable); +} + +/*....................................................................... + * Lookup a history line by its sequential number of entry in the + * history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * id unsigned long The identification number of the line to + * be returned, where 0 denotes the first line + * that was entered in the history list, and + * each subsequently added line has a number + * one greater than the previous one. For + * the range of lines currently in the list, + * see the gl_range_of_history() function. + * Input/Output: + * line GlHistoryLine * A pointer to the variable in which to + * return the details of the line. + * Output: + * return int 0 - The line is no longer in the history + * list, and *line has not been changed. + * 1 - The requested line can be found in + * *line. Note that line->line is part + * of the history buffer, so a + * private copy should be made if you + * wish to use it after subsequent calls + * to any functions that take *gl as an + * argument. + */ +int gl_lookup_history(GetLine *gl, unsigned long id, GlHistoryLine *line) +{ + return gl ? _glh_lookup_history(gl->glh, (GlhLineID) id, &line->line, + &line->group, &line->timestamp) : 0; +} + +/*....................................................................... + * Query the state of the history list. Note that any of the input/output + * pointers can be specified as NULL. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Input/Output: + * state GlHistoryState * A pointer to the variable in which to record + * the return values. + */ +void gl_state_of_history(GetLine *gl, GlHistoryState *state) +{ + if(gl && state) + _glh_state_of_history(gl->glh, &state->enabled, &state->group, + &state->max_lines); +} + +/*....................................................................... + * Query the number and range of lines in the history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * range GlHistoryRange * A pointer to the variable in which to record + * the return values. If range->nline=0, the + * range of lines will be given as 0-0. + */ +void gl_range_of_history(GetLine *gl, GlHistoryRange *range) +{ + if(gl && range) + _glh_range_of_history(gl->glh, &range->oldest, &range->newest, + &range->nlines); +} + +/*....................................................................... + * Return the size of the history buffer and the amount of the + * buffer that is currently in use. + * + * Input: + * gl GetLine * The gl_get_line() resource object. + * Input/Output: + * GlHistorySize size * A pointer to the variable in which to return + * the results. + */ +void gl_size_of_history(GetLine *gl, GlHistorySize *size) +{ + if(gl && size) + _glh_size_of_history(gl->glh, &size->size, &size->used); +} + +/*....................................................................... + * This is the action function that lists the contents of the history + * list. + */ +static KT_KEY_FN(gl_list_history) +{ +/* + * Start a new line. + */ + if(fprintf(gl->output_fp, "\r\n") < 0) + return 1; +/* + * List history lines that belong to the current group. + */ + _glh_show_history(gl->glh, gl->output_fp, "%N %T %H\r\n", 0, + count<=1 ? -1 : count); +/* + * Redisplay the line being edited. + */ + gl->term_curpos = 0; + return gl_redisplay(gl,1); +} + +/*....................................................................... + * Specify whether text that users type should be displayed or hidden. + * In the latter case, only the prompt is displayed, and the final + * input line is not archived in the history list. + * + * Input: + * gl GetLine * The gl_get_line() resource object. + * enable int 0 - Disable echoing. + * 1 - Enable echoing. + * -1 - Just query the mode without changing it. + * Output: + * return int The echoing disposition that was in effect + * before this function was called: + * 0 - Echoing was disabled. + * 1 - Echoing was enabled. + */ +int gl_echo_mode(GetLine *gl, int enable) +{ + if(gl) { + int was_echoing = gl->echo; + if(enable >= 0) + gl->echo = enable; + return was_echoing; + }; + return 1; +} + +/*....................................................................... + * Display the prompt. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_display_prompt(GetLine *gl) +{ + const char *pptr; /* A pointer into gl->prompt[] */ + unsigned old_attr=0; /* The current text display attributes */ + unsigned new_attr=0; /* The requested text display attributes */ +/* + * Temporarily switch to echoing output characters. + */ + int kept_echo = gl->echo; + gl->echo = 1; +/* + * In case the screen got messed up, send a carriage return to + * put the cursor at the beginning of the current terminal line. + */ + if(gl_output_control_sequence(gl, 1, gl->bol)) + return 1; +/* + * Write the prompt, using the currently selected prompt style. + */ + switch(gl->prompt_style) { + case GL_LITERAL_PROMPT: + if(gl_output_string(gl, gl->prompt, '\0')) + return 1; + break; + case GL_FORMAT_PROMPT: + for(pptr=gl->prompt; *pptr; pptr++) { +/* + * Does the latest character appear to be the start of a directive? + */ + if(*pptr == '%') { +/* + * Check for and act on attribute changing directives. + */ + switch(pptr[1]) { +/* + * Add or remove a text attribute from the new set of attributes. + */ + case 'B': case 'U': case 'S': case 'P': case 'F': case 'V': + case 'b': case 'u': case 's': case 'p': case 'f': case 'v': + switch(*++pptr) { + case 'B': /* Switch to a bold font */ + new_attr |= GL_TXT_BOLD; + break; + case 'b': /* Switch to a non-bold font */ + new_attr &= ~GL_TXT_BOLD; + break; + case 'U': /* Start underlining */ + new_attr |= GL_TXT_UNDERLINE; + break; + case 'u': /* Stop underlining */ + new_attr &= ~GL_TXT_UNDERLINE; + break; + case 'S': /* Start highlighting */ + new_attr |= GL_TXT_STANDOUT; + break; + case 's': /* Stop highlighting */ + new_attr &= ~GL_TXT_STANDOUT; + break; + case 'P': /* Switch to a pale font */ + new_attr |= GL_TXT_DIM; + break; + case 'p': /* Switch to a non-pale font */ + new_attr &= ~GL_TXT_DIM; + break; + case 'F': /* Switch to a flashing font */ + new_attr |= GL_TXT_BLINK; + break; + case 'f': /* Switch to a steady font */ + new_attr &= ~GL_TXT_BLINK; + break; + case 'V': /* Switch to reverse video */ + new_attr |= GL_TXT_REVERSE; + break; + case 'v': /* Switch out of reverse video */ + new_attr &= ~GL_TXT_REVERSE; + break; + }; + continue; +/* + * A literal % is represented by %%. Skip the leading %. + */ + case '%': + pptr++; + break; + }; + }; +/* + * Many terminals, when asked to turn off a single text attribute, turn + * them all off, so the portable way to turn one off individually is to + * explicitly turn them all off, then specify those that we want from + * scratch. + */ + if(old_attr & ~new_attr) { + if(gl_output_control_sequence(gl, 1, gl->text_attr_off)) + return 1; + old_attr = 0; + }; +/* + * Install new text attributes? + */ + if(new_attr != old_attr) { + if(new_attr & GL_TXT_BOLD && !(old_attr & GL_TXT_BOLD) && + gl_output_control_sequence(gl, 1, gl->bold)) + return 1; + if(new_attr & GL_TXT_UNDERLINE && !(old_attr & GL_TXT_UNDERLINE) && + gl_output_control_sequence(gl, 1, gl->underline)) + return 1; + if(new_attr & GL_TXT_STANDOUT && !(old_attr & GL_TXT_STANDOUT) && + gl_output_control_sequence(gl, 1, gl->standout)) + return 1; + if(new_attr & GL_TXT_DIM && !(old_attr & GL_TXT_DIM) && + gl_output_control_sequence(gl, 1, gl->dim)) + return 1; + if(new_attr & GL_TXT_REVERSE && !(old_attr & GL_TXT_REVERSE) && + gl_output_control_sequence(gl, 1, gl->reverse)) + return 1; + if(new_attr & GL_TXT_BLINK && !(old_attr & GL_TXT_BLINK) && + gl_output_control_sequence(gl, 1, gl->blink)) + return 1; + old_attr = new_attr; + }; +/* + * Display the latest character. + */ + if(gl_output_char(gl, *pptr, pptr[1])) + return 1; + }; +/* + * Turn off all text attributes now that we have finished drawing + * the prompt. + */ + if(gl_output_control_sequence(gl, 1, gl->text_attr_off)) + return 1; + break; + }; +/* + * Restore the original echo mode. + */ + gl->echo = kept_echo; +/* + * The prompt has now been displayed at least once. + */ + gl->prompt_changed = 0; + return 0; +} + +/*....................................................................... + * This function can be called from gl_get_line() callbacks to have + * the prompt changed when they return. It has no effect if gl_get_line() + * is not currently being invoked. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * prompt const char * The new prompt. + */ +void gl_replace_prompt(GetLine *gl, const char *prompt) +{ + if(gl) { + gl->prompt = prompt ? prompt : ""; + gl->prompt_len = gl_displayed_prompt_width(gl); + gl->prompt_changed = 1; + }; +} + +/*....................................................................... + * Work out the length of the current prompt on the terminal, according + * to the current prompt formatting style. + * + * Input: + * gl GetLine * The resource object of this library. + * Output: + * return int The number of displayed characters. + */ +static int gl_displayed_prompt_width(GetLine *gl) +{ + int slen=0; /* The displayed number of characters */ + const char *pptr; /* A pointer into prompt[] */ +/* + * The length differs according to the prompt display style. + */ + switch(gl->prompt_style) { + case GL_LITERAL_PROMPT: + return gl_displayed_string_width(gl, gl->prompt, -1, 0); + break; + case GL_FORMAT_PROMPT: +/* + * Add up the length of the displayed string, while filtering out + * attribute directives. + */ + for(pptr=gl->prompt; *pptr; pptr++) { +/* + * Does the latest character appear to be the start of a directive? + */ + if(*pptr == '%') { +/* + * Check for and skip attribute changing directives. + */ + switch(pptr[1]) { + case 'B': case 'b': case 'U': case 'u': case 'S': case 's': + pptr++; + continue; +/* + * A literal % is represented by %%. Skip the leading %. + */ + case '%': + pptr++; + break; + }; + }; + slen += gl_displayed_char_width(gl, *pptr, slen); + }; + break; + }; + return slen; +} + +/*....................................................................... + * Specify whether to heed text attribute directives within prompt + * strings. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * style GlPromptStyle The style of prompt (see the definition of + * GlPromptStyle in libtecla.h for details). + */ +void gl_prompt_style(GetLine *gl, GlPromptStyle style) +{ + if(gl) { + if(style != gl->prompt_style) { + gl->prompt_style = style; + gl->prompt_len = gl_displayed_prompt_width(gl); + gl->prompt_changed = 1; + }; + }; +} + +/*....................................................................... + * Tell gl_get_line() how to respond to a given signal. This can be used + * both to override the default responses to signals that gl_get_line() + * normally catches and to add new signals to the list that are to be + * caught. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * signo int The number of the signal to be caught. + * flags unsigned A bitwise union of GlSignalFlags enumerators. + * after GlAfterSignal What to do after the application's signal + * handler has been called. + * errno_value int The value to set errno to. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value) +{ + GlSignalNode *sig; +/* + * Check the arguments. + */ + if(!gl) { + fprintf(stderr, "gl_trap_signal: NULL argument(s).\n"); + return 1; + }; +/* + * See if the signal has already been registered. + */ + for(sig=gl->sigs; sig && sig->signo != signo; sig = sig->next) + ; +/* + * If the signal hasn't already been registered, allocate a node for + * it. + */ + if(!sig) { + sig = (GlSignalNode *) _new_FreeListNode(gl->sig_mem); + if(!sig) + return 1; +/* + * Add the new node to the head of the list. + */ + sig->next = gl->sigs; + gl->sigs = sig; +/* + * Record the signal number. + */ + sig->signo = signo; +/* + * Create a signal set that includes just this signal. + */ + sigemptyset(&sig->proc_mask); + if(sigaddset(&sig->proc_mask, signo) == -1) { + fprintf(stderr, "gl_trap_signal: sigaddset error: %s\n", + strerror(errno)); + sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig); + return 1; + }; + }; +/* + * Record the new signal attributes. + */ + sig->flags = flags; + sig->after = after; + sig->errno_value = errno_value; + return 0; +} + +/*....................................................................... + * Remove a signal from the list of signals that gl_get_line() traps. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * signo int The number of the signal to be ignored. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_ignore_signal(GetLine *gl, int signo) +{ + GlSignalNode *sig; /* The gl->sigs list node of the specified signal */ + GlSignalNode *prev; /* The node that precedes sig in the list */ +/* + * Check the arguments. + */ + if(!gl) { + fprintf(stderr, "gl_ignore_signal: NULL argument(s).\n"); + return 1; + }; +/* + * Find the node of the gl->sigs list which records the disposition + * of the specified signal. + */ + for(prev=NULL,sig=gl->sigs; sig && sig->signo != signo; + prev=sig,sig=sig->next) + ; + if(sig) { +/* + * Remove the node from the list. + */ + if(prev) + prev->next = sig->next; + else + gl->sigs = sig->next; +/* + * Return the node to the freelist. + */ + sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig); + }; + return 0; +} + +/*....................................................................... + * This function is called when an input line has been completed. It + * appends the specified newline character, terminates the line, + * records the line in the history buffer if appropriate, and positions + * the terminal cursor at the start of the next line. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * newline_char int The newline character to add to the end + * of the line. + * archive int True to have the line archived in the + * history buffer. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int gl_line_ended(GetLine *gl, int newline_char, int archive) +{ +/* + * If the newline character is printable, display it. + */ + if(isprint((int)(unsigned char) newline_char)) { + if(gl_end_of_line(gl, 1) || gl_add_char_to_line(gl, newline_char)) + return 1; + } else { +/* + * Otherwise just append it to the input line buffer. + */ + gl->line[gl->ntotal++] = newline_char; + gl->line[gl->ntotal] = '\0'; + }; +/* + * Add the line to the history buffer if it was entered with a + * newline or carriage return character. + */ + if(archive) + (void) _glh_add_history(gl->glh, gl->line, 0); +/* + * Unless depending on the system-provided line editing, start a new + * line after the end of the line that has just been entered. + */ + if(gl->editor != GL_NO_EDITOR) { + if(gl_end_of_line(gl, 1) || + gl_output_raw_string(gl, "\r\n")) + return 1; + }; + return 0; +} + +/*....................................................................... + * Return the last signal that was caught by the most recent call to + * gl_get_line(), or -1 if no signals were caught. This is useful if + * gl_get_line() returns errno=EINTR and you need to find out what signal + * caused it to abort. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Output: + * return int The last signal caught by the most recent + * call to gl_get_line(), or -1 if no signals + * were caught. + */ +int gl_last_signal(const GetLine *gl) +{ + return gl ? gl->last_signal : -1; +} diff --git a/libtecla-1.4.1/getline.h b/libtecla-1.4.1/getline.h new file mode 100644 index 0000000..24b0875 --- /dev/null +++ b/libtecla-1.4.1/getline.h @@ -0,0 +1,88 @@ +#ifndef getline_h +#define getline_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Set the name of the getline configuration file. + */ +#define TECLA_CONFIG_FILE "~/.teclarc" + +/* + * The following macro returns non-zero if a character is + * a control character. + */ +#define IS_CTRL_CHAR(c) ((unsigned char)(c) < ' ' || (unsigned char)(c)=='\177') + +/* + * The following macro returns non-zero if a character is + * a meta character. + */ +#define IS_META_CHAR(c) (((unsigned char)(c) & 0x80) && !isprint((int)(unsigned char)(c))) + +/* + * Return the character that would be produced by pressing the + * specified key plus the control key. + */ +#define MAKE_CTRL(c) ((c)=='?' ? '\177' : ((unsigned char)toupper(c) & ~0x40)) + +/* + * Return the character that would be produced by pressing the + * specified key plus the meta key. + */ +#define MAKE_META(c) ((unsigned char)(c) | 0x80) + +/* + * Given a binary control character, return the character that + * had to be pressed at the same time as the control key. + */ +#define CTRL_TO_CHAR(c) (toupper((unsigned char)(c) | 0x40)) + +/* + * Given a meta character, return the character that was pressed + * at the same time as the meta key. + */ +#define META_TO_CHAR(c) ((unsigned char)(c) & ~0x80) + +/* + * Specify the string of characters other than the alphanumeric characters, + * that are to be considered parts of words. + */ +#define GL_WORD_CHARS "_*\?\\[]" + +/* + * Define the escape character, both as a string and as a character. + */ +#define GL_ESC_STR "\033" +#define GL_ESC_CHAR '\033' + +#endif diff --git a/libtecla-1.4.1/hash.c b/libtecla-1.4.1/hash.c new file mode 100644 index 0000000..89f8245 --- /dev/null +++ b/libtecla-1.4.1/hash.c @@ -0,0 +1,748 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include + +#include "hash.h" +#include "strngmem.h" +#include "freelist.h" + +/* + * The following container object contains free-lists to be used + * for allocation of HashTable containers and nodes. + */ +struct HashMemory { + FreeList *hash_memory; /* HashTable free-list */ + FreeList *node_memory; /* HashNode free-list */ + StringMem *string_memory; /* Memory used to allocate hash strings */ +}; + +/* + * Define a hash symbol-table entry. + * See symbol.h for the definition of the Symbol container type. + */ +typedef struct HashNode HashNode; +struct HashNode { + Symbol symbol; /* The symbol stored in the hash-entry */ + HashNode *next; /* The next hash-table entry in a bucket list */ +}; + +/* + * Each hash-table bucket contains a linked list of entries that + * hash to the same bucket. + */ +typedef struct { + HashNode *head; /* The head of the bucket hash-node list */ + int count; /* The number of entries in the list */ +} HashBucket; + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +/* + * A hash-table consists of 'size' hash buckets. + * Note that the HashTable typedef for this struct is contained in hash.h. + */ +struct HashTable { + char errmsg[ERRLEN+1];/* Error-report buffer */ + HashMemory *mem; /* HashTable free-list */ + int internal_mem; /* True if 'mem' was allocated by _new_HashTable() */ + int case_sensitive; /* True if case is significant in lookup keys */ + int size; /* The number of hash buckets */ + HashBucket *bucket; /* An array of 'size' hash buckets */ + int (*keycmp)(const char *, const char *); /* Key comparison function */ + void *app_data; /* Application-provided data */ + HASH_DEL_FN(*del_fn); /* Application-provided 'app_data' destructor */ +}; + +static HashNode *_del_HashNode(HashTable *hash, HashNode *node); +static HashNode *_new_HashNode(HashTable *hash, const char *name, int code, + void (*fn)(void), void *data, SYM_DEL_FN(*del_fn)); +static HashNode *_find_HashNode(HashTable *hash, HashBucket *bucket, + const char *name, HashNode **prev); +static HashBucket *_find_HashBucket(HashTable *hash, const char *name); +static int _ht_lower_strcmp(const char *node_key, const char *look_key); +static int _ht_strcmp(const char *node_key, const char *look_key); + +/*....................................................................... + * Allocate a free-list for use in allocating hash tables and their nodes. + * + * Input: + * list_count int The number of HashTable containers per free-list + * block. + * node_count int The number of HashTable nodes per free-list block. + * Output: + * return HashMemory * The new free-list for use in allocating hash tables + * and their nodes. + */ +HashMemory *_new_HashMemory(int hash_count, int node_count) +{ + HashMemory *mem; +/* + * Allocate the free-list container. + */ + mem = (HashMemory *) malloc(sizeof(HashMemory)); + if(!mem) { + fprintf(stderr, "_new_HashMemory: Insufficient memory.\n"); + return NULL; + }; +/* + * Initialize the container at least up to the point at which it can + * safely be passed to _del_HashMemory(). + */ + mem->hash_memory = NULL; + mem->node_memory = NULL; + mem->string_memory = NULL; +/* + * Allocate the two free-lists. + */ + mem->hash_memory = _new_FreeList("_new_HashMemory", sizeof(HashTable), + hash_count); + if(!mem->hash_memory) + return _del_HashMemory(mem, 1); + mem->node_memory = _new_FreeList("_new_HashMemory", sizeof(HashNode), + node_count); + if(!mem->node_memory) + return _del_HashMemory(mem, 1); + mem->string_memory = _new_StringMem("_new_HashMemory", 64); + if(!mem->string_memory) + return _del_HashMemory(mem, 1); +/* + * Return the free-list container. + */ + return mem; +} + +/*....................................................................... + * Delete a HashTable free-list. An error will be displayed if the list is + * still in use and the deletion will be aborted. + * + * Input: + * mem HashMemory * The free-list container to be deleted. + * force int If force==0 then _del_HashMemory() will complain + * and refuse to delete the free-list if any + * of nodes have not been returned to the free-list. + * If force!=0 then _del_HashMemory() will not check + * whether any nodes are still in use and will + * always delete the list. + * Output: + * return HashMemory * Always NULL (even if the memory could not be + * deleted). + */ +HashMemory *_del_HashMemory(HashMemory *mem, int force) +{ + const char *caller = "_del_HashMemory"; + if(mem) { + if(!force && (_busy_FreeListNodes(mem->hash_memory) > 0 || + _busy_FreeListNodes(mem->node_memory) > 0)) { + fprintf(stderr, "%s: Free-list in use.\n", caller); + return NULL; + }; + mem->hash_memory = _del_FreeList(caller, mem->hash_memory, force); + mem->node_memory = _del_FreeList(caller, mem->node_memory, force); + mem->string_memory = _del_StringMem(caller, mem->string_memory, force); + free(mem); + }; + return NULL; +} + +/*....................................................................... + * Create a new hash table. + * + * Input: + * mem HashMemory * An optional free-list for use in allocating + * HashTable containers and nodes. See explanation + * in hash.h. If you are going to allocate more + * than one hash table, then it will be more + * efficient to allocate a single free-list for + * all of them than to force each hash table + * to allocate its own private free-list. + * size int The size of the hash table. Best performance + * will be acheived if this is a prime number. + * hcase HashCase Specify how symbol case is considered when + * looking up symbols, from: + * IGNORE_CASE - Upper and lower case versions + * of a letter are treated as + * being identical. + * HONOUR_CASE - Upper and lower case versions + * of a letter are treated as + * being distinct. + * characters in a lookup name is significant. + * app_data void * Optional application data to be registered + * to the table. This is presented to user + * provided SYM_DEL_FN() symbol destructors along + * with the symbol data. + * del_fn() HASH_DEL_FN(*) If you want app_data to be free'd when the + * hash-table is destroyed, register a suitable + * destructor function here. + * Output: + * return HashTable * The new hash table, or NULL on error. + */ +HashTable *_new_HashTable(HashMemory *mem, int size, HashCase hcase, + void *app_data, HASH_DEL_FN(*del_fn)) +{ + HashTable *hash; /* The table to be returned */ + int allocate_mem = !mem; /* True if mem should be internally allocated */ + int i; +/* + * Check arguments. + */ + if(size <= 0) { + fprintf(stderr, "_new_HashTable: Illegal table size (%d).\n", size); + return NULL; + }; +/* + * Allocate an internal free-list? + */ + if(allocate_mem) { + mem = _new_HashMemory(1, 100); + if(!mem) + return NULL; + }; +/* + * Allocate the container. + */ + hash = (HashTable *) _new_FreeListNode(mem->hash_memory); + if(!hash) { + fprintf(stderr, "_new_HashTable: Insufficient memory.\n"); + if(allocate_mem) + mem = _del_HashMemory(mem, 1); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize + * the container at least up to the point at which it can safely + * be passed to _del_HashTable(). + */ + hash->errmsg[0] = '\0'; + hash->mem = mem; + hash->internal_mem = allocate_mem; + hash->case_sensitive = hcase==HONOUR_CASE; + hash->size = size; + hash->bucket = NULL; + hash->keycmp = hash->case_sensitive ? _ht_strcmp : _ht_lower_strcmp; + hash->app_data = app_data; + hash->del_fn = del_fn; +/* + * Allocate the array of 'size' hash buckets. + */ + hash->bucket = (HashBucket *) malloc(sizeof(HashBucket) * size); + if(!hash->bucket) { + fprintf(stderr, "_new_HashTable: Insufficient memory for %d buckets.\n", + size); + return _del_HashTable(hash); + }; +/* + * Initialize the bucket array. + */ + for(i=0; ibucket + i; + b->head = NULL; + b->count = 0; + }; +/* + * The table is ready for use - albeit currently empty. + */ + return hash; +} + +/*....................................................................... + * Delete a hash-table. + * + * Input: + * hash HashTable * The hash table to be deleted. + * Output: + * return HashTable * The deleted hash table (always NULL). + */ +HashTable *_del_HashTable(HashTable *hash) +{ + if(hash) { +/* + * Clear and delete the bucket array. + */ + if(hash->bucket) { + _clear_HashTable(hash); + free(hash->bucket); + hash->bucket = NULL; + }; +/* + * Delete application data. + */ + if(hash->del_fn) + hash->del_fn(hash->app_data); +/* + * If the hash table was allocated from an internal free-list, delete + * it and the hash table by deleting the free-list. Otherwise just + * return the hash-table to the external free-list. + */ + if(hash->internal_mem) + _del_HashMemory(hash->mem, 1); + else + hash = (HashTable *) _del_FreeListNode(hash->mem->hash_memory, hash); + }; + return NULL; +} + +/*....................................................................... + * Create and install a new entry in a hash table. If an entry with the + * same name already exists, replace its contents with the new data. + * + * Input: + * hash HashTable * The hash table to insert the symbol into. + * name const char * The name to tag the entry with. + * code int An application-specific code to be stored in + * the entry. + * fn void (*)(void) An application-specific function to be stored + * in the entry. + * data void * An application-specific pointer to data to be + * associated with the entry, or NULL if not + * relevant. + * del_fn SYM_DEL_FN(*) An optional destructor function. When the + * symbol is deleted this function will be called + * with the 'code' and 'data' arguments given + * above. Any application data that was registered + * to the table via the app_data argument of + * _new_HashTable() will also be passed. + * Output: + * return HashNode * The new entry, or NULL if there was insufficient + * memory or the arguments were invalid. + */ +Symbol *_new_HashSymbol(HashTable *hash, const char *name, int code, + void (*fn)(void), void *data, SYM_DEL_FN(*del_fn)) +{ + HashBucket *bucket; /* The hash-bucket associated with the name */ + HashNode *node; /* The new node */ +/* + * Check arguments. + */ + if(!hash || !name) + return NULL; +/* + * Get the hash bucket of the specified name. + */ + bucket = _find_HashBucket(hash, name); +/* + * See if a node with the same name already exists. + */ + node = _find_HashNode(hash, bucket, name, NULL); +/* + * If found, delete its contents by calling the user-supplied + * destructor function, if provided. + */ + if(node) { + if(node->symbol.data && node->symbol.del_fn) { + node->symbol.data = node->symbol.del_fn(hash->app_data, node->symbol.code, + node->symbol.data); + }; +/* + * Allocate a new node if necessary. + */ + } else { + node = _new_HashNode(hash, name, code, fn, data, del_fn); + if(!node) + return NULL; + }; +/* + * Install the node at the head of the hash-bucket list. + */ + node->next = bucket->head; + bucket->head = node; + bucket->count++; + return &node->symbol; +} + +/*....................................................................... + * Remove and delete a given hash-table entry. + * + * Input: + * hash HashTable * The hash table to find the symbol in. + * name const char * The name of the entry. + * Output: + * return HashNode * The deleted hash node (always NULL). + */ +Symbol *_del_HashSymbol(HashTable *hash, const char *name) +{ + if(hash && name) { + HashBucket *bucket = _find_HashBucket(hash, name); + HashNode *prev; /* The node preceding the located node */ + HashNode *node = _find_HashNode(hash, bucket, name, &prev); +/* + * Node found? + */ + if(node) { +/* + * Remove the node from the bucket list. + */ + if(prev) { + prev->next = node->next; + } else { + bucket->head = node->next; + }; +/* + * Record the loss of a node. + */ + bucket->count--; +/* + * Delete the node. + */ + (void) _del_HashNode(hash, node); + }; + }; + return NULL; +} + +/*....................................................................... + * Look up a symbol in the hash table. + * + * Input: + * hash HashTable * The table to look up the string in. + * name const char * The name of the symbol to look up. + * Output: + * return Symbol * The located hash-table symbol, or NULL if not + * found. + */ +Symbol *_find_HashSymbol(HashTable *hash, const char *name) +{ + HashBucket *bucket; /* The hash-table bucket associated with name[] */ + HashNode *node; /* The hash-table node of the requested symbol */ +/* + * Check arguments. + */ + if(!hash) + return NULL; +/* + * Nothing to lookup? + */ + if(!name) + return NULL; +/* + * Hash the name to a hash-table bucket. + */ + bucket = _find_HashBucket(hash, name); +/* + * Find the bucket entry that exactly matches the name. + */ + node = _find_HashNode(hash, bucket, name, NULL); + if(!node) + return NULL; + return &node->symbol; +} + +/*....................................................................... + * Private function used to allocate a hash-table node. + * The caller is responsible for checking that the specified symbol + * is unique and for installing the returned entry in the table. + * + * Input: + * hash HashTable * The table to allocate the node for. + * name const char * The name of the new entry. + * code int A user-supplied context code. + * fn void (*)(void) A user-supplied function pointer. + * data void * A user-supplied data pointer. + * del_fn SYM_DEL_FN(*) An optional 'data' destructor function. + * Output: + * return HashNode * The new node, or NULL on error. + */ +static HashNode *_new_HashNode(HashTable *hash, const char *name, int code, + void (*fn)(void), void *data, SYM_DEL_FN(*del_fn)) +{ + HashNode *node; /* The new node */ +/* + * Allocate the new node from the free list. + */ + node = (HashNode *) _new_FreeListNode(hash->mem->node_memory); + if(!node) + return NULL; +/* + * Before attempting any operation that might fail, initialize the + * contents of 'node' at least up to the point at which it can be + * safely passed to _del_HashNode(). + */ + node->symbol.name = NULL; + node->symbol.code = code; + node->symbol.fn = fn; + node->symbol.data = data; + node->symbol.del_fn = del_fn; + node->next = NULL; +/* + * Allocate a copy of 'name'. + */ + node->symbol.name = _new_StringMemString(hash->mem->string_memory, + strlen(name) + 1); + if(!node->symbol.name) + return _del_HashNode(hash, node); +/* + * If character-case is insignificant in the current table, convert the + * name to lower case while copying it. + */ + if(hash->case_sensitive) { + strcpy(node->symbol.name, name); + } else { + const char *src = name; + char *dst = node->symbol.name; + for( ; *src; src++,dst++) + *dst = tolower(*src); + *dst = '\0'; + }; + return node; +} + +/*....................................................................... + * Private function used to delete a hash-table node. + * The node must have been removed from its list before calling this + * function. + * + * Input: + * hash HashTable * The table for which the node was originally + * allocated. + * node HashNode * The node to be deleted. + * Output: + * return HashNode * The deleted node (always NULL). + */ +static HashNode *_del_HashNode(HashTable *hash, HashNode *node) +{ + if(node) { + node->symbol.name = _del_StringMemString(hash->mem->string_memory, + node->symbol.name); +/* + * Call the user-supplied data-destructor if provided. + */ + if(node->symbol.data && node->symbol.del_fn) + node->symbol.data = node->symbol.del_fn(hash->app_data, + node->symbol.code, + node->symbol.data); +/* + * Return the node to the free-list. + */ + node->next = NULL; + node = (HashNode *) _del_FreeListNode(hash->mem->node_memory, node); + }; + return NULL; +} + +/*....................................................................... + * Private function to locate the hash bucket associated with a given + * name. + * + * This uses a hash-function described in the dragon-book + * ("Compilers - Principles, Techniques and Tools", by Aho, Sethi and + * Ullman; pub. Adison Wesley) page 435. + * + * Input: + * hash HashTable * The table to look up the string in. + * name const char * The name of the symbol to look up. + * Output: + * return HashBucket * The located hash-bucket. + */ +static HashBucket *_find_HashBucket(HashTable *hash, const char *name) +{ + unsigned const char *kp; + unsigned long h = 0L; + if(hash->case_sensitive) { + for(kp=(unsigned const char *) name; *kp; kp++) + h = 65599UL * h + *kp; /* 65599 is a prime close to 2^16 */ + } else { + for(kp=(unsigned const char *) name; *kp; kp++) + h = 65599UL * h + tolower((int)*kp); /* 65599 is a prime close to 2^16 */ + }; + return hash->bucket + (h % hash->size); +} + +/*....................................................................... + * Search for a given name in the entries of a given bucket. + * + * Input: + * hash HashTable * The hash-table being searched. + * bucket HashBucket * The bucket to search (use _find_HashBucket()). + * name const char * The name to search for. + * Output: + * prev HashNode ** If prev!=NULL then the pointer to the node + * preceding the located node in the list will + * be recorded in *prev. This will be NULL either + * if the name is not found or the located node is + * at the head of the list of entries. + * return HashNode * The located hash-table node, or NULL if not + * found. + */ +static HashNode *_find_HashNode(HashTable *hash, HashBucket *bucket, + const char *name, HashNode **prev) +{ + HashNode *last; /* The previously searched node */ + HashNode *node; /* The node that is being searched */ +/* + * Search the list for a node containing the specified name. + */ + for(last=NULL, node=bucket->head; + node && hash->keycmp(node->symbol.name, name)!=0; + last = node, node=node->next) + ; + if(prev) + *prev = node ? last : NULL; + return node; +} + +/*....................................................................... + * When hash->case_sensitive is zero this function is called + * in place of strcmp(). In such cases the hash-table names are stored + * as lower-case versions of the original strings so this function + * performs the comparison against lower-case copies of the characters + * of the string being compared. + * + * Input: + * node_key const char * The lower-case hash-node key being compared + * against. + * look_key const char * The lookup key. + * Output: + * return int <0 if node_key < look_key. + * 0 if node_key == look_key. + * >0 if node_key > look_key. + */ +static int _ht_lower_strcmp(const char *node_key, const char *look_key) +{ + int cn; /* The latest character from node_key[] */ + int cl; /* The latest character from look_key[] */ + do { + cn = *node_key++; + cl = *look_key++; + } while(cn && cn==tolower(cl)); + return cn - tolower(cl); +} + +/*....................................................................... + * This is a wrapper around strcmp for comparing hash-keys in a case + * sensitive manner. The reason for having this wrapper, instead of using + * strcmp() directly, is to make some C++ compilers happy. The problem + * is that when the library is compiled with a C++ compiler, the + * declaration of the comparison function is a C++ declaration, whereas + * strcmp() is a pure C function and thus although it appears to have the + * same declaration, the compiler disagrees. + * + * Input: + * node_key char * The lower-case hash-node key being compared against. + * look_key char * The lookup key. + * Output: + * return int <0 if node_key < look_key. + * 0 if node_key == look_key. + * >0 if node_key > look_key. + */ +static int _ht_strcmp(const char *node_key, const char *look_key) +{ + return strcmp(node_key, look_key); +} + +/*....................................................................... + * Empty a hash-table by deleting all of its entries. + * + * Input: + * hash HashTable * The hash table to clear. + * Output: + * return int 0 - OK. + * 1 - Invalid arguments. + */ +int _clear_HashTable(HashTable *hash) +{ + int i; +/* + * Check the arguments. + */ + if(!hash) + return 1; +/* + * Clear the contents of the bucket array. + */ + for(i=0; isize; i++) { + HashBucket *bucket = hash->bucket + i; +/* + * Delete the list of active hash nodes from the bucket. + */ + HashNode *node = bucket->head; + while(node) { + HashNode *next = node->next; + (void) _del_HashNode(hash, node); + node = next; + }; +/* + * Mark the bucket as empty. + */ + bucket->head = NULL; + bucket->count = 0; + }; + return 0; +} + +/*....................................................................... + * Execute a given function on each entry of a hash table, returning + * before completion if the the specified function returns non-zero. + * + * Input: + * hash HashTable * The table to traverse. + * scan_fn HASH_SCAN_FN(*) The function to call. + * context void * Optional caller-specific context data + * to be passed to scan_fn(). + * Output: + * return int 0 - OK. + * 1 - Either the arguments were invalid, or + * scan_fn() returned non-zero at some + * point. + */ +int _scan_HashTable(HashTable *hash, HASH_SCAN_FN(*scan_fn), void *context) +{ + int i; +/* + * Check the arguments. + */ + if(!hash || !scan_fn) + return 1; +/* + * Iterate through the buckets of the table. + */ + for(i=0; isize; i++) { + HashBucket *bucket = hash->bucket + i; + HashNode *node; +/* + * Iterate through the list of symbols that fall into bucket i, + * passing each one to the caller-specified function. + */ + for(node=bucket->head; node; node=node->next) { + if(scan_fn(&node->symbol, context)) + return 1; + }; + }; + return 0; +} diff --git a/libtecla-1.4.1/hash.h b/libtecla-1.4.1/hash.h new file mode 100644 index 0000000..13c0a2b --- /dev/null +++ b/libtecla-1.4.1/hash.h @@ -0,0 +1,157 @@ +#ifndef hash_h +#define hash_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * The following macro can be used to prototype or define a + * function that deletes the data of a symbol-table entry. + * + * Input: + * app_data void * The _new_HashTable() app_data argument. + * code int The Symbol::code argument. + * sym_data void * The Symbol::data argument to be deleted. + * Output: + * return void * The deleted data (always return NULL). + */ +#define SYM_DEL_FN(fn) void *(fn)(void *app_data, int code, void *sym_data) + +/* + * The following macro can be used to prototype or define a + * function that deletes the application-data of a hash-table. + * + * Input: + * data void * The _new_HashTable() 'app_data' argument to be + * deleted. + * Output: + * return void * The deleted data (always return NULL). + */ +#define HASH_DEL_FN(fn) void *(fn)(void *app_data) + +/* + * The following is a container for recording the context + * of a symbol in a manner that is independant of the particular + * symbol-table implementation. Each hash-table entry contains + * the following user supplied parameters: + * + * 1. An optional integral parameter 'code'. This is useful for + * enumerating a symbol or for describing what type of data + * or function is stored in the symbol. + * + * 2. An optional generic function pointer. This is useful for + * associating functions with names. The user is responsible + * for casting between the generic function type and the + * actual function type. The code field could be used to + * enumerate what type of function to cast to. + * + * 3. An optional generic pointer to a static or heap-allocated + * object. It is up to the user to cast this back to the + * appropriate object type. Again, the code field could be used + * to describe what type of object is stored there. + * If the object is dynamically allocated and should be discarded + * when the symbol is deleted from the symbol table, send a + * destructor function to have it deleted automatically. + */ +typedef struct { + char *name; /* The name of the symbol */ + int code; /* Application supplied integral code */ + void (*fn)(void); /* Application supplied generic function */ + void *data; /* Application supplied context data */ + SYM_DEL_FN(*del_fn); /* Data destructor function */ +} Symbol; + +/* + * HashNode's and HashTable's are small objects. Separately allocating + * many such objects would normally cause memory fragmentation. To + * counter this, HashMemory objects are used. These contain + * dedicated free-lists formed from large dynamically allocated arrays + * of objects. One HashMemory object can be shared between multiple hash + * tables (within a single thread). + */ +typedef struct HashMemory HashMemory; + + /* Create a free-list for allocation of hash tables and their nodes */ + +HashMemory *_new_HashMemory(int hash_count, int node_count); + + /* Delete a redundant free-list if not being used */ + +HashMemory *_del_HashMemory(HashMemory *mem, int force); + +/* + * Declare an alias for the private HashTable structure defined in + * hash.c. + */ +typedef struct HashTable HashTable; + +/* + * Enumerate case-sensitivity options. + */ +typedef enum { + IGNORE_CASE, /* Ignore case when looking up symbols */ + HONOUR_CASE /* Honor case when looking up symbols */ +} HashCase; + + /* Create a new hash-table */ + +HashTable *_new_HashTable(HashMemory *mem, int size, HashCase hcase, + void *app_data, HASH_DEL_FN(*del_fn)); + + /* Delete a reference to a hash-table */ + +HashTable *_del_HashTable(HashTable *hash); + + /* Add an entry to a hash table */ + +Symbol *_new_HashSymbol(HashTable *hash, const char *key, int code, + void (*fn)(void), void *data, SYM_DEL_FN(*del_fn)); + + /* Remove and delete all the entries in a given hash table */ + +int _clear_HashTable(HashTable *hash); + + /* Remove and delete a given hash-table entry */ + +Symbol *_del_HashSymbol(HashTable *hash, const char *key); + + /* Lookup a given hash-table entry */ + +Symbol *_find_HashSymbol(HashTable *hash, const char *key); + + /* Execute a given function on each entry of a hash table, returning */ + /* before completion if the specified function returns non-zero. */ + +#define HASH_SCAN_FN(fn) int (fn)(Symbol *sym, void *context) + +int _scan_HashTable(HashTable *hash, HASH_SCAN_FN(*scan_fn), void *context); + +#endif diff --git a/libtecla-1.4.1/history.c b/libtecla-1.4.1/history.c new file mode 100644 index 0000000..5a8d94f --- /dev/null +++ b/libtecla-1.4.1/history.c @@ -0,0 +1,2003 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include +#include +#include + +#include "history.h" +#include "freelist.h" + +/* + * GlLineNode's record the location and length of historical lines in + * a buffer array. + */ +typedef struct GlLineNode GlLineNode; +struct GlLineNode { + long id; /* The unique identifier of this history line */ + time_t timestamp; /* The time at which the line was archived */ + unsigned group; /* The identifier of the history group to which the */ + /* the line belongs. */ + GlLineNode *next; /* The next youngest line in the list */ + GlLineNode *prev; /* The next oldest line in the list */ + int start; /* The start index of the line in the buffer */ + int nchar; /* The total length of the line, including the '\0' */ +}; + +/* + * The number of GlLineNode elements per freelist block. + */ +#define LINE_NODE_BLK 100 + +/* + * Lines are organised in the buffer from oldest to newest. The + * positions of the lines are recorded in a doubly linked list + * of GlLineNode objects. + */ +typedef struct { + FreeList *node_mem; /* A freelist of GlLineNode objects */ + GlLineNode *head; /* The head of the list of lines */ + GlLineNode *tail; /* The tail of the list of lines */ +} GlLineList; + +/* + * All elements of the history mechanism are recorded in an object of + * the following type. + */ +struct GlHistory { + char *buffer; /* A circular buffer used to record historical input */ + /* lines. */ + size_t buflen; /* The length of the buffer array */ + GlLineList list; /* A list of the start of lines in buffer[] */ + GlLineNode *recall; /* The last line recalled, or NULL if no recall */ + /* session is currently active. */ + GlLineNode *id_node;/* The node at which the last ID search terminated */ + const char *prefix; /* A pointer to the line containing the prefix that */ + /* is being searched for. */ + int prefix_len; /* The length of the prefix */ + unsigned long seq; /* The next ID to assign to a line node */ + unsigned group; /* The identifier of the current history group */ + int nline; /* The number of lines currently in the history list */ + int max_lines; /* Either -1 or a ceiling on the number of lines */ + int enable; /* If false, ignore history additions and lookups */ +}; + +static char *_glh_restore_line(GlHistory *glh, char *line, size_t dim); +static int _glh_cant_load_history(GlHistory *glh, const char *filename, + int lineno, const char *message, FILE *fp); +static int _glh_write_timestamp(FILE *fp, time_t timestamp); +static int _glh_decode_timestamp(char *string, char **endp, time_t *t); +static void _glh_discard_node(GlHistory *glh, GlLineNode *node); +static GlLineNode *_glh_find_id(GlHistory *glh, GlhLineID id); + +/*....................................................................... + * Create a line history maintenance object. + * + * Input: + * buflen size_t The number of bytes to allocate to the circular + * buffer that is used to record all of the + * most recent lines of user input that will fit. + * If buflen==0, no buffer will be allocated. + * Output: + * return GlHistory * The new object, or NULL on error. + */ +GlHistory *_new_GlHistory(size_t buflen) +{ + GlHistory *glh; /* The object to be returned */ +/* + * Allocate the container. + */ + glh = (GlHistory *) malloc(sizeof(GlHistory)); + if(!glh) { + fprintf(stderr, "_new_GlHistory: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_GlHistory(). + */ + glh->buffer = NULL; + glh->buflen = buflen; + glh->list.node_mem = NULL; + glh->list.head = NULL; + glh->list.tail = NULL; + glh->recall = NULL; + glh->id_node = NULL; + glh->prefix = NULL; + glh->prefix_len = 0; + glh->seq = 0; + glh->group = 0; + glh->nline = 0; + glh->max_lines = -1; + glh->enable = 1; +/* + * Allocate the buffer, if required. + */ + if(buflen > 0) { + glh->buffer = (char *) malloc(sizeof(char) * buflen); + if(!glh->buffer) { + fprintf(stderr, "_new_GlHistory: Insufficient memory.\n"); + return _del_GlHistory(glh); + }; + }; +/* + * Allocate the GlLineNode freelist. + */ + glh->list.node_mem = _new_FreeList("_new_GlHistory", sizeof(GlLineNode), + LINE_NODE_BLK); + if(!glh->list.node_mem) + return _del_GlHistory(glh); + return glh; +} + +/*....................................................................... + * Delete a GlHistory object. + * + * Input: + * glh GlHistory * The object to be deleted. + * Output: + * return GlHistory * The deleted object (always NULL). + */ +GlHistory *_del_GlHistory(GlHistory *glh) +{ + if(glh) { +/* + * Delete the buffer. + */ + if(glh->buffer) { + free(glh->buffer); + glh->buffer = NULL; + }; +/* + * Delete the freelist of GlLineNode's. + */ + glh->list.node_mem = _del_FreeList("_del_GlHistory", glh->list.node_mem, 1); +/* + * The contents of the list were deleted by deleting the freelist. + */ + glh->list.head = NULL; + glh->list.tail = NULL; +/* + * Delete the container. + */ + free(glh); + }; + return NULL; +} + +/*....................................................................... + * Add a new line to the end of the history buffer, wrapping round to the + * start of the buffer if needed. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The line to be archived. + * force int Unless this flag is non-zero, empty lines and + * lines which match the previous line in the history + * buffer, aren't archived. This flag requests that + * the line be archived regardless. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_add_history(GlHistory *glh, const char *line, int force) +{ + GlLineList *list; /* The line location list */ + int nchar; /* The number of characters needed to record the line */ + GlLineNode *node; /* The new line location list node */ + int empty; /* True if the string is empty */ + const char *nlptr;/* A pointer to a newline character in line[] */ + int i; +/* + * Check the arguments. + */ + if(!glh || !line) + return 1; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return 0; +/* + * Get the line location list. + */ + list = &glh->list; +/* + * Cancel any ongoing search. + */ + if(_glh_cancel_search(glh)) + return 1; +/* + * See how much buffer space will be needed to record the line? + * + * If the string contains a terminating newline character, arrange to + * have the archived line NUL terminated at this point. + */ + nlptr = strchr(line, '\n'); + if(nlptr) + nchar = (nlptr - line) + 1; + else + nchar = strlen(line) + 1; +/* + * If the line is too big to fit in the buffer, truncate it. + */ + if(nchar > glh->buflen) + nchar = glh->buflen; +/* + * Is the line empty? + */ + empty = 1; + for(i=0; itail && strlen(glh->buffer + list->tail->start) == nchar-1 && + strncmp(line, glh->buffer + list->tail->start, nchar-1)==0) + return 0; +/* + * Allocate the list node that will record the line location. + */ + node = (GlLineNode *) _new_FreeListNode(list->node_mem); + if(!node) + return 1; +/* + * Is the buffer empty? + */ + if(!list->head) { +/* + * Place the line at the beginning of the buffer. + */ + strncpy(glh->buffer, line, nchar); + glh->buffer[nchar-1] = '\0'; +/* + * Record the location of the line. + */ + node->start = 0; +/* + * The buffer has one or more lines in it. + */ + } else { +/* + * Place the start of the new line just after the most recently + * added line. + */ + int start = list->tail->start + list->tail->nchar; +/* + * If there is insufficient room between the end of the most + * recently added line and the end of the buffer, we place the + * line at the beginning of the buffer. To make as much space + * as possible for this line, we first delete any old lines + * at the end of the buffer, then shift the remaining contents + * of the buffer to the end of the buffer. + */ + if(start + nchar >= glh->buflen) { + GlLineNode *last; /* The last line in the buffer */ + GlLineNode *ln; /* A member of the list of line locations */ + int shift; /* The shift needed to move the contents of the */ + /* buffer to its end. */ +/* + * Delete any old lines between the most recent line and the end of the + * buffer. + */ + while(list->head && list->head->start > list->tail->start) + _glh_discard_node(glh, list->head); +/* + * Find the line that is nearest the end of the buffer. + */ + last = NULL; + for(ln=list->head; ln; ln=ln->next) { + if(!last || ln->start > last->start) + last = ln; + }; +/* + * How big a shift is needed to move the existing contents of the + * buffer to the end of the buffer? + */ + shift = last ? (glh->buflen - (last->start + last->nchar)) : 0; +/* + * Is any shift needed? + */ + if(shift > 0) { +/* + * Move the buffer contents to the end of the buffer. + */ + memmove(glh->buffer + shift, glh->buffer, glh->buflen - shift); +/* + * Update the listed locations to reflect the shift. + */ + for(ln=list->head; ln; ln=ln->next) + ln->start += shift; + }; +/* + * The new line should now be located at the start of the buffer. + */ + start = 0; + }; +/* + * Make space for the new line at the beginning of the buffer by + * deleting the oldest lines. This just involves removing them + * from the list of used locations. Also enforce the current + * maximum number of lines. + */ + while(list->head && + ((list->head->start >= start && list->head->start - start < nchar) || + (glh->max_lines >= 0 && glh->nline>=glh->max_lines))) { + _glh_discard_node(glh, list->head); + }; +/* + * Copy the new line into the buffer. + */ + memcpy(glh->buffer + start, line, nchar); + glh->buffer[start + nchar - 1] = '\0'; +/* + * Record its location. + */ + node->start = start; + }; +/* + * Append the line location node to the end of the list. + */ + node->id = glh->seq++; + node->timestamp = time(NULL); + node->group = glh->group; + node->nchar = nchar; + node->next = NULL; + node->prev = list->tail; + if(list->tail) + list->tail->next = node; + else + list->head = node; + list->tail = node; + glh->nline++; + return 0; +} + +/*....................................................................... + * Recall the next oldest line that has the search prefix last recorded + * by _glh_search_prefix(). + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, if anything + * was found, its contents will have been replaced + * with the matching line. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * A pointer to line[0], or NULL if not found. + */ +char *_glh_find_backwards(GlHistory *glh, char *line, size_t dim) +{ + GlLineNode *node; /* The line location node being checked */ + int first; /* True if this is the start of a new search */ +/* + * Check the arguments. + */ + if(!glh || !line) { + fprintf(stderr, "_glh_find_backwards: NULL argument(s).\n"); + return NULL; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return NULL; +/* + * Check the line dimensions. + */ + if(dim < strlen(line) + 1) { + fprintf(stderr, + "_glh_find_backwards: 'dim' inconsistent with strlen(line) contents.\n"); + return NULL; + }; +/* + * Is this the start of a new search? + */ + first = glh->recall==NULL; +/* + * If this is the first search backwards, save the current line + * for potential recall later, and mark it as the last line + * recalled. + */ + if(first) { + if(_glh_add_history(glh, line, 1)) + return NULL; + glh->recall = glh->list.tail; + }; +/* + * If there is no search prefix, the prefix last set by glh_search_prefix() + * doesn't exist in the history buffer. + */ + if(!glh->prefix) + return NULL; +/* + * From where should we start the search? + */ + if(glh->recall) + node = glh->recall->prev; + else + node = glh->list.tail; +/* + * Search backwards through the list for the first match with the + * prefix string. + */ + for( ; node && + (node->group != glh->group || + strncmp(glh->buffer + node->start, glh->prefix, glh->prefix_len) != 0); + node = node->prev) + ; +/* + * Was a matching line found? + */ + if(node) { +/* + * Recall the found node as the starting point for subsequent + * searches. + */ + glh->recall = node; +/* + * Copy the matching line into the provided line buffer. + */ + strncpy(line, glh->buffer + node->start, dim); + line[dim-1] = '\0'; + return line; + }; +/* + * No match was found. + */ + return NULL; +} + +/*....................................................................... + * Recall the next newest line that has the search prefix last recorded + * by _glh_search_prefix(). + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, if anything + * was found, its contents will have been replaced + * with the matching line. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * The line requested, or NULL if no matching line + * was found. + */ +char *_glh_find_forwards(GlHistory *glh, char *line, size_t dim) +{ + GlLineNode *node; /* The line location node being checked */ +/* + * Check the arguments. + */ + if(!glh || !line) { + fprintf(stderr, "_glh_find_forwards: NULL argument(s).\n"); + return NULL; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return NULL; +/* + * Check the line dimensions. + */ + if(dim < strlen(line) + 1) { + fprintf(stderr, + "_glh_find_forwards: 'dim' inconsistent with strlen(line) contents.\n"); + return NULL; + }; +/* + * From where should we start the search? + */ + if(glh->recall) + node = glh->recall->next; + else + return NULL; +/* + * If there is no search prefix, the prefix last set by glh_search_prefix() + * doesn't exist in the history buffer. + */ + if(!glh->prefix) + return NULL; +/* + * Search forwards through the list for the first match with the + * prefix string. + */ + for( ; node && + (node->group != glh->group || + strncmp(glh->buffer + node->start, glh->prefix, glh->prefix_len) != 0); + node = node->next) + ; +/* + * Was a matching line found? + */ + if(node) { +/* + * Did we hit the line that was originally being edited when the + * current history traversal started? + */ + if(node == glh->list.tail) + return _glh_restore_line(glh, line, dim); +/* + * Copy the matching line into the provided line buffer. + */ + strncpy(line, glh->buffer + node->start, dim); + line[dim-1] = '\0'; +/* + * Record the starting point of the next search. + */ + glh->recall = node; +/* + * Return the matching line to the user. + */ + return line; + }; +/* + * No match was found. + */ + return NULL; +} + +/*....................................................................... + * If a search is in progress, cancel it. + * + * This involves discarding the line that was temporarily saved by + * _glh_find_backwards() when the search was originally started, + * and reseting the search iteration pointer to NULL. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_cancel_search(GlHistory *glh) +{ +/* + * Check the arguments. + */ + if(!glh) { + fprintf(stderr, "_glh_cancel_search: NULL argument(s).\n"); + return 1; + }; +/* + * If there wasn't a search in progress, do nothing. + */ + if(!glh->recall) + return 0; +/* + * Delete the node of the preserved line. + */ + _glh_discard_node(glh, glh->list.tail); +/* + * Reset the search pointers. + */ + glh->recall = NULL; + glh->prefix = ""; + glh->prefix_len = 0; + return 0; +} + +/*....................................................................... + * Set the prefix of subsequent history searches. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The command line who's prefix is to be used. + * prefix_len int The length of the prefix. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_search_prefix(GlHistory *glh, const char *line, int prefix_len) +{ + GlLineNode *node; /* The line location node being checked */ +/* + * Check the arguments. + */ + if(!glh) { + fprintf(stderr, "_glh_search_prefix: NULL argument(s).\n"); + return 1; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return 0; +/* + * Record a zero length search prefix? + */ + if(prefix_len <= 0) { + glh->prefix_len = 0; + glh->prefix = ""; + return 0; + }; +/* + * Record the length of the new search prefix. + */ + glh->prefix_len = prefix_len; +/* + * If any history line starts with the specified prefix, record a + * pointer to it for comparison in subsequent searches. If the prefix + * doesn't match any of the lines, then simply record NULL to indicate + * that there is no point in searching. Note that _glh_add_history() + * clears this pointer by calling _glh_cancel_search(), so there is + * no danger of it being used after the buffer has been modified. + */ + for(node = glh->list.tail ; node && + (node->group != glh->group || + strncmp(glh->buffer + node->start, line, prefix_len) != 0); + node = node->prev) + ; +/* + * If a matching line was found record it for use as the search + * prefix. + */ + glh->prefix = node ? glh->buffer + node->start : NULL; + return 0; +} + +/*....................................................................... + * Recall the oldest recorded line. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, its contents + * will have been replaced with the oldest line. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * A pointer to line[0], or NULL if not found. + */ +char *_glh_oldest_line(GlHistory *glh, char *line, size_t dim) +{ + GlLineNode *node; /* The line location node being checked */ + int first; /* True if this is the start of a new search */ +/* + * Check the arguments. + */ + if(!glh || !line) { + fprintf(stderr, "_glh_oldest_line: NULL argument(s).\n"); + return NULL; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return NULL; +/* + * Check the line dimensions. + */ + if(dim < strlen(line) + 1) { + fprintf(stderr, + "_glh_oldest_line: 'dim' inconsistent with strlen(line) contents.\n"); + return NULL; + }; +/* + * Is this the start of a new search? + */ + first = glh->recall==NULL; +/* + * If this is the first search backwards, save the current line + * for potential recall later, and mark it as the last line + * recalled. + */ + if(first) { + if(_glh_add_history(glh, line, 1)) + return NULL; + glh->recall = glh->list.tail; + }; +/* + * Locate the oldest line that belongs to the current group. + */ + for(node=glh->list.head; node && node->group != glh->group; + node = node->next) + ; +/* + * No line found? + */ + if(!node) + return NULL; +/* + * Record the above node as the starting point for subsequent + * searches. + */ + glh->recall = node; +/* + * Copy the recalled line into the provided line buffer. + */ + strncpy(line, glh->buffer + node->start, dim); + line[dim-1] = '\0'; + return line; +} + +/*....................................................................... + * Recall the line that was being entered when the search started. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, its contents + * will have been replaced with the line that was + * being entered when the search was started. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * A pointer to line[0], or NULL if not found. + */ +char *_glh_current_line(GlHistory *glh, char *line, size_t dim) +{ +/* + * Check the arguments. + */ + if(!glh || !line) { + fprintf(stderr, "_glh_current_line: NULL argument(s).\n"); + return NULL; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return NULL; +/* + * Check the line dimensions. + */ + if(dim < strlen(line) + 1) { + fprintf(stderr, + "_glh_current_line: 'dim' inconsistent with strlen(line) contents.\n"); + return NULL; + }; +/* + * Restore the original line. + */ + return _glh_restore_line(glh, line, dim); +} + +/*....................................................................... + * Remove the line that was originally being edited when the history + * traversal was started, from its saved position in the history list, + * and place it in the provided line buffer. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, its contents + * will have been replaced with the saved line. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * A pointer to line[0], or NULL if not found. + */ +static char *_glh_restore_line(GlHistory *glh, char *line, size_t dim) +{ + GlLineNode *tail; /* The tail node to be discarded */ +/* + * If there wasn't a search in progress, do nothing. + */ + if(!glh->recall) + return NULL; +/* + * Get the list node that is to be removed. + */ + tail = glh->list.tail; +/* + * If a pointer to the saved line is being used to record the + * current search prefix, reestablish the search prefix, to + * have it recorded by another history line if possible. + */ + if(glh->prefix == glh->buffer + tail->start) + (void) _glh_search_prefix(glh, glh->buffer + tail->start, glh->prefix_len); +/* + * Copy the recalled line into the input-line buffer. + */ + strncpy(line, glh->buffer + tail->start, dim); + line[dim-1] = '\0'; +/* + * Discard the line-location node. + */ + _glh_discard_node(glh, tail); +/* + * Mark the search as ended. + */ + glh->recall = NULL; + return line; +} + +/*....................................................................... + * Query the id of a history line offset by a given number of lines from + * the one that is currently being recalled. If a recall session isn't + * in progress, or the offset points outside the history list, 0 is + * returned. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * offset int The line offset (0 for the current line, < 0 + * for an older line, > 0 for a newer line. + * Output: + * return GlhLineID The identifier of the line that is currently + * being recalled, or 0 if no recall session is + * currently in progress. + */ +GlhLineID _glh_line_id(GlHistory *glh, int offset) +{ + GlLineNode *node; /* The line location node being checked */ +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return 0; +/* + * Search forward 'offset' lines to find the required line. + */ + if(offset >= 0) { + for(node=glh->recall; node && offset != 0; node=node->next) { + if(node->group == glh->group) + offset--; + }; + } else { + for(node=glh->recall; node && offset != 0; node=node->prev) { + if(node->group == glh->group) + offset++; + }; + }; + return node ? node->id : 0; +} + +/*....................................................................... + * Recall a line by its history buffer ID. If the line is no longer + * in the buffer, or the id is zero, NULL is returned. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * id GlhLineID The ID of the line to be returned. + * line char * The input line buffer. On input this should contain + * the current input line, and on output, its contents + * will have been replaced with the saved line. + * dim size_t The allocated dimensions of the line buffer. + * Output: + * return char * A pointer to line[0], or NULL if not found. + */ +char *_glh_recall_line(GlHistory *glh, GlhLineID id, char *line, size_t dim) +{ + GlLineNode *node; /* The line location node being checked */ +/* + * Is history enabled? + */ + if(!glh->enable || !glh->buffer || glh->max_lines == 0) + return NULL; +/* + * If we are starting a new recall session, save the current line + * for potential recall later. + */ + if(!glh->recall && _glh_add_history(glh, line, 1)) + return NULL; +/* + * Search for the specified line. + */ + node = _glh_find_id(glh, id); +/* + * Not found? + */ + if(!node || node->group != glh->group) + return NULL; +/* + * Record the node of the matching line as the starting point + * for subsequent searches. + */ + glh->recall = node; +/* + * Copy the recalled line into the provided line buffer. + */ + strncpy(line, glh->buffer + node->start, dim); + line[dim-1] = '\0'; + return line; +} + +/*....................................................................... + * Save the current history in a specified file. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * filename const char * The name of the new file to record the + * history in. + * comment const char * Extra information such as timestamps will + * be recorded on a line started with this + * string, the idea being that the file can + * double as a command file. Specify "" if + * you don't care. + * max_lines int The maximum number of lines to save, or -1 + * to save all of the lines in the history + * list. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_save_history(GlHistory *glh, const char *filename, const char *comment, + int max_lines) +{ + FILE *fp; /* The output file */ + GlLineNode *node; /* The line being saved */ + GlLineNode *head; /* The head of the list of lines to be saved */ +/* + * Check the arguments. + */ + if(!glh || !filename || !comment) { + fprintf(stderr, "_glh_save_history: NULL argument(s).\n"); + return 1; + }; +/* + * Attempt to open the specified file. + */ + fp = fopen(filename, "w"); + if(!fp) { + fprintf(stderr, "_glh_save_history: Can't open %s (%s).\n", + filename, strerror(errno)); + return 1; + }; +/* + * If a ceiling on the number of lines to save was specified, count + * that number of lines backwards, to find the first line to be saved. + */ + head = NULL; + if(max_lines >= 0) { + for(head=glh->list.tail; head && --max_lines > 0; head=head->prev) + ; + }; + if(!head) + head = glh->list.head; +/* + * Write the contents of the history buffer to the history file, writing + * associated data such as timestamps, to a line starting with the + * specified comment string. + */ + for(node=head; node; node=node->next) { +/* + * Write peripheral information associated with the line, as a comment. + */ + if(fprintf(fp, "%s ", comment) < 0 || + _glh_write_timestamp(fp, node->timestamp) || + fprintf(fp, " %u\n", node->group) < 0) { + fprintf(stderr, "Error writing %s (%s).\n", filename, strerror(errno)); + (void) fclose(fp); + return 1; + }; +/* + * Write the history line. + */ + if(fprintf(fp, "%s\n", glh->buffer + node->start) < 0) { + fprintf(stderr, "Error writing %s (%s).\n", filename, strerror(errno)); + (void) fclose(fp); + return 1; + }; + }; +/* + * Close the history file. + */ + if(fclose(fp) == EOF) { + fprintf(stderr, "Error writing %s (%s).\n", filename, strerror(errno)); + return 1; + }; + return 0; +} + +/*....................................................................... + * Restore previous history lines from a given file. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * filename const char * The name of the file to read from. + * comment const char * The same comment string that was passed to + * _glh_save_history() when this file was + * written. + * line char * A buffer into which lines can be read. + * dim size_t The allocated dimension of line[]. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_load_history(GlHistory *glh, const char *filename, const char *comment, + char *line, size_t dim) +{ + FILE *fp; /* The output file */ + size_t comment_len; /* The length of the comment string */ + time_t timestamp; /* The timestamp of the history line */ + unsigned group; /* The identifier of the history group to which */ + /* the line belongs. */ + int lineno; /* The line number being read */ +/* + * Check the arguments. + */ + if(!glh || !filename || !comment || !line) { + fprintf(stderr, "_glh_load_history: NULL argument(s).\n"); + return 1; + }; +/* + * Measure the length of the comment string. + */ + comment_len = strlen(comment); +/* + * Clear the history list. + */ + _glh_clear_history(glh, 1); +/* + * Attempt to open the specified file. Don't treat it as an error + * if the file doesn't exist. + */ + fp = fopen(filename, "r"); + if(!fp) + return 0; +/* + * Attempt to read each line and preceding peripheral info, and add these + * to the history list. + */ + for(lineno=1; fgets(line, dim, fp) != NULL; lineno++) { + char *lptr; /* A pointer into the input line */ +/* + * Check that the line starts with the comment string. + */ + if(strncmp(line, comment, comment_len) != 0) { + return _glh_cant_load_history(glh, filename, lineno, + "Corrupt history parameter line", fp); + }; +/* + * Skip spaces and tabs after the comment. + */ + for(lptr=line+comment_len; *lptr && (*lptr==' ' || *lptr=='\t'); lptr++) + ; +/* + * The next word must be a timestamp. + */ + if(_glh_decode_timestamp(lptr, &lptr, ×tamp)) { + return _glh_cant_load_history(glh, filename, lineno, + "Corrupt timestamp", fp); + }; +/* + * Skip spaces and tabs. + */ + while(*lptr==' ' || *lptr=='\t') + lptr++; +/* + * The next word must be an unsigned integer group number. + */ + group = (int) strtoul(lptr, &lptr, 10); + if(*lptr != ' ' && *lptr != '\n') { + return _glh_cant_load_history(glh, filename, lineno, + "Corrupt group id", fp); + }; +/* + * Skip spaces and tabs. + */ + while(*lptr==' ' || *lptr=='\t') + lptr++; +/* + * There shouldn't be anything left on the line. + */ + if(*lptr != '\n') { + return _glh_cant_load_history(glh, filename, lineno, + "Corrupt parameter line", fp); + }; +/* + * Now read the history line itself. + */ + lineno++; + if(fgets(line, dim, fp) == NULL) + return _glh_cant_load_history(glh, filename, lineno, "Read error", fp); +/* + * Append the line to the history buffer. + */ + if(_glh_add_history(glh, line, 1)) { + return _glh_cant_load_history(glh, filename, lineno, + "Insufficient memory to record line", fp); + }; +/* + * Record the group and timestamp information along with the line. + */ + if(glh->list.tail) { + glh->list.tail->timestamp = timestamp; + glh->list.tail->group = group; + }; + }; +/* + * Close the file. + */ + (void) fclose(fp); + return 0; +} + +/*....................................................................... + * This is a private error return function of _glh_load_history(). + */ +static int _glh_cant_load_history(GlHistory *glh, const char *filename, + int lineno, const char *message, FILE *fp) +{ + fprintf(stderr, "%s:%d: %s.\n", filename, lineno, message); + (void) fclose(fp); + return 1; +} + +/*....................................................................... + * Switch history groups. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * group unsigned The new group identifier. This will be recorded + * with subsequent history lines, and subsequent + * history searches will only return lines with + * this group identifier. This allows multiple + * separate history lists to exist within + * a single GlHistory object. Note that the + * default group identifier is 0. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_set_group(GlHistory *glh, unsigned group) +{ +/* + * Check the arguments. + */ + if(!glh) { + fprintf(stderr, "_glh_set_group: NULL argument(s).\n"); + return 1; + }; +/* + * Is the group being changed? + */ + if(group != glh->group) { +/* + * Cancel any ongoing search. + */ + if(_glh_cancel_search(glh)) + return 1; +/* + * Record the new group. + */ + glh->group = group; + }; + return 0; +} + +/*....................................................................... + * Query the current history group. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * Output: + * return unsigned The group identifier. + */ +int _glh_get_group(GlHistory *glh) +{ + return glh ? glh->group : 0; +} + +/*....................................................................... + * Write a timestamp to a given stdio stream, in the format + * yyyymmddhhmmss + * + * Input: + * fp FILE * The stream to write to. + * timestamp time_t The timestamp to be written. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _glh_write_timestamp(FILE *fp, time_t timestamp) +{ + struct tm *t; /* THe broken-down calendar time */ +/* + * Get the calendar components corresponding to the given timestamp. + */ + if(timestamp < 0 || (t = localtime(×tamp)) == NULL) { + if(fprintf(fp, "?") < 0) + return 1; + return 0; + }; +/* + * Write the calendar time as yyyymmddhhmmss. + */ + if(fprintf(fp, "%04d%02d%02d%02d%02d%02d", t->tm_year + 1900, t->tm_mon + 1, + t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec) < 0) + return 1; + return 0; +} + +/*....................................................................... + * Read a timestamp from a string. + * + * Input: + * string char * The string to read from. + * Input/Output: + * endp char ** On output *endp will point to the next unprocessed + * character in string[]. + * timestamp time_t * The timestamp will be assigned to *t. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _glh_decode_timestamp(char *string, char **endp, time_t *timestamp) +{ + unsigned year,month,day,hour,min,sec; /* Calendar time components */ + struct tm t; +/* + * There are 14 characters in the date format yyyymmddhhmmss. + */ + enum {TSLEN=14}; + char timestr[TSLEN+1]; /* The timestamp part of the string */ +/* + * If the time wasn't available at the time that the line was recorded + * it will have been written as "?". Check for this before trying + * to read the timestamp. + */ + if(string[0] == '\?') { + *endp = string+1; + *timestamp = -1; + return 0; + }; +/* + * The timestamp is expected to be written in the form yyyymmddhhmmss. + */ + if(strlen(string) < TSLEN) { + *endp = string; + return 1; + }; +/* + * Copy the timestamp out of the string. + */ + strncpy(timestr, string, TSLEN); + timestr[TSLEN] = '\0'; +/* + * Decode the timestamp. + */ + if(sscanf(timestr, "%4u%2u%2u%2u%2u%2u", &year, &month, &day, &hour, &min, + &sec) != 6) { + *endp = string; + return 1; + }; +/* + * Advance the string pointer over the successfully read timestamp. + */ + *endp = string + TSLEN; +/* + * Copy the read values into a struct tm. + */ + t.tm_sec = sec; + t.tm_min = min; + t.tm_hour = hour; + t.tm_mday = day; + t.tm_wday = 0; + t.tm_yday = 0; + t.tm_mon = month - 1; + t.tm_year = year - 1900; + t.tm_isdst = -1; +/* + * Convert the contents of the struct tm to a time_t. + */ + *timestamp = mktime(&t); + return 0; +} + +/*....................................................................... + * Display the contents of the history list. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * fp FILE * The stdio stream to write to. + * fmt const char * A format string. This can contain arbitrary + * characters, which are written verbatim, plus + * any of the following format directives: + * %D - The date, like 2001-11-20 + * %T - The time of day, like 23:59:59 + * %N - The sequential entry number of the + * line in the history buffer. + * %G - The history group number of the line. + * %% - A literal % character. + * %H - The history line. + * all_groups int If true, display history lines from all + * history groups. Otherwise only display + * those of the current history group. + * max_lines int If max_lines is < 0, all available lines + * are displayed. Otherwise only the most + * recent max_lines lines will be displayed. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _glh_show_history(GlHistory *glh, FILE *fp, const char *fmt, + int all_groups, int max_lines) +{ + GlLineNode *node; /* The line being displayed */ + GlLineNode *oldest; /* The oldest line to display */ + enum {TSMAX=32}; /* The maximum length of the date and time string */ + char buffer[TSMAX+1]; /* The buffer in which to write the date and time */ + int idlen; /* The length of displayed ID strings */ + unsigned grpmax; /* The maximum group number in the buffer */ + int grplen; /* The number of characters needed to print grpmax */ +/* + * Check the arguments. + */ + if(!glh || !fp || !fmt) { + fprintf(stderr, "_glh_show_history: NULL argument(s).\n"); + return 1; + }; +/* + * Is history enabled? + */ + if(!glh->enable || !glh->list.head) + return 0; +/* + * Work out the length to display ID numbers, choosing the length of + * the biggest number in the buffer. Smaller numbers will be padded + * with leading zeroes if needed. + */ + sprintf(buffer, "%lu", (unsigned long) glh->list.tail->id); + idlen = strlen(buffer); +/* + * Find the largest group number. + */ + grpmax = 0; + for(node=glh->list.head; node; node=node->next) { + if(node->group > grpmax) + grpmax = node->group; + }; +/* + * Find out how many characters are needed to display the group number. + */ + sprintf(buffer, "%u", (unsigned) grpmax); + grplen = strlen(buffer); +/* + * Find the node that follows the oldest line to be displayed. + */ + if(max_lines < 0) { + oldest = glh->list.head; + } else if(max_lines==0) { + return 0; + } else { + for(oldest=glh->list.tail; oldest; oldest=oldest->prev) { + if((all_groups || oldest->group == glh->group) && --max_lines <= 0) + break; + }; +/* + * If the number of lines in the buffer doesn't exceed the specified + * maximum, start from the oldest line in the buffer. + */ + if(!oldest) + oldest = glh->list.head; + }; +/* + * List the history lines in increasing time order. + */ + for(node=oldest; node; node=node->next) { +/* + * Only display lines from the current history group, unless + * told otherwise. + */ + if(all_groups || node->group == glh->group) { + const char *fptr; /* A pointer into the format string */ + struct tm *t = NULL; /* The broken time version of the timestamp */ +/* + * Work out the calendar representation of the node timestamp. + */ + if(node->timestamp != (time_t) -1) + t = localtime(&node->timestamp); +/* + * Parse the format string. + */ + fptr = fmt; + while(*fptr) { +/* + * Search for the start of the next format directive or the end of the string. + */ + const char *start = fptr; + while(*fptr && *fptr != '%') + fptr++; +/* + * Display any literal characters that precede the located directive. + */ + if(fptr > start && fprintf(fp, "%.*s", (int) (fptr - start), start) < 0) + return 1; +/* + * Did we hit a new directive before the end of the line? + */ + if(*fptr) { +/* + * Obey the directive. Ignore unknown directives. + */ + switch(*++fptr) { + case 'D': /* Display the date */ + if(t && strftime(buffer, TSMAX, "%Y-%m-%d", t) != 0 && + fprintf(fp, "%s", buffer) < 0) + return 1; + break; + case 'T': /* Display the time of day */ + if(t && strftime(buffer, TSMAX, "%H:%M:%S", t) != 0 && + fprintf(fp, "%s", buffer) < 0) + return 1; + break; + case 'N': /* Display the sequential entry number */ + if(fprintf(fp, "%*lu", idlen, (unsigned long) node->id) < 0) + return 1; + break; + case 'G': + if(fprintf(fp, "%*u", grplen, (unsigned) node->group) < 0) + return 1; + break; + case 'H': /* Display the history line */ + if(fprintf(fp, "%s", glh->buffer + node->start) < 0) + return 1; + break; + case '%': /* A literal % symbol */ + if(fputc('%', fp) == EOF) + return 1; + break; + }; +/* + * Skip the directive. + */ + if(*fptr) + fptr++; + }; + }; + }; + }; + return 0; +} + +/*....................................................................... + * Change the size of the history buffer. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * bufsize size_t The number of bytes in the history buffer, or 0 + * to delete the buffer completely. + * Output: + * return int 0 - OK. + * 1 - Insufficient memory (the previous buffer + * will have been retained). No error message + * will be displayed. + */ +int _glh_resize_history(GlHistory *glh, size_t bufsize) +{ + GlLineNode *node; /* A line location node in the list of lines */ + GlLineNode *prev; /* The line location node preceding 'node' */ +/* + * Check the arguments. + */ + if(!glh) + return bufsize > 0; +/* + * If the new size doesn't differ from the existing size, do nothing. + */ + if(glh->buflen == bufsize) + return 0; +/* + * Cancel any ongoing search. + */ + (void) _glh_cancel_search(glh); +/* + * Create a wholly new buffer? + */ + if(glh->buflen == 0) { + glh->buffer = (char *) malloc(bufsize); + if(!glh->buffer) + return 1; + glh->buflen = bufsize; +/* + * Delete an existing buffer? + */ + } else if(bufsize == 0) { + _glh_clear_history(glh, 1); + free(glh->buffer); + glh->buffer = NULL; + glh->buflen = 0; +/* + * To get here, we must be shrinking or expanding from one + * finite size to another. + */ + } else { +/* + * If we are shrinking the size of the buffer, then we first need + * to discard the oldest lines that won't fit in the new buffer. + */ + if(bufsize < glh->buflen) { + size_t nbytes = 0; /* The number of bytes used in the new buffer */ + GlLineNode *oldest; /* The oldest node to be kept */ +/* + * Searching backwards from the youngest line, find the oldest + * line for which there will be sufficient room in the new buffer. + */ + for(oldest = glh->list.tail; + oldest && (nbytes += oldest->nchar) <= bufsize; + oldest = oldest->prev) + ; +/* + * We will have gone one node too far, unless we reached the oldest line + * without exceeding the target length. + */ + if(oldest) { + nbytes -= oldest->nchar; + oldest = oldest->next; + }; +/* + * Discard the nodes that can't be retained. + */ + while(glh->list.head && glh->list.head != oldest) + _glh_discard_node(glh, glh->list.head); +/* + * If we are increasing the size of the buffer, we need to reallocate + * the buffer before shifting the lines into their new positions. + */ + } else { + char *new_buffer = (char *) realloc(glh->buffer, bufsize); + if(!new_buffer) + return 1; + glh->buffer = new_buffer; + glh->buflen = bufsize; + }; +/* + * If there are any lines to be preserved, copy the block of lines + * that precedes the end of the existing buffer to what will be + * the end of the new buffer. + */ + if(glh->list.head) { + int shift; /* The number of bytes to shift lines in the buffer */ +/* + * Get the oldest line to be kept. + */ + GlLineNode *oldest = glh->list.head; +/* + * Count the number of characters that are used in the lines that + * precede the end of the current buffer (ie. not including those + * lines that have been wrapped to the start of the buffer). + */ + int n = 0; + for(node=oldest,prev=oldest->prev; node && node->start >= oldest->start; + prev=node, node=node->next) + n += node->nchar; +/* + * Move these bytes to the end of the resized buffer. + */ + memmove(glh->buffer + bufsize - n, glh->buffer + oldest->start, n); +/* + * Adjust the buffer pointers to reflect the new locations of the moved + * lines. + */ + shift = bufsize - n - oldest->start; + for(node=prev; node && node->start >= oldest->start; node=node->prev) + node->start += shift; + }; +/* + * Shrink the buffer? + */ + if(bufsize < glh->buflen) { + char *new_buffer = (char *) realloc(glh->buffer, bufsize); + if(new_buffer) + glh->buffer = new_buffer; + glh->buflen = bufsize; /* Mark it as shrunk, regardless of success */ + }; + }; + return 0; +} + +/*....................................................................... + * Set an upper limit to the number of lines that can be recorded in the + * history list, or remove a previously specified limit. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * max_lines int The maximum number of lines to allow, or -1 to + * cancel a previous limit and allow as many lines + * as will fit in the current history buffer size. + */ +void _glh_limit_history(GlHistory *glh, int max_lines) +{ + if(!glh) + return; +/* + * Apply a new limit? + */ + if(max_lines >= 0 && max_lines != glh->max_lines) { +/* + * Count successively older lines until we reach the start of the + * list, or until we have seen max_lines lines (at which point 'node' + * will be line number max_lines+1). + */ + int nline = 0; + GlLineNode *node; + for(node=glh->list.tail; node && ++nline <= max_lines; node=node->prev) + ; +/* + * Discard any lines that exceed the limit. + */ + if(node) { + GlLineNode *oldest = node->next; /* The oldest line to be kept */ +/* + * Delete nodes from the head of the list until we reach the node that + * is to be kept. + */ + while(glh->list.head && glh->list.head != oldest) + _glh_discard_node(glh, glh->list.head); + }; + }; +/* + * Record the new limit. + */ + glh->max_lines = max_lines; + return; +} + +/*....................................................................... + * Discard either all history, or the history associated with the current + * history group. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * all_groups int If true, clear all of the history. If false, + * clear only the stored lines associated with the + * currently selected history group. + */ +void _glh_clear_history(GlHistory *glh, int all_groups) +{ +/* + * Check the arguments. + */ + if(!glh) + return; +/* + * Cancel any ongoing search. + */ + (void) _glh_cancel_search(glh); +/* + * Delete all history lines regardless of group? + */ + if(all_groups) { + _rst_FreeList(glh->list.node_mem); + glh->list.head = glh->list.tail = NULL; + glh->nline = 0; + glh->id_node = NULL; +/* + * Just delete lines of the current group? + */ + } else { + GlLineNode *node; /* The line node being checked */ + GlLineNode *prev; /* The line node that precedes 'node' */ + GlLineNode *next; /* The line node that follows 'node' */ +/* + * Search out and delete the line nodes of the current group. + */ + for(node=glh->list.head; node; node=next) { +/* + * Keep a record of the following node before we delete the current + * node. + */ + next = node->next; +/* + * Discard this node? + */ + if(node->group == glh->group) + _glh_discard_node(glh, node); + }; +/* + * If there are any lines left, and we deleted any lines, there will + * be gaps in the buffer. These need to be removed. + */ + if(glh->list.head) { + int epos; /* The index of the last used element in the buffer */ +/* + * Find the line nearest the end of the buffer. + */ + GlLineNode *enode; + for(node=glh->list.head, prev=NULL; + node && node->start >= glh->list.head->start; + prev=node, node = node->next) + ; + enode = prev; +/* + * Move the end line to abutt the end of the buffer, and remove gaps + * between the lines that precede it. + */ + epos = glh->buflen; + for(node=enode; node; node=node->prev) { + int shift = epos - (node->start + node->nchar); + if(shift) { + memmove(glh->buffer + node->start + shift, + glh->buffer + node->start, node->nchar); + node->start += shift; + }; + epos = node->start; + }; +/* + * Move the first line in the buffer to the start of the buffer, and + * remove gaps between the lines that follow it. + */ + epos = 0; + for(node=enode ? enode->next : NULL; node; node=node->next) { + int shift = epos - node->start; + if(shift) { + memmove(glh->buffer + node->start + shift, + glh->buffer + node->start, node->nchar); + node->start += shift; + }; + epos = node->start + node->nchar; + }; + }; + }; + return; +} + +/*....................................................................... + * Temporarily enable or disable the history list. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * enable int If true, turn on the history mechanism. If + * false, disable it. + */ +void _glh_toggle_history(GlHistory *glh, int enable) +{ + if(glh) + glh->enable = enable; +} + +/*....................................................................... + * Remove a given line location node from the history list, and return + * it to the freelist. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * node GlLineNode * The node to be removed. This must be currently + * in the list who's head is glh->list.head, or + * be NULL. + */ +static void _glh_discard_node(GlHistory *glh, GlLineNode *node) +{ + if(node) { +/* + * Make the node that precedes the node being removed point + * to the one that follows it. + */ + if(node->prev) + node->prev->next = node->next; + else + glh->list.head = node->next; +/* + * Make the node that follows the node being removed point + * to the one that precedes it. + */ + if(node->next) + node->next->prev = node->prev; + else + glh->list.tail = node->prev; +/* + * If we are deleting the node that is marked as the start point of the + * last ID search, remove the cached starting point. + */ + if(node == glh->id_node) + glh->id_node = NULL; +/* + * Return the node to the free list. + */ + node = (GlLineNode *) _del_FreeListNode(glh->list.node_mem, node); +/* + * Decrement the count of the number of lines in the buffer. + */ + glh->nline--; + }; +} + +/*....................................................................... + * Lookup the details of a given history line, given its id. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * id GlLineID The sequential number of the line. + * Input/Output: + * line const char ** A pointer to the history line will be assigned + * to *line. + * group unsigned * The group membership of the line will be assigned + * to *group. + * timestamp time_t * The timestamp of the line will be assigned to + * *timestamp. + * Output: + * return int 0 - The requested line wasn't found. + * 1 - The line was found. + */ +int _glh_lookup_history(GlHistory *glh, GlhLineID id, const char **line, + unsigned *group, time_t *timestamp) +{ + GlLineNode *node; /* The located line location node */ +/* + * Check the arguments. + */ + if(!glh) + return 0; +/* + * Search for the line that has the specified ID. + */ + node = _glh_find_id(glh, (GlhLineID) id); +/* + * Not found? + */ + if(!node) + return 0; +/* + * Return the details of the line. + */ + if(line) + *line = glh->buffer + node->start; + if(group) + *group = node->group; + if(timestamp) + *timestamp = node->timestamp; + return 1; +} + +/*....................................................................... + * Lookup a node in the history list by its ID. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * id GlhLineID The ID of the line to be returned. + * Output: + * return GlLIneNode * The located node, or NULL if not found. + */ +static GlLineNode *_glh_find_id(GlHistory *glh, GlhLineID id) +{ + GlLineNode *node; /* The node being checked */ +/* + * Is history enabled? + */ + if(!glh->enable || !glh->list.head) + return NULL; +/* + * If possible, start at the end point of the last ID search. + * Otherwise start from the head of the list. + */ + node = glh->id_node; + if(!node) + node = glh->list.head; +/* + * Search forwards from 'node'? + */ + if(node->id < id) { + while(node && node->id != id) + node = node->next; + glh->id_node = node ? node : glh->list.tail; +/* + * Search backwards from 'node'? + */ + } else { + while(node && node->id != id) + node = node->prev; + glh->id_node = node ? node : glh->list.head; + }; +/* + * Return the located node (this will be NULL if the ID wasn't found). + */ + return node; +} + +/*....................................................................... + * Query the state of the history list. Note that any of the input/output + * pointers can be specified as NULL. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * Input/Output: + * enabled int * If history is enabled, *enabled will be + * set to 1. Otherwise it will be assigned 0. + * group unsigned * The current history group ID will be assigned + * to *group. + * max_lines int * The currently requested limit on the number + * of history lines in the list, or -1 if + * unlimited. + */ +void _glh_state_of_history(GlHistory *glh, int *enabled, unsigned *group, + int *max_lines) +{ + if(glh) { + if(enabled) + *enabled = glh->enable; + if(group) + *group = glh->group; + if(max_lines) + *max_lines = glh->max_lines; + }; +} + +/*....................................................................... + * Get the range of lines in the history buffer. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * Input/Output: + * oldest unsigned long * The sequential entry number of the oldest + * line in the history list will be assigned + * to *oldest, unless there are no lines, in + * which case 0 will be assigned. + * newest unsigned long * The sequential entry number of the newest + * line in the history list will be assigned + * to *newest, unless there are no lines, in + * which case 0 will be assigned. + * nlines int * The number of lines currently in the history + * list. + */ +void _glh_range_of_history(GlHistory *glh, unsigned long *oldest, + unsigned long *newest, int *nlines) +{ + if(glh) { + if(oldest) + *oldest = glh->list.head ? glh->list.head->id : 0; + if(newest) + *newest = glh->list.tail ? glh->list.tail->id : 0; + if(nlines) + *nlines = glh->nline; + }; +} + +/*....................................................................... + * Return the size of the history buffer and the amount of the + * buffer that is currently in use. + * + * Input: + * glh GlHistory * The input-line history maintenance object. + * Input/Output: + * buff_size size_t * The size of the history buffer (bytes). + * buff_used size_t * The amount of the history buffer that + * is currently occupied (bytes). + */ +void _glh_size_of_history(GlHistory *glh, size_t *buff_size, size_t *buff_used) +{ + if(glh) { + if(buff_size) + *buff_size = glh->buflen; +/* + * Determine the amount of buffer space that is currently occupied. + */ + if(buff_used) { + size_t used = 0; + GlLineNode *node; + for(node=glh->list.head; node; node=node->next) + used += node->nchar; + *buff_used = used; + }; + }; +} diff --git a/libtecla-1.4.1/history.h b/libtecla-1.4.1/history.h new file mode 100644 index 0000000..49671a4 --- /dev/null +++ b/libtecla-1.4.1/history.h @@ -0,0 +1,159 @@ +#ifndef history_h +#define history_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include /* FILE * */ + +/*----------------------------------------------------------------------- + * This module is used to record and traverse historical lines of user input. + */ + +typedef struct GlHistory GlHistory; + +/* + * Create a new history maintenance object. + */ +GlHistory *_new_GlHistory(size_t buflen); + +/* + * Delete a history maintenance object. + */ +GlHistory *_del_GlHistory(GlHistory *glh); + +int _glh_add_history(GlHistory *glh, const char *line, int force); + +int _glh_search_prefix(GlHistory *glh, const char *line, int prefix_len); + +char *_glh_find_backwards(GlHistory *glh, char *line, size_t dim); +char *_glh_find_forwards(GlHistory *glh, char *line, size_t dim); + +int _glh_cancel_search(GlHistory *glh); + +char *_glh_oldest_line(GlHistory *glh, char *line, size_t dim); +char *_glh_current_line(GlHistory *glh, char *line, size_t dim); + +/* + * Whenever a new line is added to the history buffer, it is given + * a unique ID, recorded in an object of the following type. + */ +typedef unsigned long GlhLineID; + +/* + * Query the id of a history line offset by a given number of lines from + * the one that is currently being recalled. If a recall session isn't + * in progress, or the offset points outside the history list, 0 is + * returned. + */ +GlhLineID _glh_line_id(GlHistory *glh, int offset); + +/* + * Recall a line by its history buffer ID. If the line is no longer + * in the buffer, or the specified id is zero, NULL is returned. + */ +char *_glh_recall_line(GlHistory *glh, GlhLineID id, char *line, size_t dim); + +/* + * Write the contents of the history buffer to a given file. Note that + * ~ and $ expansion are not performed on the filename. + */ +int _glh_save_history(GlHistory *glh, const char *filename, + const char *comment, int max_lines); + +/* + * Restore the contents of the history buffer from a given file. + * Note that ~ and $ expansion are not performed on the filename. + */ +int _glh_load_history(GlHistory *glh, const char *filename, const char *comment, + char *line, size_t dim); + +/* + * Set and query the current history group. + */ +int _glh_set_group(GlHistory *glh, unsigned group); +int _glh_get_group(GlHistory *glh); + +/* + * Display the contents of the history list to the specified stdio + * output group. + */ +int _glh_show_history(GlHistory *glh, FILE *fp, const char *fmt, + int all_groups, int max_lines); + +/* + * Change the size of the history buffer. + */ +int _glh_resize_history(GlHistory *glh, size_t bufsize); + +/* + * Set an upper limit to the number of lines that can be recorded in the + * history list, or remove a previously specified limit. + */ +void _glh_limit_history(GlHistory *glh, int max_lines); + +/* + * Discard either all history, or the history associated with the current + * history group. + */ +void _glh_clear_history(GlHistory *glh, int all_groups); + +/* + * Temporarily enable or disable the history facility. + */ +void _glh_toggle_history(GlHistory *glh, int enable); + +/* + * Lookup a history line by its sequential number of entry in the + * history buffer. + */ +int _glh_lookup_history(GlHistory *glh, GlhLineID id, const char **line, + unsigned *group, time_t *timestamp); + +/* + * Query the state of the history list. + */ +void _glh_state_of_history(GlHistory *glh, int *enabled, unsigned *group, + int *max_lines); + +/* + * Get the range of lines in the history buffer. + */ +void _glh_range_of_history(GlHistory *glh, unsigned long *oldest, + unsigned long *newest, int *nlines); + +/* + * Return the size of the history buffer and the amount of the + * buffer that is currently in use. + */ +void _glh_size_of_history(GlHistory *glh, size_t *buff_size, size_t *buff_used); + +#endif diff --git a/libtecla-1.4.1/homedir.c b/libtecla-1.4.1/homedir.c new file mode 100644 index 0000000..f2029b7 --- /dev/null +++ b/libtecla-1.4.1/homedir.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pathutil.h" +#include "homedir.h" + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +/* + * Use the reentrant POSIX threads versions of the password lookup functions? + */ +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L +#define THREAD_COMPATIBLE 1 +#endif + +/* + * Provide a password buffer size fallback in case the max size reported + * by sysconf() is said to be indeterminate. + */ +#define DEF_GETPW_R_SIZE_MAX 1024 + +/* + * The resources needed to lookup and record a home directory are + * maintained in objects of the following type. + */ +struct HomeDir { + char errmsg[ERRLEN+1]; /* Error-report buffer */ + char *buffer; /* A buffer for reading password entries and */ + /* directory paths. */ + int buflen; /* The allocated size of buffer[] */ +#ifdef THREAD_COMPATIBLE + struct passwd pwd; /* The password entry of a user */ +#endif +}; + +static const char *hd_getpwd(HomeDir *home); + +/*....................................................................... + * Create a new HomeDir object. + * + * Output: + * return HomeDir * The new object, or NULL on error. + */ +HomeDir *_new_HomeDir(void) +{ + HomeDir *home; /* The object to be returned */ + size_t pathlen; /* The estimated maximum size of a pathname */ +/* + * Allocate the container. + */ + home = (HomeDir *) malloc(sizeof(HomeDir)); + if(!home) { + fprintf(stderr, "_new_HomeDir: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_HomeDir(). + */ + home->errmsg[0] = '\0'; + home->buffer = NULL; + home->buflen = 0; +/* + * Allocate the buffer that is used by the reentrant POSIX password-entry + * lookup functions. + */ +#ifdef THREAD_COMPATIBLE +/* + * Get the length of the buffer needed by the reentrant version + * of getpwnam(). + */ +#ifndef _SC_GETPW_R_SIZE_MAX + home->buflen = DEF_GETPW_R_SIZE_MAX; +#else + errno = 0; + home->buflen = sysconf(_SC_GETPW_R_SIZE_MAX); +/* + * If the limit isn't available, substitute a suitably large fallback value. + */ + if(home->buflen < 0 || errno) + home->buflen = DEF_GETPW_R_SIZE_MAX; +#endif +#endif +/* + * If the existing buffer length requirement is too restrictive to record + * a pathname, increase its length. + */ + pathlen = _pu_pathname_dim(); + if(pathlen > home->buflen) + home->buflen = pathlen; +/* + * Allocate a work buffer. + */ + home->buffer = (char *) malloc(home->buflen); + if(!home->buffer) { + fprintf(stderr, "_new_HomeDir: Insufficient memory."); + return _del_HomeDir(home); + }; + return home; +} + +/*....................................................................... + * Delete a HomeDir object. + * + * Input: + * home HomeDir * The object to be deleted. + * Output: + * return HomeDir * The deleted object (always NULL). + */ +HomeDir *_del_HomeDir(HomeDir *home) +{ + if(home) { + if(home->buffer) + free(home->buffer); + free(home); + }; + return NULL; +} + +/*....................................................................... + * Lookup the home directory of a given user in the password file. + * + * Input: + * home HomeDir * The resources needed to lookup the home directory. + * user const char * The name of the user to lookup, or "" to lookup + * the home directory of the person running the + * program. + * Output: + * return const char * The home directory. If the library was compiled + * with threads, this string is part of the HomeDir + * object and will change on subsequent calls. If + * the library wasn't compiled to be reentrant, + * then the string is a pointer into a static string + * in the C library and will change not only on + * subsequent calls to this function, but also if + * any calls are made to the C library password + * file lookup functions. Thus to be safe, you should + * make a copy of this string before calling any + * other function that might do a password file + * lookup. + * + * On error, NULL is returned and a description + * of the error can be acquired by calling + * _hd_last_home_dir_error(). + */ +const char *_hd_lookup_home_dir(HomeDir *home, const char *user) +{ + const char *home_dir; /* A pointer to the home directory of the user */ +/* + * If no username has been specified, arrange to lookup the current + * user. + */ + int login_user = !user || *user=='\0'; +/* + * Check the arguments. + */ + if(!home) { + fprintf(stderr, "_hd_lookup_home_dir: NULL argument(s).\n"); + return NULL; + }; +/* + * Handle the ksh "~+". This expands to the absolute path of the + * current working directory. + */ + if (!login_user && strcmp(user, "+") == 0) { + home_dir = hd_getpwd(home); + if(!home_dir) { + strncpy(home->errmsg, "Cannot determine current directory.", ERRLEN); + home->errmsg[ERRLEN] = '\0'; + return NULL; + } + return home_dir; + }; +/* + * Look up the password entry of the user. + * First the POSIX threads version - this is painful! + */ +#ifdef THREAD_COMPATIBLE + { + struct passwd *ret; /* The returned pointer to pwd */ + int status; /* The return value of getpwnam_r() */ +/* + * Look up the password entry of the specified user. + */ + if(login_user) + status = getpwuid_r(geteuid(), &home->pwd, home->buffer, home->buflen, + &ret); + else + status = getpwnam_r(user, &home->pwd, home->buffer, home->buflen, &ret); + if(status || !ret) { + const char *fmt = "User '%.*s' doesn't exist."; + sprintf(home->errmsg, fmt, ERRLEN - strlen(fmt), user); + return NULL; + }; +/* + * Get a pointer to the string that holds the home directory. + */ + home_dir = home->pwd.pw_dir; + }; +/* + * Now the classic unix version. + */ +#else + { + struct passwd *pwd = login_user ? getpwuid(geteuid()) : getpwnam(user); + if(!pwd) { + const char *fmt = "User '%.*s' doesn't exist."; + sprintf(home->errmsg, fmt, ERRLEN - strlen(fmt), user); + return NULL; + }; +/* + * Get a pointer to the home directory. + */ + home_dir = pwd->pw_dir; + }; +#endif + return home_dir; +} + +/*....................................................................... + * Return a description of the last error that caused _hd_lookup_home_dir() + * to return NULL. + * + * Input: + * home HomeDir * The resources needed to record the home directory. + * Output: + * return char * The description of the last error. + */ +const char *_hd_last_home_dir_error(HomeDir *home) +{ + return home ? home->errmsg : "NULL HomeDir argument"; +} + +/*....................................................................... + * The _hd_scan_user_home_dirs() function calls a user-provided function + * for each username known by the system, passing the function both + * the name and the home directory of the user. + * + * Input: + * home HomeDir * The resource object for reading home + * directories. + * data void * Anonymous data to be passed to the + * callback function. + * callback_fn HOME_DIR_FN(*) The function to call for each user. + * Output: + * return int 0 - Successful completion. + * 1 - An error occurred. A description + * of the error can be obtained by + * calling _hd_last_home_dir_error(). + */ +int _hd_scan_user_home_dirs(HomeDir *home, void *data, HOME_DIR_FN(*callback_fn)) +{ + int waserr = 0; /* True after errors */ +/* + * Check the arguments. + */ + if(!home || !callback_fn) { + if(home) + strcpy(home->errmsg, + "_hd_scan_user_home_dirs: Missing callback function"); + return 1; + }; +/* + * There are no reentrant versions of getpwent() etc for scanning + * the password file, so disable username completion when the + * library is compiled to be reentrant. + */ +#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 199506L + { + struct passwd *pwd; /* The pointer to the latest password entry */ +/* + * Open the password file. + */ + setpwent(); +/* + * Read the contents of the password file, looking for usernames + * that start with the specified prefix, and adding them to the + * list of matches. + */ + while((pwd = getpwent()) != NULL && !waserr) + waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir, home->errmsg, + ERRLEN); +/* + * Close the password file. + */ + endpwent(); + }; +#endif +/* + * Under ksh ~+ stands for the absolute pathname of the current working + * directory. + */ + if (!waserr) { + const char *pwd = hd_getpwd(home); + if(pwd) { + waserr = callback_fn(data, "+", pwd, home->errmsg, ERRLEN); + } else { + waserr = 1; + strncpy(home->errmsg, "Cannot determine current directory.", ERRLEN); + home->errmsg[ERRLEN] = '\0'; + }; + }; + return waserr; +} + +/*....................................................................... + * Return the value of getenv("PWD") if this points to the current + * directory, or the return value of getcwd() otherwise. The reason for + * prefering PWD over getcwd() is that the former preserves the history + * of symbolic links that have been traversed to reach the current + * directory. This function is designed to provide the equivalent + * expansion of the ksh ~+ directive, which normally returns its value + * of PWD. + * + * Input: + * home HomeDir * The resource object for reading home directories. + * Output: + * return const char * A pointer to either home->buffer, where the + * pathname is recorded, the string returned by + * getenv("PWD"), or NULL on error. + */ +static const char *hd_getpwd(HomeDir *home) +{ +/* + * Get the absolute path of the current working directory. + */ + char *cwd = getcwd(home->buffer, home->buflen); +/* + * Some shells set PWD with the path of the current working directory. + * This will differ from cwd in that it won't have had symbolic links + * expanded. + */ + const char *pwd = getenv("PWD"); +/* + * If PWD was set, and it points to the same directory as cwd, return + * its value. Note that it won't be the same if the current shell or + * the current program has changed directories, after inheriting PWD + * from a parent shell. + */ + struct stat cwdstat, pwdstat; + if(pwd && cwd && stat(cwd, &cwdstat)==0 && stat(pwd, &pwdstat)==0 && + cwdstat.st_dev == pwdstat.st_dev && cwdstat.st_ino == pwdstat.st_ino) + return pwd; +/* + * Also return pwd if getcwd() failed, since it represents the best + * information that we have access to. + */ + if(!cwd) + return pwd; +/* + * In the absence of a valid PWD, return cwd. + */ + return cwd; +} diff --git a/libtecla-1.4.1/homedir.h b/libtecla-1.4.1/homedir.h new file mode 100644 index 0000000..5607802 --- /dev/null +++ b/libtecla-1.4.1/homedir.h @@ -0,0 +1,81 @@ +#ifndef homedir_h +#define homedir_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +typedef struct HomeDir HomeDir; + +/* + * The following constructor and destructor functions create and + * delete the resources needed to look up home directories. + */ +HomeDir *_new_HomeDir(void); +HomeDir *_del_HomeDir(HomeDir *home); + +/* + * Return the home directory of a specified user, or NULL if unknown. + */ +const char *_hd_lookup_home_dir(HomeDir *home, const char *user); + +/* + * Get the description of the that occured when _hd_lookup_home_dir() was + * last called. + */ +const char *_hd_last_home_dir_error(HomeDir *home); + +/* + * The _hd_scan_user_home_dirs() function calls a user-provided function + * for each username known by the system, passing the function both + * the name and the home directory of the user. + * + * The following macro can be used to declare both pointers and + * prototypes for the callback functions. The 'data' argument is + * a copy of the 'data' argument passed to _hd_scan_user_home_dirs() + * and is intended for the user of _hd_scan_user_home_dirs() to use + * to pass anonymous context data to the callback function. + * The username and home directories are passed to the callback function + * in the *usrnam and *homedir arguments respectively. + * To abort the scan, and have _hd_scan_user_home_dirs() return 1, the + * callback function can return 1. A description of up to maxerr + * characters before the terminating '\0', can be written to errmsg[]. + * This can then be examined by calling _hd_last_home_dir_error(). + * To indicate success and continue the scan, the callback function + * should return 0. _hd_scan_user_home_dirs() returns 0 on successful + * completion of the scan, or 1 if an error occurred or a call to the + * callback function returned 1. + */ +#define HOME_DIR_FN(fn) int (fn)(void *data, const char *usrnam, const char *homedir, char *errmsg, int maxerr) + +int _hd_scan_user_home_dirs(HomeDir *home, void *data, + HOME_DIR_FN(*callback_fn)); + +#endif diff --git a/libtecla-1.4.1/html/changes.html b/libtecla-1.4.1/html/changes.html new file mode 100644 index 0000000..b309a7b --- /dev/null +++ b/libtecla-1.4.1/html/changes.html @@ -0,0 +1,1495 @@ +The tecla library change log +
    +In the following log, modification dates are listed using the European
    +convention in which the day comes before the month (ie. DD/MM/YYYY).
    +The most recent modifications are listed first.
    +
    +25/05/2002 mcs@astro.caltech.edu  (based on suggestions by Paul Smith)
    +           pathutil.c
    +             Apparently, under QNX pathconf("/",_PC_PATH_MAX) returns
    +             EINVAL. At Paul's suggestion I have modified the code to
    +             silently substitute the existing MAX_PATHLEN_FALLBACK
    +             value if pathconf() returns an error of any kind.
    +           homedir.c
    +             Under QNX, sysconf(_SC_GETPW_R_SIZE_MAX) also apparently
    +             returns EINVAL, so as with pathconf() I modified the code
    +             to substitute a fallback default, rather than
    +             complaining and failing.
    +           enhance.c
    +             Paul told me that the inclusion of sys/termios.h was
    +             causing compilation of enhance.c to fail under QNX. This
    +             line is a bug.  The correct thing to do is include
    +             termios.h without a sub-directory prefix, as I was
    +             already doing futher up in the file, so I have just
    +             removed the errant include line.
    +
    +12/02/2002 mcs@astro.caltech.edu
    +           getline.c configure.in configure
    +             Mac OS X doesn't have a term.h or termcap.h, but it does
    +             define prototypes for tputs() and setupterm(), so the
    +             default prototypes that I was including if no headers
    +             where available, upset it. I've removed these prototypes.
    +             I also now conditionally include whichever is found of
    +             curses.h and ncurses/curses.h for both termcap and
    +             terminfo (before I wasn't including curses.h when
    +             termcap was selected).
    +
    +12/02/2002 mcs@astro.caltech.edu
    +           Updated version number to 1.4.1, ready for a micro
    +           release.
    +
    +12/02/2002 mcs@astro.caltech.edu
    +           html/index.html
    +             Added Mac OS X and Cygwin to the list of systems that
    +             can compile libtecla.
    +
    +12/02/2002 mcs@astro.caltech.edu
    +           getline.c
    +             Under Mac OS X, the tputs() callback function returns
    +             void, instead of the int return value used by other
    +             systems. This declaration is now used if both __MACH__
    +             and __APPLE__ are defined. Hopefully these are the
    +             correct system macros to check. Thanks for Stephan
    +             Fiedler for providing information on Mac OS X.
    +
    +11/02/2002 mcs@astro.caltech.edu
    +           configure.in configure getline.c
    +             Some systems don't have term.h, and others have it hidden
    +             in an ncurses sub-directory of the standard system include
    +             directory. If term.h can't be found, simply don't include
    +             it. If it is in an ncurses sub-directory, include
    +             ncurses/term.h instead of term.h.
    +
    +04/02/2002 mcs@astro.caltech.edu
    +           configure.in configure Makefile.in Makefile.rules
    +             Use ranlib on systems that need it (Mac OS X).  Also,
    +             make all components of the installation directories where
    +             needed, instead of assuming that they exist.
    +
    +04/02/2002 mcs@astro.caltech.edu
    +           getline.c
    +             When the tab completion binding was unbound from the tab
    +             key, hitting the tab key caused gl_get_line() to ring the
    +             bell instead of inserting a tab character. This is
    +             problematic when using the 'enhance' program with
    +             Jython, since tabs are important in Python. I have
    +             corrected this.
    +
    +10/12/2001 Version 1.4.0 released.
    +
    +10/12/2001 mcs@astro.caltech.edu
    +           getline.c
    +             If the TIOCGWINSZ ioctl doesn't work, as is the case when
    +             running in an emacs shell, leave the size unchanged, rather
    +             than returning a fatal error.
    +
    +07/12/2001 mcs@astro.caltech.edu
    +           configure.in configure
    +             Now that the configure version of CFLAGS is included in
    +             the makefile, I noticed that the optimization flags -g
    +             and -O2 had been added. It turns out that if CFLAGS isn't
    +             already set, the autoconf AC_PROG_CC macro initializes it
    +             with these two optimization flags. Since this would break
    +             backwards compatibility in embedded distributions that
    +             already use the OPT= makefile argument, and because
    +             turning debugging on needlessly bloats the library, I now
    +             make sure that CFLAGS is set before calling this macro.
    +
    +07/12/2001 mcs@astro.caltech.edu
    +           enhance.c
    +             Use argv[0] in error reports instead of using a
    +             hardcoded macro.
    +
    +07/12/2001 mcs@astro.caltech.edu
    +           getline.c
    +             The cut buffer wasn't being cleared after being
    +             used as a work buffer by gl_load_history().
    +
    +06/12/2001 mcs@astro.caltech.edu
    +           configure.in configure
    +             I removed my now redundant definition of SUN_TPUTS from
    +             CFLAGS. I also added "-I/usr/include" to CFLAGS under
    +             Solaris to prevent gcc from seeing conflicting versions
    +             of system header files in /usr/local/include.
    +
    +06/12/2001 Markus Gyger (logged here by mcs)
    +           Lots of files.
    +             Lots of corrections to misspellings and typos in the
    +             comments.
    +           getline.c
    +             Markus reverted a supposed fix that I added a day or two
    +             ago. I had incorrectly thought that in Solaris 8, Sun had
    +             finally brought their declaration of the callback
    +             function of tputs() into line with other systems, but it
    +             turned out that gcc was pulling in a GNU version of
    +             term.h from /usr/local/include, and this was what
    +             confused me.
    +
    +05/12/2001 mcs@astro.caltech.edu
    +           Makefile.in
    +             I added @CFLAGS@ to the CFLAGS assignment, so that
    +             if CFLAGS is set as an environment variable when
    +             configure is run, the corresponding make variable
    +             includes its values in the output makefile.
    +
    +05/12/2001 mcs@astro.caltech.edu
    +           getline.c libtecla.h libtecla.map man3/gl_get_line.3
    +           man3/gl_last_signal.3
    +             I added a function that programs can use to find out
    +             which signal caused gl_get_line() to return EINTR.
    +
    +05/12/2001 mcs@astro.caltech.edu
    +           getline.c
    +             When the newline action was triggered by a printable
    +             character, it failed to display that character. It now
    +             does. Also, extra control codes that I had added, to
    +             clear to the end of the display after the carriage return,
    +             but before displaying the prompt, were confusing expect
    +             scripts, so I have removed them. This step is now done
    +             instead in gl_redisplay() after displaying the full input
    +             line.
    +
    +05/12/2001 mcs@astro.caltech.edu
    +           getline.c man3/gl_get_line.3
    +             A user convinced me that continuing to invoke meta
    +             keybindings for meta characters that are printable is a
    +             bad idea, as is allowing users to ask to have setlocale()
    +             called behind the application's back. I have thus changed
    +             this. The setlocale configuration option has gone, and
    +             gl_get_line() is now completely 8-bit clean, by default.
    +             This means that if a meta character is printable, it is
    +             treated as a literal character, rather than a potential
    +             M-c binding.  Meta bindings can still be invoked via
    +             their Esc-c equivalents, and indeed most terminal
    +             emulators either output such escape pairs by default when
    +             the meta character is pressed, or can be configured to do
    +             so. I have documented how to configure xterm to do this,
    +             in the man page.
    +
    +03/12/2001 mcs@astro.caltech.edu
    +           getline.c man3/gl_get_line.3
    +             gl_get_line() by default now prints any 8-bit printable
    +             characters that don't match keybindings. Previously
    +             characters > 127 were only printed if preceded by the
    +             literal-next action.  Alternatively, by placing the
    +             command literal_if_printable in the tecla configuration
    +             file, all printable characters are treated as literal
    +             characters, even if they are bound to action functions.
    +
    +             For international users of programs written by
    +             programmers that weren't aware of the need to call
    +             setlocale() to support alternate character sets, the
    +             configuration file can now also contain the single-word
    +             command "setlocale", which tells gl_get_line() to remedy
    +             this.
    +
    +27/11/2001 mcs@astro.caltech.edu
    +           demo.c demo2.c enhance man3/gl_get_line.3
    +             All demos and programs now call setlocale(LC_CTYPE,"").
    +             This makes them support character sets of different
    +             locales, where specified with the LC_CTYPE, LC_ALL, or
    +             LANG environment variables. I also added this to the demo
    +             in the man page, and documented its effect.
    +
    +27/11/2001 mcs@astro.caltech.edu
    +           getline.c
    +             When displaying unsigned characters with values over
    +             127 literally, previously it was assumed that they would
    +             all be displayable. Now isprint() is consulted, and if it
    +             says that a character isn't printable, the character code
    +             is displayed in octal like \307. In non-C locales, some
    +             characters with values > 127 are displayable, and
    +             isprint() tells gl_get_line() which are and which aren't.
    +
    +27/11/2001 mcs@astro.caltech.edu
    +           getline.c pathutil.c history.c enhance.c demo2.c
    +             All arguments of the ctype.h character class functions
    +             are now cast to (int)(unsigned char). Previously they
    +             were cast to (int), which doesn't correctly conform to
    +             the requirements of the C standard, and could cause
    +             problems for characters with values > 127 on systems
    +             with signed char's.
    +
    +26/11/2001 mcs@astro.caltech.edu
    +           man3/enhance.3 man3/libtecla.3
    +             I started writing a man page for the enhance program.
    +
    +26/11/2001 mcs@astro.caltech.edu
    +           Makefile.in Makefile.rules INSTALL
    +             It is now possible to specify whether the demos and other
    +             programs are to be built, by overriding the default
    +             values of the DEMOS, PROGRAMS and PROGRAMS_R variables.
    +             I have also documented the BINDIR variable and the
    +             install_bin makefile target.
    +
    +22/11/2001 mcs@astro.caltech.edu
    +           getline.c libtecla.h libtecla.map man3/gl_get_line.3
    +           man3/gl_ignore_signal.3 man3/gl_trap_signal.3
    +             Signal handling has now been modified to be customizable.
    +             Signals that are trapped by default can be removed from
    +             the list of trapped signals, and signals that aren't
    +             currently trapped, can be added to the list. Applications
    +             can also specify the signal and terminal environments in
    +             which an application's signal handler is invoked, and
    +             what gl_get_line() does after the signal handler returns.
    +
    +13/11/2001 mcs@astro.caltech.edu
    +           getline.c man3/gl_get_line.3
    +             Added half-bright, reverse-video and blinking text to the
    +             available prompt formatting options.
    +           getline.c
    +             Removed ^O from the default VT100 sgr0 capability
    +             string.  Apparently it can cause problems with some
    +             terminal emulators, and we don't need it, since it turns
    +             off the alternative character set mode, which we don't
    +             use.
    +           getline.c
    +             gl_tigetstr() and gl_tgetstr() didn't guard against the
    +             error returns of tigetstr() and tgetstr() respectively.
    +             They now do.
    +
    +11/11/2001 mcs@astro.caltech.edu
    +           getline.c libtecla.h libtecla.map man3/gl_get_line.3
    +           man3/gl_prompt_style.3
    +             Although the default remains to display the prompt string
    +             literally, the new gl_prompt_style() function can be used
    +             to enable text attribute formatting directives in prompt
    +             strings, such as underlining, bold font, and highlighting
    +             directives.
    +
    +09/11/2001 mcs@astro.caltech.edu
    +           enhance.c Makefile.rules configure.in configure
    +             I added a new program to the distribution that allows one
    +             to run most third party programs with the tecla library
    +             providing command-line editing.
    +
    +08/11/2001 mcs@astro.caltech.edu
    +           libtecla.h getline.c man3/gl_get_line.3 history.c history.h
    +             I added a max_lines argument to gl_show_history() and
    +             _glh_show_history(). This can optionally be used to
    +             set a limit on the number of history lines displayed.
    +           libtecla.h getline.c man3/gl_get_line.3
    +             I added a new function called gl_replace_prompt(). This
    +             can be used by gl_get_line() callback functions to
    +             request that a new prompt be use when they return.
    +
    +06/11/2001 mcs@astro.caltech.edu
    +           getline.c man3/gl_get_line.3
    +             I implemented, bound and documented the list-history
    +             action, used for listing historical lines of the current
    +             history group.
    +           getline.c man3/gl_get_line.3 man3/gl_echo_mode.3
    +             I wrote functions to specify and query whether subsequent
    +             lines will be visible as they are being typed.
    +
    +28/10/2001 mcs@astro.caltech.edu
    +           getline.c man3/gl_get_line.3
    +             For those cases where a terminal provides its own
    +             high-level terminal editing facilities, you can now
    +             specify an edit-mode argument of 'none'. This disables
    +             all tecla key bindings, and by using canonical terminal
    +             input mode instead of raw input mode, editing is left up
    +             to the terminal driver.
    +
    +21/10/2001 mcs@astro.caltech.edu
    +           libtecla.h getline.c history.c history.h
    +           man3/gl_get_line.3 man3/gl_history_info.3
    +             I added the new gl_state_of_history(),
    +             gl_range_of_history() and gl_size_of_history()
    +             functions for querying information about the
    +             history list.
    +           history.c
    +             While testing the new gl_size_of_history()
    +             function, I noticed that when the history buffer
    +             wrapped, any location nodes of old lines between
    +             the most recent line and the end of the buffer
    +             weren't being removed. This could result in bogus
    +             entries appearing at the start of the history list.
    +             Now fixed.
    +
    +20/10/2001 mcs@astro.caltech.edu
    +
    +           libtecla.h getline.c history.c history.h
    +           man3/gl_get_line.3 man3/gl_lookup_history.3
    +             I added a function called gl_lookup_history(), that
    +             the application can use to lookup lines in the history
    +             list.
    +           libtecla.h getline.c history.c history.h man3/gl_get_line.3
    +             gl_show_history() now takes a format string argument
    +             to control how the line is displayed, and with what
    +             information. It also now provides the option of either
    +             displaying all history lines or just those of the
    +             current history group.
    +           getline.c man3/gl_get_line.3
    +             gl_get_line() only archives lines in the history buffer
    +             if the newline action was invoked by a newline or
    +             carriage return character.
    +
    +16/10/2001 mcs@astro.caltech.edu
    +
    +           history.c history.h getline.c libtecla.h libtecla.map
    +           man3/gl_get_line.3 man3/gl_resize_history.3
    +           man3/gl_limit_history.3 man3/gl_clear_history.3
    +           man3/gl_toggle_history.3
    +	     I added a number of miscellaneous history configuration
    +	     functions. You can now resize or delete the history
    +	     buffer, limit the number of lines that are allowed in the
    +	     buffer, clear either all history or just the history of
    +	     the current history group, and temporarily enable and
    +	     disable the history mechanism.
    +
    +13/10/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             tputs_fp is now only declared if using termcap or
    +             terminfo.
    +           getline.c libtecla.map man3/gl_get_line.3
    +           man3/gl_terminal_size.3
    +             I added a public gl_terminal_size() function for
    +             updating and querying the current size of the terminal.
    +           update_version configure.in libtecla.h
    +             A user noted that on systems where the configure script
    +             couldn't be used, it was inconvenient to have the version
    +             number macros set by the configure script, so they are
    +             now specified in libtecla.h. To reduce the likelihood
    +             that the various files where the version number now
    +             appears might get out of sync, I have written the
    +             update_version script, which changes the version number
    +             in all of these files to a given value.
    +
    +01/10/2001 mcs@astro.caltech.edu
    +
    +           getline.c history.c history.h man3/gl_get_line.3
    +             I added a max_lines argument to gl_save_history(), to
    +             allow people to optionally place a ceiling on the number
    +             of history lines saved. Specifying this as -1 sets the
    +             ceiling to infinity.
    +
    +01/10/2001 mcs@astro.caltech.edu
    +
    +           configure.in configure
    +             Under digital unix, getline wouldn't compile with
    +             _POSIX_C_SOURCE set, due to type definitions needed by
    +             select being excluded by this flag. Defining the
    +             _OSF_SOURCE macro as well on this system, resolved this.
    +
    +30/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c libtecla.h history.c history.h man3/gl_get_line.3
    +           man3/gl_group_history.3
    +             I implemented history streams. History streams
    +             effectively allow multiple history lists to be stored in
    +             a single history buffer. Lines in the buffer are tagged
    +             with the current stream identification number, and
    +             lookups only consider lines that are marked with the
    +             current stream identifier.
    +           getline.c libtecla.h history.c history.h man3/gl_get_line.3
    +           man3/gl_show_history.3
    +             The new gl_show_history function displays the current
    +             history to a given stdio output stream.
    +
    +29/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             Previously new_GetLine() installed a persistent signal
    +             handler to be sure to catch the SIGWINCH (terminal size
    +             change) signal between calls to gl_get_line(). This had
    +             the drawback that if multiple GetLine objects were
    +             created, only the first GetLine object used after the
    +             signal was received, would see the signal and adapt to
    +             the new terminal size. Instead of this, a signal handler
    +             for sigwinch is only installed while gl_get_line() is
    +             running, and just after installing this handler,
    +             gl_get_line() checks for terminal size changes that
    +             might have occurred while the signal handler wasn't
    +             installed.
    +           getline.c
    +             Dynamically allocated copies of capability strings looked
    +             up in the terminfo or termcap databases are now made, so
    +             that calls to setupterm() etc for one GetLine object
    +             don't get trashed when another GetLine object calls
    +             setupterm() etc. It is now safe to allocate and use
    +             multiple GetLine objects, albeit only within a single
    +             thread.
    +           
    +28/09/2001 mcs@astro.caltech.edu
    +
    +           version.c Makefile.rules
    +             I added a function for querying the version number of
    +             the library.
    +
    +26/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c man3/gl_get_line.3
    +             I added the new gl_watch_fd() function, which allows
    +             applications to register callback functions to be invoked
    +             when activity is seen on arbitrary file descriptors while
    +             gl_get_line() is awaiting keyboard input from the user.
    +
    +           keytab.c
    +             If a request is received to delete a non-existent
    +             binding, which happens to be an ambiguous prefix of other
    +             bindings no complaint is now generated about it being
    +             ambiguous.
    +
    +23/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c history.c history.h man3/gl_get_line.3
    +           libtecla.map demo.c
    +             I added new public functions for saving and restoring the
    +             contents of the history list. The demo program now uses
    +             these functions to load and save history in ~/.demo_history.
    +
    +23/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             On trying the demo for the first time on a KDE konsole
    +             terminal, I discovered that the default M-O binding
    +             to repeat history was hiding the arrow keys, which are
    +             M-OA etc. I have removed this binding. The M-o (ie the
    +             lower case version of this), is still bound.
    +
    +18/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c man3/gl_get_line.3 libtecla.map
    +             Automatic reading of ~/.teclarc is now postponed until
    +             the first call to gl_get_line(), to give the application
    +             the chance to specify alternative configuration sources
    +             with the new function gl_configure_getline(). The latter
    +             function allows configuration to be done with a string, a
    +             specified application-specific file, and/or a specified
    +             user-specific file. I also added a read-init-files action
    +             function, for re-reading the configuration files, if any.
    +             This is by default bound to ^X^R. This is all documented
    +             in gl_get_line.3.
    +
    +08/09/2001 mcs@astro.caltech.edu
    +
    +           getline.c man3/gl_get_line.3
    +             It is now possible to bind actions to key-sequences
    +             that start with printable characters. Previously
    +             keysequences were required to start with meta or control
    +             characters. This is documented in gl_get_line.3.
    +
    +           getline.c man3/gl_get_line.3
    +             A customized completion function can now arrange for
    +             gl_get_line() to return the current input line whenever a
    +             successful completion has been made. This is signalled by
    +             setting the last character of the optional continuation
    +             suffix to a newline character. This is documented in
    +             gl_get_line.3.
    +
    +05/07/2001 Bug reported by Mike MacFaden, fixed by mcs
    +
    +           configure.in
    +             There was a bug in the configure script that only
    +             revealed itself on systems without termcap but not
    +             terminfo (eg. NetBSD). I traced the bug back to a lack of
    +             sufficient quoting of multi-line m4 macro arguments in
    +             configure.in, and have now fixed this and recreated the
    +             configure script.
    +
    +05/07/2001 Bug reported and patched by Mike MacFaden (patch modified
    +           by mcs to match original intentions).
    +
    +           getline.c
    +             getline.c wouldn't compile when termcap was selected as
    +             the terminal information database. setupterm() was being
    +             passed a non-existent variable, in place of the term[]
    +             argument of gl_control_strings(). Also if
    +             gl_change_terminal() is called with term==NULL, "ansi"
    +             is now substituted.
    +
    +02/07/2001 Version 1.3.3 released.
    +
    +27/06/2001 mcs@astro.caltech.edu
    +
    +           getline.c expand.c cplmatch.c
    +             Added checks to fprintf() statements that write to the
    +             terminal.
    +           getline.c
    +             Move the cursor to the end of the line before suspending,
    +             so that the cursor doesn't get left in the middle of the
    +             input line.
    +           Makefile.in
    +             On systems that don't support shared libraries, the
    +             distclean target of make deleted libtecla.h. This has
    +             now been fixed.
    +           getline.c
    +             gl_change_terminal() was being called by gl_change_editor(),
    +             with the unwanted side effect that raw terminal modes were
    +             stored as those to be restored later, if called by an
    +             action function. gl_change_terminal() was being called in
    +             this case to re-establish terminal-specific key bindings,
    +             so I have just split this part of the function out into
    +             a separate function for both gl_change_editor() and
    +             gl_change_terminal() to call.
    +
    +12/06/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             Signal handling has been improved. Many more signals are
    +             now trapped, and instead of using a simple flag set by a
    +             signal handler, race conditions are avoided by blocking
    +             signals during most of the gl_get_line() code, and
    +             unblocking them via calls to sigsetjmp(), just before
    +             attempting to read each new character from the user.
    +             The matching use of siglongjmp() in the signal
    +             handlers ensures that signals are reblocked correctly
    +             before they are handled. In most cases, signals cause
    +             gl_get_line() to restore the terminal modes and signal
    +             handlers of the calling application, then resend the
    +             signal to the application. In the case of SIGINT, SIGHUP,
    +             SIGPIPE, and SIGQUIT, if the process still exists after
    +             the signals are resent, gl_get_line() immediately returns
    +             with appropriate values assigned to errno. If SIGTSTP,
    +             SIGTTIN or SIGTTOU signals are received, the process is
    +             suspended. If any other signal is received, and the
    +             process continues to exist after the signal is resent to
    +             the calling application, line input is resumed after the
    +             terminal is put back into raw mode, the gl_get_line()
    +             signal handling is restored, and the input line redrawn.
    +           man/gl_get_line(3)
    +             I added a SIGNAL HANDLING section to the gl_get_line()
    +             man page, describing the new signal handling features.
    +
    +21/05/2001 Version 1.3.2 released.
    +
    +21/05/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             When vi-replace-char was used to replace the character at
    +             the end of the line, it left the cursor one character to
    +             its right instead of on top of it. Now rememdied.
    +           getline.c
    +             When undoing, to properly emulate vi, the cursor is now
    +             left at the leftmost of the saved and current cursor
    +             positions.
    +           getline.c man3/gl_get_line.3
    +             Implemented find-parenthesis (%), delete-to-paren (M-d%),
    +             vi-change-to-paren (M-c%), copy-to-paren (M-y%).
    +           cplfile.c pcache.c
    +             In three places I was comparing the last argument of
    +             strncmp() to zero instead of the return value of
    +             strncmp().
    +
    +20/05/2001 mcs@astro.caltech.edu
    +
    +           getline.c man3/gl_get_line.3
    +             Implemented and documented the vi-repeat-change action,
    +             bound to the period key. This repeats the last action
    +             that modified the input line.
    +
    +19/05/2001 mcs@astro.caltech.edu
    +
    +           man3/gl_get_line.3
    +             I documented the new action functions and bindings
    +             provided by Tim Eliseo, plus the ring-bell action and
    +             the new "nobeep" configuration option.
    +           getline.c
    +             I modified gl_change_editor() to remove and reinstate the
    +             terminal settings as well as the default bindings, since
    +             these have editor-specific differences. I also modified
    +             it to not abort if a key-sequence can't be bound for some
    +             reason. This allows the new vi-mode and emacs-mode
    +             bindings to be used safely.
    +           getline.c
    +             When the line was re-displayed on receipt of a SIGWINCH
    +             signal, the result wasn't visible until the next
    +             character was typed, since a call to fflush() was needed.
    +             gl_redisplay_line() now calls gl_flush_output() to remedy
    +             this.
    +
    +17/05/2001 mcs@astro.catlech.edu
    +
    +           getline.c
    +             Under Linux, calling fflush(gl->output_fd) hangs if
    +             terminal output has been suspended with ^S. With the
    +             tecla library taking responsability for reading the stop
    +             and start characters this was a problem, because once
    +             hung in fflush(), the keyboard input loop wasn't entered,
    +             so the user couldn't type the start character to resume
    +             output.  To remedy this, I now have the terminal process
    +             these characters, rather than the library.
    +
    +12/05/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             The literal-next action is now implemented as a single
    +             function which reads the next character itself.
    +             Previously it just set a flag which effected the
    +             interpretation of the next character read by the input
    +             loop.
    +           getline.c
    +             Added a ring-bell action function. This is currently
    +             unbound to any key by default, but it is used internally,
    +             and can be used by users that want to disable any of the
    +             default key-bindings.
    +
    +12/05/2001 Tim Eliseo    (logged here by mcs)
    +
    +           getline.c
    +             Don't reset gl->number until after calling an action
    +             function. By looking at whether gl->number is <0 or
    +             not, action functions can then tell whether the count
    +             that they were passed was explicitly specified by the
    +             user, as opposed to being defaulted to 1.
    +           getline.c
    +             In vi, the position at which input mode is entered
    +             acts as a barrier to backward motion for the few
    +             backward moving actions that are enabled in input mode.
    +             Tim added this barrier to getline.
    +           getline.c
    +             In gl_get_line() after reading an input line, or
    +             having the read aborted by a signal, the sig_atomic_t
    +             gl_pending_signal was being compared to zero instead
    +             of -1 to see if no signals had been received.
    +             gl_get_line() will thus have been calling raise(-1),
    +             which luckily didn't seem to do anything. Tim also
    +             arranged for errno to be set to EINTR when a signal
    +             aborts gl_get_line().
    +           getline.c
    +             The test in gl_add_char_to_line() for detecting
    +             when overwriting a character with a wider character,
    +             had a < where it needed a >. Overwriting with a wider
    +             character thus overwrote trailing characters. Tim also
    +             removed a redundant copy of the character into the
    +             line buffer.
    +           getline.c
    +             gl_cursor_left() and gl->cursor_right() were executing
    +             a lot of redundant code, when the existing call to the
    +             recently added gl_place_cursor() function, does all that
    +             is necessary.
    +           getline.c
    +             Remove redundant code from backward_kill_line() by
    +             re-implimenting in terms of gl_place_cursor() and
    +             gl_delete_chars().
    +           getline.c
    +             gl_forward_delete_char() now records characters in cut
    +             buffer when in vi command mode.
    +           getline.c
    +             In vi mode gl_backward_delete_char() now only deletes
    +             up to the point at which input mode was entered. Also
    +             gl_delete_chars() restores from the undo buffer when
    +             deleting in vi insert mode.
    +           getline.c
    +             Added action functions, vi-delete-goto-column,
    +             vi-change-to-bol, vi-change-line, emacs-mode, vi-mode,
    +             vi-forward-change-find, vi-backward-change-find,
    +             vi-forward-change-to, vi-backward-change-to,
    +             vi-change-goto-col, forward-delete-find, backward-delete-find,
    +             forward-delete-to, backward-delete-to,
    +             delete-refind, delete-invert-refind, forward-copy-find,
    +             backward-copy-find, forward-copy-to, backward-copy-to
    +             copy-goto-column, copy-rest-of-line, copy-to-bol, copy-line,
    +             history-re-search-forward, history-re-search-backward.
    +
    +06/05/2001 Version 1.3.1 released.
    +
    +03/05/2001 mcs@astro.caltech.edu
    +
    +           configure.in
    +             Old versions of GNU ld don't accept version scripts.
    +             Under Linux I thus added a test to try out ld with
    +             the --version-script argument to see if it works.
    +             If not, version scripts aren't used.
    +           configure.in
    +             My test for versions of Solaris earlier than 7
    +             failed when confronted by a three figure version
    +             number (2.5.1). Fixed.
    +
    +30/04/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             In vi mode, history-search-backward and
    +             history-search-forward weren't doing anything when
    +             invoked at the start of an empty line, whereas
    +             they should have acted like up-history and down-history.
    +           Makefile.in Makefile.rules
    +             When shared libraries are being created, the build
    +             procedure now arranges for any alternate library
    +             links to be created as well, before linking the
    +             demos. Without this the demos always linked to the
    +             static libraries (which was perfectly ok, but wasn't a
    +             good example).
    +           Makefile.in Makefile.rules
    +             On systems on which shared libraries were being created,
    +             if there were no alternate list of names, make would
    +             abort due to a Bourne shell 'for' statement that didn't
    +             have any arguments. Currently there are no systems who's
    +             shared library configurations would trigger this
    +             problem.
    +           Makefile.rules
    +             The demos now relink to take account of changes to the
    +             library.
    +           configure.in configure
    +             When determining whether the reentrant version of the
    +             library should be compiled by default, the configure
    +             script now attempts to compile a dummy program that
    +             includes all of the appropriate system headers and
    +             defines _POSIX_C_SOURCE. This should now be a robust test
    +             on systems which use C macros to alias these function
    +             names to other internal functions.
    +           configure.in
    +             Under Solaris 2.6 and earlier, the curses library is in
    +             /usr/ccs/lib. Gcc wasn't finding this. In addition to
    +             remedying this, I had to remove "-z text" from
    +             LINK_SHARED under Solaris to get it to successfully
    +             compile the shared library against the static curses
    +             library.
    +           configure.in
    +             Under Linux the -soname directive was being used
    +             incorrectly, citing the fully qualified name of the
    +             library instead of its major version alias. This will
    +             unfortunately mean that binaries linked with the 1.2.3
    +             and 1.2.4 versions of the shared library won't use
    +             later versions of the library unless relinked.
    +
    +30/04/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             In gl_get_input_line(), don't redundantly copy the
    +             start_line if start_line == gl->line.
    +
    +30/04/2001 Version 1.3.0 released.
    +
    +28/04/2001 mcs@astro.caltech.edu
    +
    +           configure.in
    +             I removed the --no-undefined directive from the Linux
    +             LINK_SHARED command. After recent patches to our RedHat
    +             7.0 systems ld started reporting some internal symbols of
    +             libc as being undefined.  Using nm on libc indicated that
    +             the offending symbols are indeed defined, albeit as
    +             "common" symbols, so there appears to be a bug in
    +             RedHat's ld. Removing this flag allows the tecla shared
    +             library to compile, and programs appear to function fine.
    +           man3/gl_get_line.3
    +             The default key-sequence used to invoke the
    +             read-from-file action was incorrectly cited as ^Xi
    +             instead of ^X^F.
    +
    +26/04/2001 mcs@astro.caltech.edu
    +
    +           getline.c man3/gl_get_line.3
    +             A new vi-style editing mode was added. This involved
    +             adding many new action functions, adding support for
    +             specifying editing modes in users' ~/.teclarc files,
    +             writing a higher level cursor motion function to support
    +             the different line-end bounds required in vi command
    +             mode, and a few small changes to support the fact that vi
    +             has two modes, input mode and command mode with different
    +             bindings.
    +
    +             When vi editing mode is enabled, any binding that starts
    +             with an escape or a meta character, is interpreted as a
    +             command-mode binding, and switches the library to vi
    +             command mode if not already in that mode. Once in command
    +             mode the first character of all keysequences entered
    +             until input mode is re-enabled, are quietly coerced to
    +             meta characters before being looked up in the key-binding
    +             table. So, for example, in the key-binding table, the
    +             standard vi command-mode 'w' key, which moves the cursor
    +             one word to the right, is represented by M-w. This
    +             emulates vi's dual sets of bindings in a natural way
    +             without needing large changes to the library, or new
    +             binding syntaxes. Since cursor keys normally emit
    +             keysequences which start with escape, it also does
    +             something sensible when a cursor key is pressed during
    +             input mode (unlike true vi, which gets upset).
    +
    +             I also added a ^Xg binding for the new list-glob action
    +             to both the emacs and vi key-binding tables. This lists
    +             the files that match the wild-card expression that
    +             precedes it on the command line.
    +
    +             The function that reads in ~/.teclarc used to tell
    +             new_GetLine() to abort if it encountered anything that it
    +             didn't understand in this file. It now just reports an
    +             error and continues onto the next line.
    +           Makefile.in:
    +             When passing LIBS=$(LIBS) to recursive invokations of
    +             make, quotes weren't included around the $(LIBS) part.
    +             This would cause problems if LIBS ever contained more
    +             than one word (with the supplied configure script this
    +             doesn't happen currently). I added these quotes.
    +           expand.c man3/ef_expand_file.3:
    +             I wrote a new public function called ef_list_expansions(),
    +             to list the matching filenames returned by
    +             ef_expand_file().
    +
    +             I also fixed the example in the man page, which cited
    +             exp->file instead of exp->files, and changed the
    +             dangerous name 'exp' with 'expn'.
    +           keytab.c:
    +             Key-binding tables start with 100 elements, and are
    +             supposedly incremented in size by 100 elements whenever
    +             the a table runs out of space. The realloc arguments to
    +             do this were wrong. This would have caused problems if
    +             anybody added a lot of personal bindings in their
    +             ~/.teclarc file. I only noticed it because the number of
    +             key bindings needed by the new vi mode exceeded this
    +             number.
    +           libtecla.map
    +             ef_expand_file() is now reported as having been added in
    +             the upcoming 1.3.0 release.
    +
    +25/03/2001 Markus Gyger  (logged here by mcs)
    +
    +           Makefile.in:
    +             Make symbolic links to alternative shared library names
    +             relative instead of absolute.
    +           Makefile.rules:
    +             The HP-UX libtecla.map.opt file should be made in the
    +             compilation directory, to allow the source code directory
    +             to be on a readonly filesystem.
    +           cplmatch.c demo2.c history.c pcache.c
    +             To allow the library to be compiled with a C++ compiler,
    +             without generating warnings, a few casts were added where
    +             void* return values were being assigned directly to
    +             none void* pointer variables.
    +
    +25/03/2001 mcs@astro.caltech.edu
    +
    +           libtecla.map:
    +             Added comment header to explain the purpose of the file.
    +             Also added cpl_init_FileArgs to the list of exported
    +             symbols. This symbol is deprecated, and no longer
    +             documented, but for backwards compatibility, it should
    +             still be exported.
    +           configure:
    +             I had forgotten to run autoconf before releasing version
    +             1.2.4, so I have just belatedly done so.  This enables
    +             Markus' changes to "configure.in" documented previously,
    +             (see 17/03/2001).
    +
    +20/03/2001 John Levon   (logged here by mcs)
    +
    +           libtecla.h
    +             A couple of the function prototypes in libtecla.h have
    +             (FILE *) argument declarations, which means that stdio.h
    +             needs to be included. The header file should be self
    +             contained, so libtecla.h now includes stdio.h.
    +
    +18/03/2001 Version 1.2.4 released.
    +
    +           README html/index.html configure.in
    +             Incremented minor version from 3 to 4.
    +
    +18/03/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             The fix for the end-of-line problem that I released a
    +             couple of weeks ago, only worked for the first line,
    +             because I was handling this case when the cursor position
    +             was equal to the last column, rather than when the cursor
    +             position modulo ncolumn was zero.
    +           Makefile.in Makefile.rules
    +             The demos are now made by default, their rules now being
    +             int Makefile.rules instead of Makefile.in.
    +           INSTALL
    +             I documented how to compile the library in a different
    +             directory than the distribution directory.
    +             I also documented features designed to facilitate
    +             configuring and building the library as part of another
    +             package.
    +
    +17/03/2001 Markus Gyger (logged here by mcs)
    +
    +           getline.c
    +             Until now cursor motions were done one at a time. Markus
    +             has added code to make use the of the terminfo capability
    +             that moves the cursor by more than one position at a
    +             time. This greatly improves performance when editing near
    +             the start of long lines.
    +           getline.c
    +             To further improve performance, Markus switched from
    +             writing one character at a time to the terminal, using
    +             the write() system call, to using C buffered output
    +             streams. The output buffer is only flushed when
    +             necessary.
    +           Makefile.rules Makefile.in configure.in
    +             Added support for compiling for different architectures
    +             in different directories. Simply create another directory
    +             and run the configure script located in the original
    +             directory.
    +           Makefile.in configure.in libtecla.map
    +             Under Solaris, Linux and HP-UX, symbols that are to be
    +             exported by tecla shared libraries are explicitly specified
    +             via symbol map files. Only publicly documented functions
    +             are thus visible to applications.
    +           configure.in
    +             When linking shared libraries under Solaris SPARC,
    +             registers that are reserved for applications are marked
    +             as off limits to the library, using -xregs=no%appl when
    +             compiling with Sun cc, or -mno-app-regs when compiling
    +             with gcc. Also removed -z redlocsym for Solaris, which
    +             caused problems under some releases of ld.
    +           homedir.c  (after minor changes by mcs)
    +             Under ksh, ~+ expands to the current value of the ksh
    +             PWD environment variable, which contains the path of
    +             the current working directory, including any symbolic
    +             links that were traversed to get there. The special
    +             username "+" is now treated equally by tecla, except
    +             that it substitutes the return value of getcwd() if PWD
    +             either isn't set, or if it points at a different
    +             directory than that reported by getcwd().
    +
    +08/03/2001 Version 1.2.3 released.
    +
    +08/03/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             On compiling the library under HP-UX for the first time
    +             I encountered and fixed a couple of bugs:
    +
    +             1. On all systems except Solaris, the callback function
    +                required by tputs() takes an int argument for the
    +                character that is to be printed. Under Solaris it
    +                takes a char argument. The callback function was
    +                passing this argument, regardless of type, to write(),
    +                which wrote the first byte of the argument.  This was
    +                fine under Solaris and under little-endian systems,
    +                because the first byte contained the character to be
    +                written, but on big-endian systems, it always wrote
    +                the zero byte at the other end of the word. As a
    +                result, no control characters were being written to
    +                the terminal.
    +             2. While attempting to start a newline after the user hit
    +                enter, the library was outputting the control sequence
    +                for moving the cursor down, instead of the newline
    +                character. On many systems the control sequence for
    +                moving the cursor down happends to be a newline
    +                character, but under HP-UX it isn't. The result was
    +                that no new line was being started under HP-UX.
    +
    +04/03/2001 mcs@astro.caltech.edu
    +
    +           configure.in Makefile.in Makefile.stub configure config.guess
    +           config.sub Makefile.rules install-sh PORTING README INSTALL
    +             Configuration and compilation of the library is now
    +             performed with the help of an autoconf configure
    +             script. In addition to relieving the user of the need to
    +             edit the Makefile, this also allows automatic compilation
    +             of the reentrant version of the library on platforms that
    +             can handle it, along with the creation of shared
    +             libraries where configured. On systems that aren't known
    +             to the configure script, just the static tecla library is
    +             compiled. This is currently the case on all systems
    +             except Linux, Solaris and HP-UX. In the hope that
    +             installers will provide specific conigurations for other
    +             systems, the configure.in script is heavily commented,
    +             and instructions on how to use are included in a new
    +             PORTING file.
    +
    +24/02/2001 Version 1.2b released.
    +
    +22/02/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             It turns out that most terminals, but not all, on writing
    +             a character in the rightmost column, don't wrap the
    +             cursor onto the next line until the next character is
    +             output. This library wasn't aware of this and thus if one
    +             tried to reposition the cursor from the last column,
    +             gl_get_line() thought that it was moving relative to a
    +             point on the next line, and thus moved the cursor up a
    +             line. The fix was to write one extra character when in
    +             the last column to force the cursor onto the next line,
    +             then backup the cursor to the start of the new line.
    +           getline.c
    +             On terminal initialization, the dynamic LINES and COLUMNS
    +             environment variables were ignored unless
    +             terminfo/termcap didn't return sensible dimensions. In
    +             practice, when present they should override the static
    +             versions in the terminfo/termcap databases. This is the
    +             new behavior. In reality this probably won't have caused
    +             many problems, because a SIGWINCH signal which informs of
    +             terminal size changes is sent when the terminal is
    +             opened, so the dimensions established during
    +             initialization quickly get updated on most systems.
    +
    +18/02/2001 Version 1.2a released.
    +
    +18/02/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             Three months ago I moved the point at which termios.h
    +             was included in getline.c. Unfortunately, I didn't notice
    +             that this moved it to after the test for TIOCGWINSZ being
    +             defined. This resulted in SIGWINCH signals not being
    +             trapped for, and thus terminal size changes went
    +             unnoticed. I have now moved the test to after the 
    +             inclusion of termios.h.
    +
    +12/02/2001 Markus Gyger     (described here by mcs)
    +
    +           man3/pca_lookup_file.3 man3/gl_get_line.3
    +           man3/ef_expand_file.3 man3/cpl_complete_word.3
    +             In the 1.2 release of the library, all functions in the
    +             library were given man pages. Most of these simply
    +             include one of the above 4 man pages, which describe the
    +             functions while describing the modules that they are in.
    +             Markus added all of these function names to the lists in
    +             the "NAME" headers of the respective man pages.
    +             Previously only the primary function of each module was
    +             named there.
    +
    +11/02/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             On entering a line that wrapped over two or more
    +             terminal, if the user pressed enter when the cursor
    +             wasn't on the last of the wrapped lines, the text of the
    +             wrapped lines that followed it got mixed up with the next
    +             line written by the application, or the next input
    +             line. Somehow this slipped through the cracks and wasn't
    +             noticed until now. Anyway, it is fixed now.
    +
    +09/02/2001 Version 1.2 released.
    +
    +04/02/2001 mcs@astro.caltech.edu
    +
    +           pcache.c libtecla.h
    +             With all filesystems local, demo2 was very fast to start
    +             up, but on a Sun system with one of the target
    +             directories being on a remote nfs mounted filesystem, the
    +             startup time was many seconds. This was due to the
    +             executable selection callback being applied to all files
    +             in the path at startup. To avoid this, all files are now
    +             included in the cache, and the application specified
    +             file-selection callback is only called on files as they
    +             are matched. Whether the callback rejected or accepted
    +             them is then cached so that the next time an already
    +             checked file is looked at, the callback doesn't have to
    +             be called. As a result, startup is now fast on all
    +             systems, and since usually there are only a few matching
    +             file completions at a time, the delay during completion
    +             is also usually small. The only exception is if the user
    +             tries to complete an empty string, at which point all
    +             files have to be checked. Having done this once, however,
    +             doing it again is fast.
    +           man3/pca_lookup_file.3
    +             I added a man page documenting the new PathCache module.
    +           man3/.3
    +             I have added man pages for all of the functions in each
    +             of the modules. These 1-line pages use the .so directive
    +             to redirect nroff to the man page of the parent module.
    +           man Makefile update_html
    +             I renamed man to man3 to make it easier to test man page
    +             rediction, and updated Makefile and update_html
    +             accordingly. I also instructed update_html to ignore
    +             1-line man pages when making html equivalents of the man
    +             pages.
    +           cplmatch.c
    +             In cpl_list_completions() the size_t return value of
    +             strlen() was being used as the length argument of a "%*s"
    +             printf directive. This ought to be an int, so the return
    +             value of strlen() is now cast to int. This would have
    +             caused problems on architectures where the size of a
    +             size_t is not equal to the size of an int.
    +
    +02/02/2001 mcs@astro.caltech.edu
    +
    +           getline.c
    +             Under UNIX, certain terminal bindings are set using the
    +             stty command. This, for example, specifies which control
    +             key generates a user-interrupt (usually ^C or ^Y). What I
    +             hadn't realized was that ASCII NUL is used as the way to
    +             specify that one of these bindings is unset. I have now
    +             modified the code to skip unset bindings, leaving the
    +             corresponding action bound to the built-in default, or a
    +             user provided binding.
    +
    +28/01/2001 mcs@astro.caltech.edu
    +
    +           pcache.c libtecla.h
    +             A new module was added which supports searching for files
    +             in any colon separated list of directories, such as the
    +             unix execution PATH environment variable. Files in these
    +             directories, after being individually okayed for
    +             inclusion via an application provided callback, are
    +             cached in a PathCache object. You can then look up the
    +             full pathname of a given filename, or you can use the
    +             provided completion callback to list possible completions
    +             in the path-list. The contents of relative directories,
    +             such as ".", obviously can't be cached, so these
    +             directories are read on the fly during lookups and
    +             completions. The obvious application of this facility is
    +             to provide Tab-completion of commands, and thus a
    +             callback to place executable files in the cache, is
    +             provided.
    +           demo2.c
    +             This new program demonstrates the new PathCache
    +             module. It reads and processes lines of input until the
    +             word 'exit' is entered, or C-d is pressed. The default
    +             tab-completion callback is replaced with one which at the
    +             start of a line, looks up completions of commands in the
    +             user's execution path, and when invoked in other parts of
    +             the line, reverts to normal filename completion. Whenever
    +             a new line is entered, it extracts the first word on the
    +             line, looks it up in the user's execution path to see if
    +             it corresponds to a known command file, and if so,
    +             displays the full pathname of the file, along with the
    +             remaining arguments.
    +           cplfile.c
    +             I added an optional pair of callback function/data
    +             members to the new cpl_file_completions() configuration
    +             structure. Where provided, this callback is asked
    +             on a file-by-file basis, which files should be included
    +             in the list of file completions. For example, a callback
    +             is provided for listing only completions of executable
    +             files.
    +           cplmatch.c
    +             When listing completions, the length of the type suffix
    +             of each completion wasn't being taken into account
    +             correctly when computing the column widths. Thus the
    +             listing appeared ragged sometimes. This is now fixed.
    +           pathutil.c
    +             I added a function for prepending a string to a path,
    +             and another for testing whether a pathname referred to
    +             an executable file.
    +
    +28/01/2001 mcs@astro.caltech.edu
    +
    +           libtecla.h cplmatch.c man/cpl_complete_word.3
    +             The use of a publically defined structure to configure
    +             the cpl_file_completions() callback was flawed, so a new
    +             approach has been designed, and the old method, albeit
    +             still supported, is no longer documented in the man
    +             pages. The definition of the CplFileArgs structure in
    +             libtecla.h is now accompanied by comments warning people
    +             not to modify it, since modifications could break
    +             applications linked to shared versions of the tecla
    +             library. The new method involves an opaque CplFileConf
    +             object, instances of which are returned by a provided
    +             constructor function, configured with provided accessor
    +             functions, and when no longer needed, deleted with a
    +             provided destructor function. This is documented in the
    +             cpl_complete_word man page. The cpl_file_completions()
    +             callback distinguishes what type of configuration
    +             structure it has been sent by virtue of a code placed at
    +             the beginning of the CplFileConf argument by its
    +             constructor.
    +
    +04/01/2001 mcs@astro.caltech.edu (Release of version 1.1j)
    +
    +           getline.c
    +             I added upper-case bindings for the default meta-letter
    +             keysequences such as M-b. They thus continue to work
    +             when the user has caps-lock on.
    +           Makefile
    +             I re-implemented the "install" target in terms of new
    +             install_lib, install_inc and install_man targets. When
    +             distributing the library with other packages, these new
    +             targets allows for finer grained control of the
    +             installation process.
    +
    +30/12/2000 mcs@astro.caltech.edu
    +
    +           getline.c man/gl_get_line.3
    +             I realized that the recall-history action that I
    +             implemented wasn't what Markus had asked me for. What he
    +             actually wanted was for down-history to continue going
    +             forwards through a previous history recall session if no
    +             history recall session had been started while entering
    +             the current line. I have thus removed the recall-history
    +             action and modified the down-history action function
    +             accordingly.
    +
    +24/12/2000 mcs@astro.caltech.edu
    +
    +           getline.c
    +             I modified gl_get_line() to allow the previously returned
    +             line to be passed in the start_line argument.
    +           getline.c man/gl_get_line.3
    +             I added a recall-history action function, bound to M^P.
    +             This recalls the last recalled history line, regardless
    +             of whether it was from the current or previous line.
    +
    +13/12/2000 mcs@astro.caltech.edu (Release of version 1.1i)
    +
    +           getline.c history.h history.c man/gl_get_line.3
    +             I implemented the equivalent of the ksh Operate action. I
    +             have named the tecla equivalent "repeat-history". This
    +             causes the line that is to be edited to returned, and
    +             arranges for the next most recent history line to be
    +             preloaded on the next call to gl_get_line(). Repeated
    +             invocations of this action thus result in successive
    +             history lines being repeated - hence the
    +             name. Implementing the ksh Operate action was suggested
    +             by Markus Gyger. In ksh it is bound to ^O, but since ^O
    +             is traditionally bound by the default terminal settings,
    +             to stop-output, I have bound the tecla equivalent to M-o.
    +
    +01/12/2000 mcs@astro.caltech.edu (Release of version 1.1h)
    +
    +           getline.c keytab.c keytab.h man/gl_get_line.3
    +             I added a digit-argument action, to allow repeat
    +             counts for actions to be entered. As in both tcsh
    +             and readline, this is bound by default to each of
    +             M-0, M-1 through to M-9, the number being appended
    +             to the current repeat count. Once one of these has been
    +             pressed, the subsequent digits of the repeat count can be
    +             typed with or without the meta key pressed. It is also
    +             possible to bind digit-argument to other keys, with or
    +             without a numeric final keystroke. See man page for
    +             details.
    +
    +           getline.c man/gl_get_line.3
    +             Markus noted that my choice of M-< for the default
    +             binding of read-from-file, could be confusing, since
    +             readline binds this to beginning-of-history. I have
    +             thus rebound it to ^X^F (ie. like find-file in emacs).
    +
    +           getline.c history.c history.h man/gl_get_line.3
    +             I have now implemented equivalents of the readline
    +             beginning-of-history and end-of-history actions.
    +             These are bound to M-< and M-> respectively.
    +
    +           history.c history.h
    +             I Moved the definition of the GlHistory type, and
    +             its subordinate types from history.h to history.c.
    +             There is no good reason for any other module to
    +             have access to the innards of this structure.
    +
    +27/11/2000 mcs@astro.caltech.edu (Release of version 1.1g)
    +
    +           getline.c man/gl_get_line.3
    +             I added a "read-from-file" action function and bound it
    +             by default to M-<. This causes gl_get_line() to
    +             temporarily return input from the file who's name
    +             precedes the cursor.
    +             
    +26/11/2000 mcs@astro.caltech.edu
    +
    +           getline.c keytab.c keytab.h man/gl_get_line.3
    +             I have reworked some of the keybinding code again.
    +
    +             Now, within key binding strings, in addition to the
    +             previously existing notation, you can now use M-a to
    +             denote meta-a, and C-a to denote control-a. For example,
    +             a key binding which triggers when the user presses the
    +             meta key, the control key and the letter [
    +             simultaneously, can now be denoted by M-C-[, or M-^[ or
    +             \EC-[ or \E^[.
    +
    +             I also updated the man page to use M- instead of \E in
    +             the list of default bindings, since this looks cleaner.
    +
    +           getline.c man/gl_get_line.3
    +             I added a copy-region-as-kill action function and
    +             gave it a default binding to M-w.
    +
    +22/11/2000 mcs@astro.caltech.edu
    +
    +           *.c
    +             Markus Gyger sent me a copy of a previous version of
    +             the library, with const qualifiers added in appropriate
    +             places. I have done the same for the latest version.
    +             Among other things, this gets rid of the warnings
    +             that are generated if one tells the compiler to
    +             const qualify literal strings.
    +
    +           getline.c getline.h glconf.c
    +             I have moved the contents of glconf.c and the declaration
    +             of the GetLine structure into getline.c. This is cleaner,
    +             since now only functions in getline.c can mess with the
    +             innards of GetLine objects. It also clears up some problems
    +             with system header inclusion order under Solaris, and also
    +             the possibility that this might result in inconsistent
    +             system macro definitions, which in turn could cause different
    +             declarations of the structure to be seen in different files.
    +
    +           hash.c
    +             I wrote a wrapper function to go around strcmp(), such that
    +             when hash.c is compiled with a C++ compiler, the pointer
    +             to the wrapper function is a C++ function pointer.
    +             This makes it compatible with comparison function pointer
    +             recorded in the hash table.
    +
    +           cplmatch.c getline.c libtecla.h
    +             Markus noted that the Sun C++ compiler wasn't able to
    +             match up the declaration of cpl_complete_word() in
    +             libtecla.h, where it is surrounded by a extern "C" {}
    +             wrapper, with the definition of this function in
    +             cplmatch.c. My suspicion is that the compiler looks not
    +             only at the function name, but also at the function
    +             arguments to see if two functions match, and that the
    +             match_fn() argument, being a fully blown function pointer
    +             declaration, got interpetted as that of a C function in
    +             one case, and a C++ function in the other, thus
    +             preventing a match.
    +
    +             To fix this I now define a CplMatchFn typedef in libtecla.h,
    +             and use this to declare the match_fn callback.
    +
    +20/11/2000 (Changes suggested by Markus Gyger to support C++ compilers):
    +           expand.c
    +             Renamed a variable called "explicit" to "xplicit", to
    +             avoid conflicts when compiling with C++ compilers.
    +           *.c
    +             Added explicit casts when converting from (void *) to
    +             other pointer types. This isn't needed in C but it is
    +             in C++.
    +           getline.c
    +             tputs() has a strange declaration under Solaris. I was
    +             enabling this declaration when the SPARC feature-test
    +             macro was set. Markus changed the test to hinge on the
    +             __sun and __SVR4 macros.
    +           direader.c glconf.c stringrp.c
    +             I had omitted to include string.h in these two files.
    +
    +           Markus also suggested some other changes, which are still
    +           under discussion. With the just above changes however, the
    +           library compiles without complaint using g++.
    +
    +19/11/2000 mcs@astro.caltech.edu
    +           getline.h getline.c keytab.c keytab.h glconf.c
    +           man/gl_get_line.3
    +             I added support for backslash escapes (include \e
    +             for the keyboard escape key) and literal binary
    +             characters to the characters allowed within key sequences
    +             of key bindings.
    +
    +           getline.h getline.c keytab.c keytab.h glconf.c
    +           man/gl_get_line.3
    +             I introduced symbolic names for the arrow keys, and
    +             modified the library to use the cursor key sequences
    +             reported by terminfo/termcap in addition to the default
    +             ANSI ones. Anything bound to the symbolically named arrow
    +             keys also gets bound to the default and terminfo/termcap
    +             cursor key sequences. Note that under Solaris
    +             terminfo/termcap report the properties of hardware X
    +             terminals when TERM is xterm instead of the terminal
    +             emulator properties, and the cursor keys on these two
    +             systems generate different key sequences. This is an
    +             example of why extra default sequences are needed.
    +
    +           getline.h getline.c keytab.c
    +             For some reason I was using \e to represent the escape
    +             character. This is supported by gcc, which thus doesn't
    +             emit a warning except with the -pedantic flag, but isn't
    +             part of standard C. I now use a macro to define escape
    +             as \033 in getline.h, and this is now used wherever the
    +             escape character is needed.
    +
    +17/11/2000 mcs@astro.caltech.edu (Release of version 1.1d)
    +
    +           getline.c, man/gl_get_line(3), html/gl_get_line.html
    +             In tcsh ^D is bound to a function which does different
    +             things depending on where the cursor is within the input
    +             line. I have implemented its equivalent in the tecla
    +             library. When invoked at the end of the line this action
    +             function displays possible completions. When invoked on
    +             an empty line it causes gl_get_line() to return NULL,
    +             thus signalling end of input. When invoked within a line
    +             it invokes forward-delete-char, as before. The new action
    +             function is called del-char-or-list-or-eof.
    +
    +           getline.c, man/gl_get_line(3), html/gl_get_line.html
    +             I found that the complete-word and expand-file actions
    +             had underscores in their names instead of hyphens. This
    +             made them different from all other action functions, so I
    +             have changed the underscores to hyphens.
    +
    +           homedir.c
    +             On SCO UnixWare while getpwuid_r() is available, the
    +             associated _SC_GETPW_R_SIZE_MAX macro used by sysconf()
    +             to find out how big to make the buffer to pass to this
    +             function to cater for any password entry, doesn't
    +             exist. I also hadn't catered for the case where sysconf()
    +             reports that this limit is indeterminate. I have thus
    +             change the code to substitute a default limit of 1024 if
    +             either the above macro isn't defined or if sysconf() says
    +             that the associated limit is indeterminate.
    +           
    +17/11/2000 mcs@astro.caltech.edu (Release of version 1.1c)
    +
    +           getline.c, getline.h, history.c, history.h
    +             I have modified the way that the history recall functions
    +             operate, to make them better emulate the behavior of
    +             tcsh. Previously the history search bindings always
    +             searched for the prefix that preceded the cursor, then
    +             left the cursor at the same point in the line, so that a
    +             following search would search using the same prefix. This
    +             isn't how tcsh operates. On finding a matching line, tcsh
    +             puts the cursor at the end of the line, but arranges for
    +             the followup search to continue with the same prefix,
    +             unless the user does any cursor motion or character
    +             insertion operations in between, in which case it changes
    +             the search prefix to the new set of characters that are
    +             before the cursor. There are other complications as well,
    +             which I have attempted to emulate. As far as I can
    +             tell, the tecla history recall facilities now fully
    +             emulate those of tcsh.
    +
    +16/11/2000 mcs@astro.caltech.edu (Release of version 1.1b)
    +
    +           demo.c:
    +             One can now quit from the demo by typing exit.
    +
    +           keytab.c:
    +             The first entry of the table was getting deleted
    +             by _kt_clear_bindings() regardless of the source
    +             of the binding. This deleted the up-arrow binding.
    +             Symptoms noted by gazelle@yin.interaccess.com.
    +
    +           getline.h:
    +             Depending on which system include files were include
    +             before the inclusion of getline.h, SIGWINCH and
    +             TIOCGWINSZ might or might not be defined. This resulted
    +             in different definitions of the GetLine object in
    +             different files, and thus some very strange bugs! I have
    +             now added #includes for the necessary system header files
    +             in getline.h itself. The symptom was that on creating a
    +             ~/.teclarc file, the demo program complained of a NULL
    +             argument to kt_set_keybinding() for the first line of the
    +             file.
    +
    +15/11/2000 mcs@astro.caltech.edu (Release of version 1.1a)
    +
    +           demo.c:
    +             I had neglected to check the return value of
    +             new_GetLine() in the demo program. Oops.
    +
    +           getline.c libtecla.h:
    +             I wrote gl_change_terminal(). This allows one to change to
    +             a different terminal or I/O stream, by specifying the
    +             stdio streams to use for input and output, along with the
    +             type of terminal that they are connected to.
    +
    +           getline.c libtecla.h:
    +             Renamed GetLine::isterm to GetLine::is_term. Standard
    +             C reserves names that start with "is" followed by
    +             alphanumeric characters, so this avoids potential
    +             clashes in the future.
    +
    +           keytab.c keytab.h
    +             Each key-sequence can now have different binding
    +             functions from different sources, with the user provided
    +             binding having the highest precedence, followed by the
    +             default binding, followed by any terminal specific
    +             binding. This allows gl_change_terminal() to redefine the
    +             terminal-specific bindings each time that
    +             gl_change_terminal() is called, without overwriting the
    +             user specified or default bindings. In the future, it will
    +             also allow for reconfiguration of user specified
    +             bindings after the call to new_GetLine(). Ie. deleting a
    +             user specified binding should reinstate any default or
    +             terminal specific binding.
    +
    +           man/cpl_complete_word.3 html/cpl_complete_word.html
    +           man/ef_expand_file.3    html/ef_expand_file.html
    +           man/gl_get_line.3       html/gl_get_line.html
    +             I added sections on thread safety to the man pages of the
    +             individual modules.
    +
    +           man/gl_get_line.3       html/gl_get_line.html
    +             I documented the new gl_change_terminal() function.
    +
    +           man/gl_get_line.3       html/gl_get_line.html
    +             In the description of the ~/.teclarc configuration file,
    +             I had omitted the 'bind' command word in the example
    +             entry. I have now remedied this.
    +
    diff --git a/libtecla-1.4.1/html/cpl_complete_word.html b/libtecla-1.4.1/html/cpl_complete_word.html new file mode 100644 index 0000000..063359d --- /dev/null +++ b/libtecla-1.4.1/html/cpl_complete_word.html @@ -0,0 +1,423 @@ + +Manual Page + + +
    +

    NAME

    +     cpl_complete_word,   cfc_file_start,    cfc_literal_escapes,
    +     cfc_set_check_fn,  cpl_add_completion, cpl_file_completions,
    +     cpl_last_error,   cpl_list_completions,    cpl_record_error,
    +     del_CplFileConf,     del_WordCompletion,    new_CplFileConf,
    +     new_WordCompletion - lookup possible completions for a word
    +
    +

    SYNOPSIS

    +     #include <stdio.h>
    +     #include <libtecla.h>
    +
    +     WordCompletion *new_WordCompletion(void);
    +
    +     WordCompletion *del_WordCompletion(WordCompletion *cpl);
    +
    +     #define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \
    +                                       void *data, \
    +                                       const char *line, \
    +                                       int word_end)
    +     typedef CPL_MATCH_FN(CplMatchFn);
    +
    +     CPL_MATCH_FN(cpl_file_completions);
    +
    +     CplMatches *cpl_complete_word(WordCompletion *cpl,
    +                                   const char *line,
    +                                   int word_end, void *data,
    +                                   CplMatchFn *match_fn);
    +
    +     int cpl_list_completions(CplMatches *result, FILE *fp,
    +                              int term_width);
    +
    +     int cpl_add_completion(WordCompletion *cpl,
    +                            const char *line, int word_start,
    +                            int word_end, const char *suffix,
    +                            const char *type_suffix,
    +                            const char *cont_suffix);
    +
    +     void cpl_record_error(WordCompletion *cpl,
    +                           const char *errmsg);
    +
    +     const char *cpl_last_error(WordCompletion *cpl);
    +
    +
    +
    +

    DESCRIPTION

    +     The  cpl_complete_word()  function  is  part  of  the  tecla
    +     library (see the libtecla(3) man page). It is usually called
    +     behind the scenes by gl_get_line(3), but can also be  called
    +     separately.
    +
    +     Given an input line containing an incomplete word to be com-
    +     pleted,  it  calls a user-provided callback function (or the
    +     provided file-completion callback function) to look  up  all
    +     possible  completion  suffixes  for  that word. The callback
    +     function is expected to look backward in the line,  starting
    +     from the specified cursor position, to find the start of the
    +     word to be completed, then to look up all  possible  comple-
    +     tions of that word and record them, one at a time by calling
    +     cpl_add_completion().
    +
    +
    +     Descriptions of the functions of this module are as follows:
    +
    +       CompleteWord *new_CompleteWord(void)
    +
    +     This  function   creates   the   resources   used   by   the
    +     cpl_complete_word()  function.  In  particular, it maintains
    +     the memory that is used to return  the  results  of  calling
    +     cpl_complete_word().
    +
    +       CompleteWord *del_CompleteWord(CompleteWord *cpl)
    +
    +     This function deletes the resources that were returned by  a
    +     previous  call to new_CompleteWord(). It always returns NULL
    +     (ie. a deleted object). It does nothing if the cpl  argument
    +     is NULL.
    +
    +     The callback functions  which  lookup  possible  completions
    +     should be defined with the following macro (which is defined
    +     in libtecla.h).
    +
    +       #define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \
    +                                         void *data, \
    +                                         const char *line, \
    +                                         int word_end)
    +
    +     Functions of this type are  called  by  cpl_complete_word(),
    +     and all of the arguments of the callback are those that were
    +     passed to said function. In particular,  the  line  argument
    +     contains the input line containing the word to be completed,
    +     and word_end is the index of the character that follows  the
    +     last  character  of  the incomplete word within this string.
    +     The callback is expected to look backwards from word_end for
    +     the start of the incomplete word. What constitutes the start
    +     of a word clearly depends on the application,  so  it  makes
    +     sense  for  the callback to take on this responsibility. For
    +     example, the  builtin  filename  completion  function  looks
    +     backwards  until it hits an unescaped space, or the start of
    +     the line.  Having found the start of the word, the  callback
    +     should  then  lookup  all possible completions of this word,
    +     and  record  each   completion   via   separate   calls   to
    +     cpl_add_completion().  If  the  callback  needs access to an
    +     application-specific symbol table, it can pass  it  and  any
    +     other  data  that  it  needs,  via  the  data argument. This
    +     removes any need for globals.
    +
    +     The callback function should return 0 if no errors occur. On
    +     failure it should return 1, and register a terse description
    +     of the error by calling cpl_record_error().
    +
    +       void cpl_record_error(WordCompletion *cpl,
    +                             const char *errmsg);
    +
    +     The    last    error    message    recorded    by    calling
    +     cpl_record_error(),  can  subsequently be queried by calling
    +     cpl_last_error(), as described later.
    +
    +       int cpl_add_completion(WordCompletion *cpl,
    +                              const char *line, int word_start,
    +                              int word_end, const char *suffix,
    +                              const char *type_suffix,
    +                              const char *cont_suffix);
    +
    +     The cpl_add_completion() function is  called  zero  or  more
    +     times  by  the  completion  callback function to record each
    +     possible completion in the specified WordCompletion  object.
    +     These    completions    are    subsequently    returned   by
    +     cpl_complete_word(), as described later. The cpl, line,  and
    +     word_end  arguments  should be those that were passed to the
    +     callback function. The word_start  argument  should  be  the
    +     index  within the input line string of the start of the word
    +     that is being completed. This should  equal  word_end  if  a
    +     zero-length  string  is being completed. The suffix argument
    +     is the string that would have to be appended to  the  incom-
    +     plete  word  to complete it.  If this needs any quoting (eg.
    +     the addition of backslashes before special charaters) to  be
    +     valid  within  the  displayed  input  line,  this  should be
    +     included. A copy of the suffix string  is  allocated  inter-
    +     nally,  so  there  is  no  need to maintain your copy of the
    +     string after cpl_add_completion() returns.
    +
    +     Note that in the array of  possible  completions  which  the
    +     cpl_complete_word() function returns, the suffix recorded by
    +     cpl_add_completion() is listed along with the concatentation
    +     of  this  suffix  with the word that lies between word_start
    +     and word_end in the input line.
    +
    +     The type_suffix argument specifies an optional string to  be
    +     appended  to  the completion if it is displayed as part of a
    +     list of completions by cpl_list_completions(). The intention
    +     is  that  this indicate to the user the type of each comple-
    +     tion. For example, the file  completion  function  places  a
    +     directory  separator after completions that are directories,
    +     to indicate their nature to the user. Similary, if the  com-
    +     pletion were a function, you could indicate this to the user
    +     by setting type_suffix to "()". Note  that  the  type_suffix
    +     string  isn't  copied,  so  if  the argument isn't a literal
    +     string between speech marks, be sure that the string remains
    +     valid   for   at   least   as   long   as   the  results  of
    +     cpl_complete_word() are needed.
    +
    +     The cont_suffix is a continuation suffix to  append  to  the
    +     completed word in the input line if this is the only comple-
    +     tion. This is something that isn't part  of  the  completion
    +     itself, but that gives the user an indication about how they
    +     might continue to extend the token.  For example, the  file-
    +     completion  callback  function adds a directory separator if
    +     the completed word is a directory.  If  the  completed  word
    +     were  a  function  name, you could similarly aid the user by
    +     arranging for an open parenthesis to be appended.
    +
    +       CplMatches *cpl_complete_word(WordCompletion *cpl,
    +                                     const char *line,
    +                                     int word_end, void *data,
    +                                     CplMatchFn *match_fn);
    +
    +     The cpl_complete_word() is normally called behind the scenes
    +     by  gl_get_line(3), but can also be called separately if you
    +     separately allocate a  WordCompletion  object.  It  performs
    +     word  completion, as described at the beginning of this sec-
    +     tion. Its first argument is  a  resource  object  previously
    +     returned  by  new_CompleteWord().   The line argument is the
    +     input line string, containing the word to be completed.  The
    +     word_end argument contains the index of the character in the
    +     input line, that just follows the last character of the word
    +     to  be  completed. When called by gl_get_line(), this is the
    +     character over which the  user  pressed  TAB.  The  match_fn
    +     argument  is  the  function pointer of the callback function
    +     which will lookup  possible  completions  of  the  word,  as
    +     described  above,  and  the data argument provides a way for
    +     the application to pass arbitrary data to the callback func-
    +     tion.
    +
    +     If no errors occur, the cpl_complete_word() function returns
    +     a  pointer to a CplMatches container, as defined below. This
    +     container is allocated as part of the cpl  object  that  was
    +     passed  to cpl_complete_word(), and will thus change on each
    +     call which uses the same cpl argument.
    +
    +       typedef struct {
    +         char *completion;        /* A matching completion */
    +                                  /*  string */
    +         char *suffix;            /* The part of the */
    +                                  /*  completion string which */
    +                                  /*  would have to be */
    +                                  /*  appended to complete the */
    +                                  /*  original word. */
    +         const char *type_suffix; /* A suffix to be added when */
    +                                  /*  listing completions, to */
    +                                  /*  indicate the type of the */
    +                                  /*  completion. */
    +       } CplMatch;
    +
    +       typedef struct {
    +         char *suffix;            /* The common initial part */
    +                                  /*  of all of the completion */
    +                                  /*  suffixes. */
    +         const char *cont_suffix; /* Optional continuation */
    +                                  /*  string to be appended to */
    +                                  /*  the sole completion when */
    +                                  /*  nmatch==1. */
    +         CplMatch *matches;       /* The array of possible */
    +                                  /*  completion strings, */
    +                                  /*  sorted into lexical */
    +                                  /*  order. */
    +         int nmatch;              /* The number of elements in */
    +                                  /*  the above matches[] */
    +                                  /*  array. */
    +       } CplMatches;
    +
    +     If an error occurs  during  completion,  cpl_complete_word()
    +     returns  NULL. A description of the error can be acquired by
    +     calling the cpl_last_error() function.
    +
    +       const char *cpl_last_error(WordCompletion *cpl);
    +
    +     The cpl_last_error() function returns a terse description of
    +     the   error   which   occurred   on   the   last   call   to
    +     cpl_complete_word() or cpl_add_completion().
    +
    +       int cpl_list_completions(CplMatches *result, FILE *fp,
    +                                int terminal_width);
    +
    +     When the cpl_complete_word() function returns multiple  pos-
    +     sible  completions,  the cpl_list_completions() function can
    +     be called upon to list them, suitably  arranged  across  the
    +     available  width  of  the  terminal.  It  arranges  for  the
    +     displayed columns of completions to all have the same width,
    +     set   by   the  longest  completion.  It  also  appends  the
    +     type_suffix strings that were recorded with each completion,
    +     thus indicating their types to the user.
    +
    +
    +

    THE BUILT-IN FILENAME-COMPLETION CALLBACK

    +     By default the gl_get_line(3) function, passes the following
    +     completion  callback  function  to cpl_complete_word(). This
    +     function can also be used separately, either by  sending  it
    +     to  cpl_complete_word(), or by calling it directly from your
    +     own completion callback function.
    +
    +       CPL_MATCH_FN(cpl_file_completions);
    +
    +     Certain aspects of the behavior  of  this  callback  can  be
    +     changed  via  its  data  argument. If you are happy with its
    +     default behavior you can pass NULL in this argument.  Other-
    +     wise  it should be a pointer to a CplFileConf object, previ-
    +     ously allocated by calling new_CplFileConf().
    +
    +       CplFileConf *new_CplFileConf(void);
    +
    +     CplFileConf objects encapsulate the configuration parameters
    +     of cpl_file_completions(). These parameters, which start out
    +     with default values, can be changed by calling the  accessor
    +     functions described below.
    +
    +     By default,  the  cpl_file_completions()  callback  function
    +     searches  backwards for the start of the filename being com-
    +     pleted, looking for the first un-escaped space or the  start
    +     of  the input line. If you wish to specify a different loca-
    +     tion, call cfc_file_start() with  the  index  at  which  the
    +     filename  starts  in  the input line. Passing start_index=-1
    +     re-enables the default behavior.
    +
    +       void cfc_file_start(CplFileConf *cfc, int start_index);
    +
    +     By default, when cpl_file_completions() looks at a  filename
    +     in  the input line, each lone backslash in the input line is
    +     interpreted as being a special character which  removes  any
    +     special significance of the character which follows it, such
    +     as a space which should be taken as  part  of  the  filename
    +     rather  than  delimiting  the  start  of the filename. These
    +     backslashes are thus ignored while looking for  completions,
    +     and  subsequently  added  before  spaces,  tabs  and literal
    +     backslashes in the list of completions.  To  have  unescaped
    +     backslashes    treated    as    normal    characters,   call
    +     cfc_literal_escapes() with a non-zero value in  its  literal
    +     argument.
    +
    +       void cfc_literal_escapes(CplFileConf *cfc, int literal);
    +
    +     By default, cpl_file_completions() reports all  files  who's
    +     names  start with the prefix that is being completed. If you
    +     only want a selected subset of these files to be reported in
    +     the list of completions, you can arrange this by providing a
    +     callback function which takes the full pathname of  a  file,
    +     and  returns  0  if  the file should be ignored, or 1 if the
    +     file should be included  in  the  list  of  completions.  To
    +     register  such a function for use by cpl_file_completions(),
    +     call cfc_set_check_fn(), and pass it a pointer to the  func-
    +     tion,  together  with  a  pointer to any data that you would
    +     like passed to this callback whenever  it  is  called.  Your
    +     callback can make its decisions based on any property of the
    +     file, such as the filename itself, whether the file is read-
    +     able, writable or executable, or even based on what the file
    +     contains.
    +
    +       #define CPL_CHECK_FN(fn) int (fn)(void *data, \
    +                                         const char *pathname)
    +       typedef CPL_CHECK_FN(CplCheckFn);
    +
    +       void cfc_set_check_fn(CplFileConf *cfc,
    +                             CplCheckFn *chk_fn, void *chk_data);
    +
    +     The cpl_check_exe() function is a provided callback  of  the
    +     above  type, for use with cpl_file_completions(). It returns
    +     non-zero if the filename that it is given represents a  nor-
    +     mal  file that the user has execute permission to. You could
    +     use this to have cpl_file_completions()  only  list  comple-
    +     tions of executable files.
    +
    +     When you have finished with a CplFileConf variable, you  can
    +     pass  it  to  the  del_CplFileConf()  destructor function to
    +     reclaim its memory.
    +
    +       CplFileConf *del_CplFileConf(CplFileConf *cfc);
    +
    +
    +
    +

    THREAD SAFETY

    +     In multi-threaded programs, you should use the  libtecla_r.a
    +     version  of the library. This uses POSIX reentrant functions
    +     where available (hence the _r suffix), and disables features
    +     that  rely on non-reentrant system functions. In the case of
    +     this module, the only disabled feature is  username  comple-
    +     tion in ~username/ expressions, in cpl_file_completions().
    +
    +     Using the libtecla_r.a version of the library, it is safe to
    +     use  the facilities of this module in multiple threads, pro-
    +     vided that each thread uses a separately allocated  WordCom-
    +     pletion  object.  In  other words, if two threads want to do
    +     word completion, they should each call  new_WordCompletion()
    +     to allocate their own completion objects.
    +
    +
    +

    FILES

    +     libtecla.a    -    The tecla library
    +     libtecla.h    -    The tecla header file.
    +
    +
    +

    SEE ALSO

    +     libtecla(3),       gl_get_line(3),        ef_expand_file(3),
    +     pca_lookup_file(3)
    +
    +
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/ef_expand_file.html b/libtecla-1.4.1/html/ef_expand_file.html new file mode 100644 index 0000000..c1e71c7 --- /dev/null +++ b/libtecla-1.4.1/html/ef_expand_file.html @@ -0,0 +1,267 @@ + +Manual Page + + +
    +

    NAME

    +     ef_expand_file,        del_ExpandFile,        ef_last_error,
    +     ef_list_expansions,  new_ExpandFile  - expand filenames con-
    +     taining ~user/$envvar and wildcard expressions
    +
    +

    SYNOPSIS

    +     #include <libtecla.h>
    +
    +     ExpandFile *new_ExpandFile(void);
    +
    +     ExpandFile *del_ExpandFile(ExpandFile *ef);
    +
    +     FileExpansion *ef_expand_file(ExpandFile *ef,
    +                                   const char *path,
    +                                   int pathlen);
    +
    +     int ef_list_expansions(FileExpansion *result, FILE *fp,
    +                            int term_width);
    +
    +     const char *ef_last_error(ExpandFile *ef);
    +
    +
    +

    DESCRIPTION

    +     The ef_expand_file() function is part of the  tecla  library
    +     (see  the  libtecla(3)  man  page).  It  expands a specified
    +     filename, converting ~user/ and ~/ expressions at the  start
    +     of  the  filename  to  the  corresponding  home directories,
    +     replacing  $envvar  with  the  value  of  the  corresponding
    +     environment  variable, and then, if there are any wildcards,
    +     matching these against existing  filenames.  Backslashes  in
    +     the  input  filename are interpreted as escaping any special
    +     meanings  of  the  characters  that   follow   them.    Only
    +     backslahes  that  are themselves preceded by backslashes are
    +     preserved in the expanded filename.
    +
    +     In the presence of wildcards, the returned list of filenames
    +     only  includes  the  names of existing files which match the
    +     wildcards. Otherwise,  the  original  filename  is  returned
    +     after  expansion  of  tilde  and dollar expressions, and the
    +     result is not checked against existing  files.  This  mimics
    +     the file-globbing behavior of the unix tcsh shell.
    +
    +     The supported wildcards and their meanings are:
    +       *        -  Match any sequence of zero or more characters.
    +       ?        -  Match any single character.
    +       [chars]  -  Match any single character that appears in
    +                   'chars'.  If 'chars' contains an expression of
    +                   the form a-b, then any character between a and
    +                   b, including a and b, matches. The '-'
    +                   character looses its special meaning as a
    +                   range specifier when it appears at the start
    +                   of the sequence of characters. The ']'
    +                   character also looses its significance as the
    +                   terminator of the range expression if it
    +                   appears immediately after the opening '[', at
    +                   which point it is treated one of the
    +                   characters of the range. If you want both '-'
    +                   and ']' to be part of the range, the '-'
    +                   should come first and the ']' second.
    +
    +       [^chars] -  The same as [chars] except that it matches any
    +                   single character that doesn't appear in
    +                   'chars'.
    +
    +     Note that wildcards never match the initial dot in filenames
    +     that  start  with  '.'.  The  initial '.' must be explicitly
    +     specified in the filename. This again  mimics  the  globbing
    +     behavior  of  most unix shells, and its rational is based in
    +     the fact that in unix, files with names that start with  '.'
    +     are usually hidden configuration files, which are not listed
    +     by default by the ls command.
    +
    +     The following is a complete example of how to use  the  file
    +     expansion function.
    +
    +       #include <stdio.h>
    +       #include <libtecla.h>
    +
    +       int main(int argc, char *argv[])
    +       {
    +         ExpandFile *ef;      /* The expansion resource object */
    +         char *filename;      /* The filename being expanded */
    +         FileExpansion *expn; /* The results of the expansion */
    +         int i;
    +
    +         ef = new_ExpandFile();
    +         if(!ef)
    +           return 1;
    +
    +         for(arg = *(argv++); arg; arg = *(argv++)) {
    +           if((expn = ef_expand_file(ef, arg, -1)) == NULL) {
    +             fprintf(stderr, "Error expanding %s (%s).\n", arg,
    +                              ef_last_error(ef));
    +           } else {
    +             printf("%s matches the following files:\n", arg);
    +             for(i=0; i<expn->nfile; i++)
    +               printf(" %s\n", expn->files[i]);
    +           }
    +         }
    +
    +         ef = del_ExpandFile(ef);
    +         return 0;
    +       }
    +
    +     Descriptions of the functions used above are as follows:
    +
    +       ExpandFile *new_ExpandFile(void)
    +
    +     This  function   creates   the   resources   used   by   the
    +     ef_expand_file()  function.  In particular, it maintains the
    +     memory  that  is  used  to  record  the  array  of  matching
    +     filenames  that  is returned by ef_expand_file(). This array
    +     is expanded as needed, so there is no built in limit to  the
    +     number of files that can be matched.
    +
    +       ExpandFile *del_ExpandFile(ExpandFile *ef)
    +
    +     This function deletes the resources that were returned by  a
    +     previous  call  to  new_ExpandFile(). It always returns NULL
    +     (ie a deleted object). It does nothing if the ef argument is
    +     NULL.
    +
    +     A  container  of  the  following   type   is   returned   by
    +     ef_expand_file().
    +
    +       typedef struct {
    +         int exists;   /* True if the files in files[] exist */
    +         int nfile;    /* The number of files in files[] */
    +         char **files; /* An array of 'nfile' filenames. */
    +       } FileExpansion;
    +
    +       FileExpansion *ef_expand_file(ExpandFile *ef,
    +                                     const char *path,
    +                                     int pathlen)
    +
    +     The ef_expand_file() function performs  filename  expansion,
    +     as  documented at the start of this section. Its first argu-
    +     ment is a resource object returned  by  new_ExpandFile().  A
    +     pointer to the start of the filename to be matched is passed
    +     via the path argument. This must be a normal NUL  terminated
    +     string, but unless a length of -1 is passed in pathlen, only
    +     the first pathlen characters will be used  in  the  filename
    +     expansion.   If  the length is specified as -1, the whole of
    +     the string will be expanded.
    +
    +     The function returns a pointer to a container who's contents
    +     are the results of the expansion. If there were no wildcards
    +     in the filename, the nfile member will be 1, and the  exists
    +     member  should  be queried if it is important to know if the
    +     expanded file currently exists or not. If there  were  wild-
    +     cards,  then  the  contained  files[] array will contain the
    +     names of the nfile existing files  that  matched  the  wild-
    +     carded  filename,  and the exists member will have the value
    +     1. Note that the returned container belongs to the specified
    +     ef  object, and its contents will change on each call, so if
    +     you need to retain the results of  more  than  one  call  to
    +     ef_expand_file(),  you  should either make a private copy of
    +     the returned  results,  or  create  multiple  file-expansion
    +     resource objects via multiple calls to new_ExpandFile().
    +
    +     On error, NULL is returned, and an explanation of the  error
    +     can be determined by calling ef_last_error(ef).
    +
    +       const char *ef_last_error(ExpandFile *ef)
    +
    +     This function returns the message which describes the  error
    +     that  occurred on the last call to ef_expand_file(), for the
    +     given (ExpandFile *ef) resource object.
    +
    +       int ef_list_expansions(FileExpansion *result, FILE *fp,
    +                              int terminal_width);
    +
    +     The ef_list_expansions() function provides a convenient  way
    +     to    list    the    filename    expansions    returned   by
    +     ef_expand_file(). Like the unix ls command, it arranges  the
    +     filenames  into  equal width columns, each column having the
    +     width of the largest file. The number  of  columns  used  is
    +     thus  determined  by the length of the longest filename, and
    +     the specified terminal width. Beware that filenames that are
    +     longer than the specified terminal width are printed without
    +     being truncated, so output longer than the specified  termi-
    +     nal width can occur. The list is written to the stdio stream
    +     specified by the fp argument.
    +
    +
    +

    THREAD SAFETY

    +     In multi-threaded programs, you should use the  libtecla_r.a
    +     version  of the library. This uses POSIX reentrant functions
    +     where available (hence the _r suffix), and disables features
    +     that rely on non-reentrant system functions. Currently there
    +     are no features disabled in this module.
    +
    +     Using the libtecla_r.a version of the library, it is safe to
    +     use  the facilities of this module in multiple threads, pro-
    +     vided that each thread uses a separately  allocated  Expand-
    +     File  object. In other words, if two threads want to do file
    +     expansion, they should each call new_ExpandFile()  to  allo-
    +     cate their own file-expansion objects.
    +
    +
    +

    FILES

    +     libtecla.a    -    The tecla library
    +     libtecla.h    -    The tecla header file.
    +
    +
    +

    SEE ALSO

    +     libtecla(3),      gl_get_line(3),      cpl_complete_word(3),
    +     pca_lookup_file(3)
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/enhance.html b/libtecla-1.4.1/html/enhance.html new file mode 100644 index 0000000..9f6bb09 --- /dev/null +++ b/libtecla-1.4.1/html/enhance.html @@ -0,0 +1,111 @@ + +Manual Page + + +
    +

    NAME

    +     enhance - A program that adds command-line editing to  third
    +     party programs.
    +
    +

    SYNOPSIS

    +     enhance command [ argument ... ]
    +
    +
    +

    DESCRIPTION

    +     The enhance program provides enhanced  command-line  editing
    +     facilities  to  users  of third party applications, to which
    +     one doesn't have any source code. It does this by placing  a
    +     pseudo-terminal  between the application and the real termi-
    +     nal. It uses the tecla command-line editing library to  read
    +     input  from  the real terminal, then forwards each just com-
    +     pleted  input  line  to  the  application  via  the  pseudo-
    +     terminal.  All output from the application is forwarded back
    +     unchanged to the real terminal.
    +
    +     Whenever the application stops generating  output  for  more
    +     than  a  tenth  of  a second, the enhance program treats the
    +     latest incomplete output line as the prompt, and  redisplays
    +     any incompleted input line that the user has typed after it.
    +     Note that the small delay, which  is  imperceptible  to  the
    +     user,  isn't necessary for correct operation of the program.
    +     It is just an optimization, designed to stop the input  line
    +     from being redisplayed so often that it slows down output.
    +
    +
    +

    DEFICIENCIES

    +     The one major problem that hasn't been solved yet, is how to
    +     deal  with  applications  that change whether typed input is
    +     echo'd by their controlling terminal. For example,  programs
    +     that ask for a password, such as ftp and telnet, temporarily
    +     tell their controlling terminal not to echo  what  the  user
    +     types.  Since  this  request goes to the application side of
    +     the psuedo terminal, the enhance program has no way of know-
    +     ing  that  this  has  happened,  and continues to echo typed
    +     input to its controlling  terminal,  while  the  user  types
    +     their password.
    +
    +     Furthermore, before  executing  the  host  application,  the
    +     enhance program initially sets the pseudo terminal to noecho
    +     mode, so that  everything  that  it  sends  to  the  program
    +     doesn't  get  redundantly echoed. If a program that switches
    +     to  noecho  mode  explicitly  restores  echoing  afterwards,
    +     rather  than  restoring  the terminal modes that were previ-
    +     ously in force, then subsequently, every time that you enter
    +     a  new input line, a duplicate copy will be displayed on the
    +     next line.
    +
    +
    +

    FILES

    +     libtecla.a    -   The tecla library.
    +     ~/.teclarc    -   The tecla personal customization file.
    +
    +
    +

    SEE ALSO

    +     libtecla(3)
    +
    +
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/gl_get_line.html b/libtecla-1.4.1/html/gl_get_line.html new file mode 100644 index 0000000..dcc45a0 --- /dev/null +++ b/libtecla-1.4.1/html/gl_get_line.html @@ -0,0 +1,2295 @@ + +Manual Page + + +
    +

    NAME

    +     gl_get_line,            new_GetLine,            del_GetLine,
    +     gl_customize_completion,                 gl_change_terminal,
    +     gl_configure_getline,   gl_load_history,    gl_save_history,
    +     gl_group_history,        gl_show_history,       gl_watch_fd,
    +     gl_terminal_size,    gl_resize_history,    gl_limit_history,
    +     gl_clear_history,    gl_toggle_history,   gl_lookup_history,
    +     gl_state_of_history,                    gl_range_of_history,
    +     gl_size_of_history,     gl_echo_mode,     gl_replace_prompt,
    +     gl_prompt_style,      gl_ignore_signal,      gl_trap_signal,
    +     gl_last_signal - allow the user to compose an input line
    +
    +

    SYNOPSIS

    +     #include <stdio.h>
    +     #include <libtecla.h>
    +
    +     GetLine *new_GetLine(size_t linelen, size_t histlen);
    +
    +     GetLine *del_GetLine(GetLine *gl);
    +
    +     char *gl_get_line(GetLine *gl, const char *prompt,
    +                      const char *start_line, int start_pos);
    +
    +     int gl_customize_completion(GetLine *gl, void *data,
    +                                 CplMatchFn *match_fn);
    +
    +     int gl_change_terminal(GetLine *gl, FILE *input_fp,
    +                            FILE *output_fp, const char *term);
    +
    +     int gl_configure_getline(GetLine *gl,
    +                              const char *app_string,
    +                              const char *app_file,
    +                              const char *user_file);
    +
    +     int gl_save_history(GetLine *gl, const char *filename,
    +                         const char *comment, int max_lines);
    +
    +     int gl_load_history(GetLine *gl, const char *filename,
    +                         const char *comment);
    +
    +     int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
    +                     GlFdEventFn *callback, void *data);
    +
    +     int gl_group_history(GetLine *gl, unsigned stream);
    +
    +     int gl_show_history(GetLine *gl, FILE *fp,
    +                         const char *fmt, int all_groups,
    +                         int max_lines);
    +
    +     int gl_resize_history(GetLine *gl, size_t bufsize);
    +
    +     void gl_limit_history(GetLine *gl, int max_lines);
    +     void gl_clear_history(GetLine *gl, int all_groups);
    +
    +     void gl_toggle_history(GetLine *gl, int enable);
    +
    +     GlTerminalSize gl_terminal_size(GetLine *gl,
    +                                     int def_ncolumn,
    +                                     int def_nline);
    +
    +     int gl_lookup_history(GetLine *gl, unsigned long id,
    +                           GlHistoryLine *hline);
    +
    +     void gl_state_of_history(GetLine *gl,
    +                              GlHistoryState *state);
    +
    +     void gl_range_of_history(GetLine *gl,
    +                              GlHistoryRange *range);
    +
    +     void gl_size_of_history(GetLine *gl, GlHistorySize *size);
    +
    +     void gl_echo_mode(GetLine *gl, int enable);
    +
    +     void gl_replace_prompt(GetLine *gl, const char *prompt);
    +
    +     void gl_prompt_style(GetLine *gl, GlPromptStyle style);
    +
    +     int gl_ignore_signal(GetLine *gl, int signo);
    +
    +     int gl_trap_signal(GetLine *gl, int signo, unsigned flags,
    +                        GlAfterSignal after, int errno_value);
    +
    +     int gl_last_signal(const GetLine *gl);
    +
    +
    +
    +

    DESCRIPTION

    +     The gl_get_line() function is part of the tecla library (see
    +     the libtecla(3) man page). If the user is typing at a termi-
    +     nal, it prompts them for an line  of  input,  then  provides
    +     interactive editing facilities, similar to those of the unix
    +     tcsh shell. In addition to simple command-line  editing,  it
    +     supports  recall  of  previously  entered command lines, TAB
    +     completion of file names, and in-line wild-card expansion of
    +     filenames.
    +
    +
    +

    AN EXAMPLE

    +     The following shows a complete example of  how  to  use  the
    +     gl_get_line() function to get input from the user:
    +
    +       #include <stdio.h>
    +       #include <locale.h>
    +       #include <libtecla.h>
    +       int main(int argc, char *argv[])
    +       {
    +         char *line;    /* The line that the user typed */
    +         GetLine *gl;   /* The gl_get_line() resource object */
    +
    +         setlocale(LC_CTYPE, ""); /* Adopt the user's choice */
    +                                  /* of character set. */
    +
    +         gl = new_GetLine(1024, 2048);
    +         if(!gl)
    +           return 1;
    +
    +         while((line=gl_get_line(gl, "$ ", NULL, -1)) != NULL &&
    +                strcmp(line, "exit\n") != 0)
    +           printf("You typed: %s\n", line);
    +
    +         gl = del_GetLine(gl);
    +         return 0;
    +       }
    +
    +     In  the  example,  first  the  resources   needed   by   the
    +     gl_get_line() function are created by calling new_GetLine().
    +     This allocates the memory used in subsequent  calls  to  the
    +     gl_get_line()  function,  including  the  history buffer for
    +     recording previously entered lines. Then one or  more  lines
    +     are read from the user, until either an error occurs, or the
    +     user types exit. Then finally the resources that were  allo-
    +     cated  by  new_GetLine(), are returned to the system by cal-
    +     ling del_GetLine(). Note the use of the NULL return value of
    +     del_GetLine()  to make gl NULL. This is a safety precaution.
    +     If  the  program  subsequently  attempts  to  pass   gl   to
    +     gl_get_line(),  said  function  will complain, and return an
    +     error, instead of attempting to  use  the  deleted  resource
    +     object.
    +
    +
    +
    +

    THE FUNCTIONS USED IN THE EXAMPLE

    +     The descriptions of the functions used in the example are as
    +     follows:
    +
    +       GetLine *new_GetLine(size_t linelen, size_t histlen)
    +
    +     This  function   creates   the   resources   used   by   the
    +     gl_get_line()  function and returns an opaque pointer to the
    +     object that contains them.  The maximum length of  an  input
    +     line  is  specified via the linelen argument, and the number
    +     of bytes to allocate for storing history lines is set by the
    +     histlen argument. History lines are stored back-to-back in a
    +     single buffer of this size. Note that this  means  that  the
    +     number  of  history  lines  that  can be stored at any given
    +     time, depends on the lengths of the  individual  lines.   If
    +     you want to place an upper limit on the number of lines that
    +     can be stored, see the gl_limit_history() function described
    +     later.  If you don't want history at all, specify histlen as
    +     zero, and no history buffer will be allocated.
    +
    +     On error, a  message  is  printed  to  stderr  and  NULL  is
    +     returned.
    +
    +       GetLine *del_GetLine(GetLine *gl)
    +
    +     This function deletes the resources that were returned by  a
    +     previous call to new_GetLine(). It always returns NULL (ie a
    +     deleted object). It does nothing if the gl argument is NULL.
    +
    +       char *gl_get_line(GetLine *gl, const char *prompt,
    +                        const char *start_line, int start_pos);
    +
    +     The gl_get_line() function can be called any number of times
    +     to  read input from the user. The gl argument must have been
    +     previously returned by a call to new_GetLine().  The  prompt
    +     argument  should be a normal NUL terminated string, specify-
    +     ing the prompt to present the user with. By default  prompts
    +     are   displayed   literally,   but   if   enabled  with  the
    +     gl_prompt_style() function (see later), prompts can  contain
    +     directives to do underlining, switch to and from bold fonts,
    +     or turn highlighting on and off.
    +
    +     If you want to specify the initial contents of the line, for
    +     the user to edit, pass the desired string via the start_line
    +     argument. You can then specify which character of this  line
    +     the cursor is initially positioned over, using the start_pos
    +     argument. This should be -1 if you want the cursor to follow
    +     the  last  character of the start line. If you don't want to
    +     preload the line in this manner, send  start_line  as  NULL,
    +     and set start_pos to -1.
    +
    +     The gl_get_line() function returns a  pointer  to  the  line
    +     entered  by  the user, or NULL on error or at the end of the
    +     input. The returned pointer is  part  of  the  specified  gl
    +     resource  object,  and  thus  should  not  be  free'd by the
    +     caller, or assumed to be unchanging from  one  call  to  the
    +     next.  When  reading  from  a user at a terminal, there will
    +     always be a newline character at the  end  of  the  returned
    +     line.   When  standard input is being taken from a pipe or a
    +     file, there will similarly be a  newline  unless  the  input
    +     line  was  too  long to store in the internal buffer. In the
    +     latter case you should call gl_get_line() again to read  the
    +     rest   of   the   line.   Note   that  this  behavior  makes
    +     gl_get_line() similar to fgets().  In fact when stdin  isn't
    +     connected to a terminal,gl_get_line() just calls fgets().
    +
    +
    +

    OPTIONAL PROMPT FORMATTING

    +     Whereas by default the prompt string  that  you  specify  is
    +     displayed  literally,  without any special interpretation of
    +     the characters within it, the gl_prompt_style() function can
    +     be  used to enable optional formatting directives within the
    +     prompt.
    +
    +       void gl_prompt_style(GetLine *gl, GlPromptStyle style);
    +
    +     The style argument, which specifies  the  formatting  style,
    +     can take any of the following values:
    +
    +       GL_FORMAT_PROMPT   -  In this style, the formatting
    +                             directives described below, when
    +                             included in prompt strings, are
    +                             interpreted as follows:
    +
    +                               %B  -  Display subsequent
    +                                      characters with a bold
    +                                      font.
    +                               %b  -  Stop displaying characters
    +                                      with the bold font.
    +                               %F  -  Make subsequent characters
    +                                      flash.
    +                               %f  -  Turn off flashing
    +                                      characters.
    +                               %U  -  Underline subsequent
    +                                      characters.
    +                               %u  -  Stop underlining
    +                                      characters.
    +                               %P  -  Switch to a pale (half
    +                                      brightness) font.
    +                               %p  -  Stop using the pale font.
    +                               %S  -  Highlight subsequent
    +                                      characters (also known as
    +                                      standout mode).
    +                               %s  -  Stop highlighting
    +                                      characters.
    +                               %V  -  Turn on reverse video.
    +                               %v  -  Turn off reverse video.
    +                               %%  -  Display a single %
    +                                      character.
    +
    +                             For example, in this mode, a prompt
    +                             string like "%UOK%u$ " would
    +                             display the prompt "OK$ ",
    +                             but with the OK part
    +                             underlined.
    +
    +                             Note that although a pair of
    +                             characters that starts with a %
    +                             character, but doesn't match any of
    +                             the above directives is displayed
    +                             literally, if a new directive is
    +                             subsequently introduced which does
    +                             match, the displayed prompt will
    +                             change, so it is better to always
    +                             use %% to display a literal %.
    +
    +                             Also note that not all terminals
    +                             support all of these text
    +                             attributes, and that some substitute
    +                             a different attribute for missing
    +                             ones.
    +
    +       GL_LITERAL_PROMPT  -  In this style, the prompt string is
    +                             printed literally. This is the
    +                             default style.
    +
    +
    +
    +

    THE AVAILABLE KEY BINDING FUNCTIONS

    +     The gl_get_line() function provides a  number  of  functions
    +     which  can  be  bound  to  key sequences. The names of these
    +     functions, and what they do, are given below.
    +
    +       user-interrupt           -  Send a SIGINT signal to the
    +                                   parent process.
    +       abort                    -  Send a SIGABRT signal to the
    +                                   parent process.
    +       suspend                  -  Suspend the parent process.
    +       stop-output              -  Pause terminal output.
    +       start-output             -  Resume paused terminal output.
    +       literal-next             -  Arrange for the next character
    +                                   to be treated as a normal
    +                                   character. This allows control
    +                                   characters to be entered.
    +       cursor-right             -  Move the cursor one character
    +                                   right.
    +       cursor-left              -  Move the cursor one character
    +                                   left.
    +       insert-mode              -  Toggle between insert mode and
    +                                   overwrite mode.
    +       beginning-of-line        -  Move the cursor to the
    +                                   beginning of the line.
    +       end-of-line              -  Move the cursor to the end of
    +                                   the line.
    +       delete-line              -  Delete the contents of the
    +                                   current line.
    +       kill-line                -  Delete everything that follows
    +                                   the cursor.
    +       backward-kill-line       -  Delete all characters between
    +                                   the cursor and the start of the
    +                                   line.
    +       forward-word             -  Move to the end of the word
    +                                   which follows the cursor.
    +       forward-to-word          -  Move the cursor to the start of
    +                                   the word that follows the
    +                                   cursor.
    +       backward-word            -  Move to the start of the word
    +                                   which precedes the cursor.
    +       goto-column              -  Move the cursor to the
    +                                   1-relative column in the line
    +                                   specified by any preceding
    +                                   digit-argument sequences (see
    +                                   ENTERING REPEAT COUNTS below).
    +       find-parenthesis         -  If the cursor is currently
    +                                   over a parenthesis character,
    +                                   move it to the matching
    +                                   parenthesis character. If not
    +                                   over a parenthesis character
    +                                   move right to the next close
    +                                   parenthesis.
    +       forward-delete-char      -  Delete the character under the
    +                                   cursor.
    +       backward-delete-char     -  Delete the character which
    +                                   precedes the cursor.
    +       list-or-eof              -  This is intended for binding
    +                                   to ^D. When invoked when the
    +                                   cursor is within the line it
    +                                   displays all possible
    +                                   completions then redisplays
    +                                   the line unchanged. When
    +                                   invoked on an empty line, it
    +                                   signals end-of-input (EOF) to
    +                                   the caller of gl_get_line().
    +       del-char-or-list-or-eof  -  This is intended for binding
    +                                   to ^D. When invoked when the
    +                                   cursor is within the line it
    +                                   invokes forward-delete-char.
    +                                   When invoked at the end of the
    +                                   line it displays all possible
    +                                   completions then redisplays
    +                                   the line unchanged. When
    +                                   invoked on an empty line, it
    +                                   signals end-of-input (EOF) to
    +                                   the caller of gl_get_line().
    +       forward-delete-word      -  Delete the word which follows
    +                                   the cursor.
    +       backward-delete-word     -  Delete the word which precedes
    +                                   the cursor.
    +       upcase-word              -  Convert all of the characters
    +                                   of the word which follows the
    +                                   cursor, to upper case.
    +       downcase-word            -  Convert all of the characters
    +                                   of the word which follows the
    +                                   cursor, to lower case.
    +       capitalize-word          -  Capitalize the word which
    +                                   follows the cursor.
    +       change-case              -  If the next character is upper
    +                                   case, toggle it to lower case
    +                                   and vice versa.
    +       redisplay                -  Redisplay the line.
    +       clear-screen             -  Clear the terminal, then
    +                                   redisplay the current line.
    +       transpose-chars          -  Swap the character under the
    +                                   cursor with the character just
    +                                   before the cursor.
    +       set-mark                 -  Set a mark at the position of
    +                                   the cursor.
    +       exchange-point-and-mark  -  Move the cursor to the last
    +                                   mark that was set, and move
    +                                   the mark to where the cursor
    +                                   used to be.
    +       kill-region              -  Delete the characters that lie
    +                                   between the last mark that was
    +                                   set, and the cursor.
    +       copy-region-as-kill      -  Copy the text between the mark
    +                                   and the cursor to the cut
    +                                   buffer, without deleting the
    +                                   original text.
    +       yank                     -  Insert the text that was last
    +                                   deleted, just before the
    +                                   current position of the cursor.
    +       append-yank              -  Paste the current contents of
    +                                   the cut buffer, after the
    +                                   cursor.
    +       up-history               -  Recall the next oldest line
    +                                   that was entered. Note that
    +                                   in vi mode you are left in
    +                                   command mode.
    +       down-history             -  Recall the next most recent
    +                                   line that was entered. If no
    +                                   history recall session is
    +                                   currently active, the next
    +                                   line from a previous recall
    +                                   session is recalled. Note that
    +                                   in vi mode you are left in
    +                                   command mode.
    +       history-search-backward  -  Recall the next oldest line
    +                                   who's prefix matches the string
    +                                   which currently precedes the
    +                                   cursor (in vi command-mode the
    +                                   character under the cursor is
    +                                   also included in the search
    +                                   string).  Note that in vi mode
    +                                   you are left in command mode.
    +       history-search-forward   -  Recall the next newest line
    +                                   who's prefix matches the string
    +                                   which currently precedes the
    +                                   cursor (in vi command-mode the
    +                                   character under the cursor is
    +                                   also included in the search
    +                                   string).  Note that in vi mode
    +                                   you are left in command mode.
    +       history-re-search-backward -Recall the next oldest line
    +                                   who's prefix matches that
    +                                   established by the last
    +                                   invocation of either
    +                                   history-search-forward or
    +                                   history-search-backward.
    +       history-re-search-forward - Recall the next newest line
    +                                   who's prefix matches that
    +                                   established by the last
    +                                   invocation of either
    +                                   history-search-forward or
    +                                   history-search-backward.
    +       complete-word            -  Attempt to complete the
    +                                   incomplete word which
    +                                   precedes the cursor. Unless
    +                                   the host program has customized
    +                                   word completion, filename
    +                                   completion is attempted. In vi
    +                                   commmand mode the character
    +                                   under the cursor is also
    +                                   included in the word being
    +                                   completed, and you are left in
    +                                   vi insert mode.
    +       expand-filename          -  Within the command line, expand
    +                                   wild cards, tilde expressions
    +                                   and dollar expressions in the
    +                                   filename which immediately
    +                                   precedes the cursor. In vi
    +                                   commmand mode the character
    +                                   under the cursor is also
    +                                   included in the filename being
    +                                   expanded, and you are left in
    +                                   vi insert mode.
    +       list-glob                -  List any filenames which match
    +                                   the wild-card, tilde and dollar
    +                                   expressions in the filename
    +                                   which immediately precedes the
    +                                   cursor, then redraw the input
    +                                   line unchanged.
    +       list-history             -  Display the contents of the
    +                                   history list for the current
    +                                   history group. If a repeat
    +                                   count of > 1 is specified,
    +                                   only that many of the most
    +                                   recent lines are displayed.
    +                                   See the "ENTERING REPEAT
    +                                   COUNTS" section.
    +       read-from-file           -  Temporarily switch to reading
    +                                   input from the file who's
    +                                   name precedes the cursor.
    +       read-init-files          -  Re-read teclarc configuration
    +                                   files.
    +       beginning-of-history     -  Move to the oldest line in the
    +                                   history list. Note that in vi
    +                                   mode you are left in command
    +                                   mode.
    +       end-of-history           -  Move to the newest line in the
    +                                   history list (ie. the current
    +                                   line). Note that in vi mode
    +                                   this leaves you in command
    +                                   mode.
    +       digit-argument           -  Enter a repeat count for the
    +                                   next key-binding function.
    +                                   For details, see the ENTERING
    +                                   REPEAT COUNTS section.
    +       newline                  -  Terminate and return the
    +                                   current contents of the
    +                                   line, after appending a
    +                                   newline character. The newline
    +                                   character is normally '\n',
    +                                   but will be the first
    +                                   character of the key-sequence
    +                                   that invoked the newline
    +                                   action, if this happens to be
    +                                   a printable character. If the
    +                                   action was invoked by the
    +                                   '\n' newline character or the
    +                                   '\r' carriage return
    +                                   character, the line is
    +                                   appended to the history
    +                                   buffer.
    +       repeat-history           -  Return the line that is being
    +                                   edited, then arrange for the
    +                                   next most recent entry in the
    +                                   history buffer to be recalled
    +                                   when gl_get_line() is
    +                                   next called. Repeatedly
    +                                   invoking this action causes
    +                                   successive historical input
    +                                   lines to be re-executed. Note
    +                                   that this action is equivalent
    +                                   to the 'Operate' action in
    +                                   ksh.
    +       ring-bell                -  Ring the terminal bell, unless
    +                                   the bell has been silenced via
    +                                   the nobeep configuration
    +                                   option (see the THE TECLA
    +                                   CONFIGURATION FILE section).
    +       forward-copy-char        -  Copy the next character into
    +                                   the cut buffer (NB. use repeat
    +                                   counts to copy more than one).
    +       backward-copy-char       -  Copy the previous character
    +                                   into the cut buffer.
    +       forward-copy-word        -  Copy the next word into the cut
    +                                   buffer.
    +       backward-copy-word       -  Copy the previous word into the
    +                                   cut buffer.
    +       forward-find-char        -  Move the cursor to the next
    +                                   occurrence of the next
    +                                   character that you type.
    +       backward-find-char       -  Move the cursor to the last
    +                                   occurrence of the next
    +                                   character that you type.
    +       forward-to-char          -  Move the cursor to the
    +                                   character just before the next
    +                                   occurrence of the next
    +                                   character that the user types.
    +       backward-to-char         -  Move the cursor to the
    +                                   character just after the last
    +                                   occurrence before the cursor
    +                                   of the next character that the
    +                                   user types.
    +       repeat-find-char         -  Repeat the last
    +                                   backward-find-char,
    +                                   forward-find-char,
    +                                   backward-to-char or
    +                                   forward-to-char.
    +       invert-refind-char       -  Repeat the last
    +                                   backward-find-char,
    +                                   forward-find-char,
    +                                   backward-to-char, or
    +                                   forward-to-char in the
    +                                   opposite direction.
    +       delete-to-column         -  Delete the characters from the
    +                                   cursor up to the column that
    +                                   is specified by the repeat
    +                                   count.
    +       delete-to-parenthesis    -  Delete the characters from the
    +                                   cursor up to and including
    +                                   the matching parenthesis, or
    +                                   next close parenthesis.
    +       forward-delete-find      -  Delete the characters from the
    +                                   cursor up to and including the
    +                                   following occurence of the
    +                                   next character typed.
    +       backward-delete-find     -  Delete the characters from the
    +                                   cursor up to and including the
    +                                   preceding occurence of the
    +                                   next character typed.
    +       forward-delete-to        -  Delete the characters from the
    +                                   cursor up to, but not
    +                                   including, the following
    +                                   occurence of the next
    +                                   character typed.
    +       backward-delete-to       -  Delete the characters from the
    +                                   cursor up to, but not
    +                                   including, the preceding
    +                                   occurence of the next
    +                                   character typed.
    +       delete-refind            -  Repeat the last *-delete-find
    +                                   or *-delete-to action.
    +       delete-invert-refind     -  Repeat the last *-delete-find
    +                                   or *-delete-to action, in the
    +                                   opposite direction.
    +       copy-to-column           -  Copy the characters from the
    +                                   cursor up to the column that
    +                                   is specified by the repeat
    +                                   count, into the cut buffer.
    +       copy-to-parenthesis      -  Copy the characters from the
    +                                   cursor up to and including
    +                                   the matching parenthesis, or
    +                                   next close parenthesis, into
    +                                   the cut buffer.
    +       forward-copy-find        -  Copy the characters from the
    +                                   cursor up to and including the
    +                                   following occurence of the
    +                                   next character typed, into the
    +                                   cut buffer.
    +       backward-copy-find       -  Copy the characters from the
    +                                   cursor up to and including the
    +                                   preceding occurence of the
    +                                   next character typed, into the
    +                                   cut buffer.
    +       forward-copy-to          -  Copy the characters from the
    +                                   cursor up to, but not
    +                                   including, the following
    +                                   occurence of the next
    +                                   character typed, into the cut
    +                                   buffer.
    +       backward-copy-to         -  Copy the characters from the
    +                                   cursor up to, but not
    +                                   including, the preceding
    +                                   occurence of the next
    +                                   character typed, into the cut
    +                                   buffer.
    +       copy-refind              -  Repeat the last *-copy-find
    +                                   or *-copy-to action.
    +       copy-invert-refind       -  Repeat the last *-copy-find
    +                                   or *-copy-to action, in the
    +                                   opposite direction.
    +       vi-mode                  -  Switch to vi mode from emacs
    +                                   mode.
    +       emacs-mode               -  Switch to emacs mode from vi
    +                                   mode.
    +       vi-insert                -  From vi command mode, switch to
    +                                   insert mode.
    +       vi-overwrite             -  From vi command mode, switch to
    +                                   overwrite mode.
    +       vi-insert-at-bol         -  From vi command mode, move the
    +                                   cursor to the start of the line
    +                                   and switch to insert mode.
    +       vi-append-at-eol         -  From vi command mode, move the
    +                                   cursor to the end of the line
    +                                   and switch to append mode.
    +       vi-append                -  From vi command mode, move the
    +                                   cursor one position right, and
    +                                   switch to insert mode.
    +       vi-replace-char          -  From vi command mode, replace
    +                                   the character under the cursor
    +                                   with the the next character
    +                                   entered.
    +       vi-forward-change-char   -  From vi command mode, delete
    +                                   the next character then enter
    +                                   insert mode.
    +       vi-backward-change-char  -  From vi command mode, delete
    +                                   the preceding character then
    +                                   enter insert mode.
    +       vi-forward-change-word   -  From vi command mode, delete
    +                                   the next word then enter
    +                                   insert mode.
    +       vi-backward-change-word  -  From vi command mode, delete
    +                                   the preceding word then
    +                                   enter insert mode.
    +       vi-change-rest-of-line   -  From vi command mode, delete
    +                                   from the cursor to the end of
    +                                   the line, then enter insert
    +                                   mode.
    +       vi-change-line           -  From vi command mode, delete
    +                                   the current line, then enter
    +                                   insert mode.
    +       vi-change-to-bol         -  From vi command mode, delete
    +                                   all characters between the
    +                                   cursor and the beginning of
    +                                   the line, then enter insert
    +                                   mode.
    +       vi-change-to-column      -  From vi command mode, delete
    +                                   the characters from the cursor
    +                                   up to the column that is
    +                                   specified by the repeat count,
    +                                   then enter insert mode.
    +       vi-change-to-parenthesis -  Delete the characters from the
    +                                   cursor up to and including
    +                                   the matching parenthesis, or
    +                                   next close parenthesis, then
    +                                   enter vi insert mode.
    +       vi-forward-change-find   -  From vi command mode, delete
    +                                   the characters from the
    +                                   cursor up to and including the
    +                                   following occurence of the
    +                                   next character typed, then
    +                                   enter insert mode.
    +       vi-backward-change-find  -  From vi command mode, delete
    +                                   the characters from the
    +                                   cursor up to and including the
    +                                   preceding occurence of the
    +                                   next character typed, then
    +                                   enter insert mode.
    +       vi-forward-change-to     -  From vi command mode, delete
    +                                   the characters from the
    +                                   cursor up to, but not
    +                                   including, the following
    +                                   occurence of the next
    +                                   character typed, then enter
    +                                   insert mode.
    +       vi-backward-change-to    -  From vi command mode, delete
    +                                   the characters from the
    +                                   cursor up to, but not
    +                                   including, the preceding
    +                                   occurence of the next
    +                                   character typed, then enter
    +                                   insert mode.
    +       vi-change-refind         -  Repeat the last
    +                                   vi-*-change-find or
    +                                   vi-*-change-to action.
    +       vi-change-invert-refind  -  Repeat the last
    +                                   vi-*-change-find or
    +                                   vi-*-change-to action, in the
    +                                   opposite direction.
    +       vi-undo                  -  In vi mode, undo the last
    +                                   editing operation.
    +       vi-repeat-change         -  In vi command mode, repeat the
    +                                   last command that modified the
    +                                   line.
    +
    +
    +

    DEFAULT KEY BINDINGS IN EMACS MODE

    +     The following default key bindings, which can  be  overriden
    +     by  the tecla configuration file, are designed to mimic most
    +     of the bindings of the unix tcsh shell, when it is in  emacs
    +     editing mode.
    +
    +     This is the default editing mode of the tecla library.
    +
    +     Note that a key sequence like  ^A  or  C-a  means  hold  the
    +     control-key down while pressing the letter A, and that where
    +     you see \E or M- in a binding, this  represents  the  escape
    +     key   or   the   Meta   modifier  key.  Also  note  that  to
    +     gl_get_line(), pressing the  escape  key  before  a  key  is
    +     equivalent to pressing the meta key at the same time as that
    +     key. Thus the key sequence M-p can be typed in two ways,  by
    +     pressing  the  escape  key,  followed  by  pressing p, or by
    +     pressing the Meta key at the same time as p.
    +
    +     Under UNIX the terminal driver sets a number of special keys
    +     for certain functions. The tecla library attempts to use the
    +     same keybindings to maintain consistency. The key  sequences
    +     shown for the following 6 bindings are thus just examples of
    +     what they will probably be set to. If you have used the stty
    +     command  to  change  these  keys,  then the default bindings
    +     should match.
    +
    +       ^C     ->   user-interrupt
    +       ^\     ->   abort
    +       ^Z     ->   suspend
    +       ^Q     ->   start-output
    +       ^S     ->   stop-output
    +       ^V     ->   literal-next
    +
    +     The cursor keys are refered to by name, as follows. This  is
    +     necessary because different types of terminals generate dif-
    +     ferent key sequences when their cursor keys are pressed.
    +
    +       right  ->   cursor-right
    +       left   ->   cursor-left
    +       up     ->   up-history
    +       down   ->   down-history
    +
    +     The remaining bindings don't depend on  the  terminal  sett-
    +     tings.
    +
    +       ^F     ->   cursor-right
    +       ^B     ->   cursor-left
    +       M-i    ->   insert-mode
    +       ^A     ->   beginning-of-line
    +       ^E     ->   end-of-line
    +       ^U     ->   delete-line
    +       ^K     ->   kill-line
    +       M-f    ->   forward-word
    +       M-b    ->   backward-word
    +       ^D     ->   del-char-or-list-or-eof
    +       ^H     ->   backward-delete-char
    +       ^?     ->   backward-delete-char
    +       M-d    ->   forward-delete-word
    +       M-^H   ->   backward-delete-word
    +       M-^?   ->   backward-delete-word
    +       M-u    ->   upcase-word
    +       M-l    ->   downcase-word
    +       M-c    ->   capitalize-word
    +       ^R     ->   redisplay
    +       ^L     ->   clear-screen
    +       ^T     ->   transpose-chars
    +       ^@     ->   set-mark
    +       ^X^X   ->   exchange-point-and-mark
    +       ^W     ->   kill-region
    +       M-w    ->   copy-region-as-kill
    +       ^Y     ->   yank
    +       ^P     ->   up-history
    +       ^N     ->   down-history
    +       M-p    ->   history-search-backward
    +       M-n    ->   history-search-forward
    +       ^I     ->   complete-word
    +       ^X*    ->   expand-filename
    +       ^X^F   ->   read-from-file
    +       ^X^R   ->   read-init-files
    +       ^Xg    ->   list-glob
    +       ^Xh    ->   list-history
    +       M-<    ->   beginning-of-history
    +       M->    ->   end-of-history
    +       \n     ->   newline
    +       \r     ->   newline
    +       M-o    ->   repeat-history
    +       M-^V   ->   vi-mode
    +
    +       M-0, M-1, ... M-9  ->  digit-argument  (see below)
    +
    +     Note that ^I is what the TAB key generates, and that ^@  can
    +     be  generated not only by pressing the control key and the @
    +     key simultaneously, but also by pressing the control key and
    +     the space bar at the same time.
    +
    +
    +

    DEFAULT KEY BINDINGS IN VI MODE

    +     The following default key bindings are designed to mimic the
    +     vi  style of editing as closely as possible. This means that
    +     very few editing functions are provided in the initial char-
    +     acter  input  mode, editing functions instead being provided
    +     by the vi command mode. Vi command mode is entered  whenever
    +     the  escape character is pressed, or whenever a key-sequence
    +     that starts with a meta character is entered. In addition to
    +     mimicing  vi, libtecla provides bindings for tab completion,
    +     wild-card expansion  of  file  names,  and  historical  line
    +     recall.
    +
    +     To learn how to tell  the  tecla  library  to  use  vi  mode
    +     instead  of  the default emacs editing mode, see the section
    +     entitled THE TECLA CONFIGURATION FILE.
    +
    +     As already mentioned above in the emacs section, Note that a
    +     key  sequence like ^A or C-a means hold the control-key down
    +     while pressing the letter A, and that where you see \E or M-
    +     in  a  binding,  this  represents the escape key or the Meta
    +     modifier key. Also note that to gl_get_line(), pressing  the
    +     escape  key  before a key is equivalent to pressing the meta
    +     key at the same time as that key. Thus the key sequence  M-p
    +     can  be  typed in two ways, by pressing the escape key, fol-
    +     lowed by pressing p, or by pressing the Meta key at the same
    +     time as p.
    +
    +     Under UNIX the terminal driver sets a number of special keys
    +     for certain functions. The tecla library attempts to use the
    +     same keybindings to maintain consistency, binding them  both
    +     in  input  mode and in command mode. The key sequences shown
    +     for the following 6 bindings are thus just examples of  what
    +     they will probably be set to. If you have used the stty com-
    +     mand to change these keys, then the default bindings  should
    +     match.
    +
    +       ^C     ->   user-interrupt
    +       ^\     ->   abort
    +       ^Z     ->   suspend
    +       ^Q     ->   start-output
    +       ^S     ->   stop-output
    +       ^V     ->   literal-next
    +       M-^C   ->   user-interrupt
    +       M-^\   ->   abort
    +       M-^Z   ->   suspend
    +       M-^Q   ->   start-output
    +       M-^S   ->   stop-output
    +
    +     Note that above, most of the  bindings  are  defined  twice,
    +     once as a raw control code like ^C and then a second time as
    +     a meta character like M-^C. The former is the binding for vi
    +     input mode, whereas the latter is the binding for vi command
    +     mode. Once in command mode all key-sequences that  the  user
    +     types  that  they don't explicitly start with an escape or a
    +     meta key, have their first key secretly converted to a  meta
    +     character  before  the  key sequence is looked up in the key
    +     binding table. Thus, once in command mode, when you type the
    +     letter  i,  for example, the tecla library actually looks up
    +     the binding for M-i.
    +
    +     The cursor keys are refered to by name, as follows. This  is
    +     necessary because different types of terminals generate dif-
    +     ferent key sequences when their cursor keys are pressed.
    +
    +       right  ->   cursor-right
    +       left   ->   cursor-left
    +       up     ->   up-history
    +       down   ->   down-history
    +
    +     The cursor keys normally generate a keysequence  that  start
    +     with  an  escape  character,  so beware that using the arrow
    +     keys will put you into command mode (if you  aren't  already
    +     in command mode).
    +
    +     The following are the terminal-independent key bindings  for
    +     vi input mode.
    +
    +       ^D     ->   list-or-eof
    +       ^G     ->   list-glob
    +       ^H     ->   backward-delete-char
    +       ^I     ->   complete-word
    +       \r     ->   newline
    +       \n     ->   newline
    +       ^L     ->   clear-screen
    +       ^N     ->   down-history
    +       ^P     ->   up-history
    +       ^R     ->   redisplay
    +       ^U     ->   backward-kill-line
    +       ^W     ->   backward-delete-word
    +       ^X*    ->   expand-filename
    +       ^X^F   ->   read-from-file
    +       ^X^R   ->   read-init-files
    +       ^?     ->   backward-delete-char
    +
    +     The following are the key bindings that are  defined  in  vi
    +     command mode, this being specified by them all starting with
    +     a meta character. As mentioned above, once in  command  mode
    +     the  initial  meta  character  is optional. For example, you
    +     might enter command mode by typing Esc,  and  then  press  h
    +     twice  to  move the cursor two positions to the left. Both h
    +     characters get quietly converted to M-h  before  being  com-
    +     pared to the key-binding table, the first one because Escape
    +     followed  by  a  character  is  always  converted   to   the
    +     equivalent  meta  character,  and the second because command
    +     mode was already active.
    +
    +       M-\     ->   cursor-right     (Meta-space)
    +       M-$     ->   end-of-line
    +       M-*     ->   expand-filename
    +       M-+     ->   down-history
    +       M--     ->   up-history
    +       M-<     ->   beginning-of-history
    +       M->     ->   end-of-history
    +       M-^     ->   beginning-of-line
    +       M-;     ->   repeat-find-char
    +       M-,     ->   invert-refind-char
    +       M-|     ->   goto-column
    +       M-~     ->   change-case
    +       M-.     ->   vi-repeat-change
    +       M-%     ->   find-parenthesis
    +       M-a     ->   vi-append
    +       M-A     ->   vi-append-at-eol
    +       M-b     ->   backward-word
    +       M-B     ->   backward-word
    +       M-C     ->   vi-change-rest-of-line
    +       M-cb    ->   vi-backward-change-word
    +       M-cB    ->   vi-backward-change-word
    +       M-cc    ->   vi-change-line
    +       M-ce    ->   vi-forward-change-word
    +       M-cE    ->   vi-forward-change-word
    +       M-cw    ->   vi-forward-change-word
    +       M-cW    ->   vi-forward-change-word
    +       M-cF    ->   vi-backward-change-find
    +       M-cf    ->   vi-forward-change-find
    +       M-cT    ->   vi-backward-change-to
    +       M-ct    ->   vi-forward-change-to
    +       M-c;    ->   vi-change-refind
    +       M-c,    ->   vi-change-invert-refind
    +       M-ch    ->   vi-backward-change-char
    +       M-c^H   ->   vi-backward-change-char
    +       M-c^?   ->   vi-backward-change-char
    +       M-cl    ->   vi-forward-change-char
    +       M-c\    ->   vi-forward-change-char  (Meta-c-space)
    +       M-c^    ->   vi-change-to-bol
    +       M-c0    ->   vi-change-to-bol
    +       M-c$    ->   vi-change-rest-of-line
    +       M-c|    ->   vi-change-to-column
    +       M-c%    ->   vi-change-to-parenthesis
    +       M-dh    ->   backward-delete-char
    +       M-d^H   ->   backward-delete-char
    +       M-d^?   ->   backward-delete-char
    +       M-dl    ->   forward-delete-char
    +       M-d     ->   forward-delete-char    (Meta-d-space)
    +       M-dd    ->   delete-line
    +       M-db    ->   backward-delete-word
    +       M-dB    ->   backward-delete-word
    +       M-de    ->   forward-delete-word
    +       M-dE    ->   forward-delete-word
    +       M-dw    ->   forward-delete-word
    +       M-dW    ->   forward-delete-word
    +       M-dF    ->   backward-delete-find
    +       M-df    ->   forward-delete-find
    +       M-dT    ->   backward-delete-to
    +       M-dt    ->   forward-delete-to
    +       M-d;    ->   delete-refind
    +       M-d,    ->   delete-invert-refind
    +       M-d^    ->   backward-kill-line
    +       M-d0    ->   backward-kill-line
    +       M-d$    ->   kill-line
    +       M-D     ->   kill-line
    +       M-d|    ->   delete-to-column
    +       M-d%    ->   delete-to-parenthesis
    +       M-e     ->   forward-word
    +       M-E     ->   forward-word
    +       M-f     ->   forward-find-char
    +       M-F     ->   backward-find-char
    +       M--     ->   up-history
    +       M-h     ->   cursor-left
    +       M-H     ->   beginning-of-history
    +       M-i     ->   vi-insert
    +       M-I     ->   vi-insert-at-bol
    +       M-j     ->   down-history
    +       M-J     ->   history-search-forward
    +       M-k     ->   up-history
    +       M-K     ->   history-search-backward
    +       M-l     ->   cursor-right
    +       M-L     ->   end-of-history
    +       M-n     ->   history-re-search-forward
    +       M-N     ->   history-re-search-backward
    +       M-p     ->   append-yank
    +       M-P     ->   yank
    +       M-r     ->   vi-replace-char
    +       M-R     ->   vi-overwrite
    +       M-s     ->   vi-forward-change-char
    +       M-S     ->   vi-change-line
    +       M-t     ->   forward-to-char
    +       M-T     ->   backward-to-char
    +       M-u     ->   vi-undo
    +       M-w     ->   forward-to-word
    +       M-W     ->   forward-to-word
    +       M-x     ->   forward-delete-char
    +       M-X     ->   backward-delete-char
    +       M-yh    ->   backward-copy-char
    +       M-y^H   ->   backward-copy-char
    +       M-y^?   ->   backward-copy-char
    +       M-yl    ->   forward-copy-char
    +       M-y\    ->   forward-copy-char  (Meta-y-space)
    +       M-ye    ->   forward-copy-word
    +       M-yE    ->   forward-copy-word
    +       M-yw    ->   forward-copy-word
    +       M-yW    ->   forward-copy-word
    +       M-yb    ->   backward-copy-word
    +       M-yB    ->   backward-copy-word
    +       M-yf    ->   forward-copy-find
    +       M-yF    ->   backward-copy-find
    +       M-yt    ->   forward-copy-to
    +       M-yT    ->   backward-copy-to
    +       M-y;    ->   copy-refind
    +       M-y,    ->   copy-invert-refind
    +       M-y^    ->   copy-to-bol
    +       M-y0    ->   copy-to-bol
    +       M-y$    ->   copy-rest-of-line
    +       M-yy    ->   copy-line
    +       M-Y     ->   copy-line
    +       M-y|    ->   copy-to-column
    +       M-y%    ->   copy-to-parenthesis
    +       M-^E    ->   emacs-mode
    +       M-^H    ->   cursor-left
    +       M-^?    ->   cursor-left
    +       M-^L    ->   clear-screen
    +       M-^N    ->   down-history
    +       M-^P    ->   up-history
    +       M-^R    ->   redisplay
    +       M-^D    ->   list-or-eof
    +       M-^I    ->   complete-word
    +       M-\r    ->   newline
    +       M-\n    ->   newline
    +       M-^X^R  ->   read-init-files
    +       M-^Xh   ->   list-history
    +
    +       M-0, M-1, ... M-9  ->  digit-argument  (see below)
    +
    +     Note that ^I is what the TAB key generates.
    +
    +
    +

    ENTERING REPEAT COUNTS

    +     Many of the key binding functions described previously, take
    +     an  optional  count, typed in before the target keysequence.
    +     This is interpreted as a repeat count by  most  bindings.  A
    +     notable  exception  is the goto-column binding, which inter-
    +     prets the count as a column number.
    +
    +     By default you can specify this count argument  by  pressing
    +     the  meta key while typing in the numeric count. This relies
    +     on the digit-argument action being bound to  Meta-0,  Meta-1
    +     etc.  Once any one of these bindings has been activated, you
    +     can optionally take your finger off the meta key to type  in
    +     the rest of the number, since every numeric digit thereafter
    +     is treated as part of the number, unless it is  preceded  by
    +     the literal-next binding. As soon as a non-digit, or literal
    +     digit key is pressed the  repeat  count  is  terminated  and
    +     either  causes  the  just typed character to be added to the
    +     line that many times, or causes the next  key-binding  func-
    +     tion to be given that argument.
    +
    +     For example, in emacs mode, typing:
    +
    +       M-12a
    +
    +     causes the letter 'a' to be added  to  the  line  12  times,
    +     whereas
    +
    +       M-4M-c
    +
    +     Capitalizes the next 4 words.
    +
    +     In vi command mode the Meta modifier is automatically  added
    +     to  all  characters  typed  in,  so  to  enter a count in vi
    +     command-mode, just involves typing in the number, just as at
    +     it  does in the vi editor itself. So for example, in vi com-
    +     mand mode, typing:
    +
    +       4w2x
    +
    +     moves the cursor four words to the right, then  deletes  two
    +     characters.
    +
    +     You can also bind digit-argument to other key sequences.  If
    +     these  end  in  a numeric digit, that digit gets appended to
    +     the current repeat count. If it doesn't  end  in  a  numeric
    +     digit,  a  new repeat count is started with a value of zero,
    +     and can be completed by typing in the number, after  letting
    +     go of the key which triggered the digit-argument action.
    +
    +
    +

    THE TECLA CONFIGURATION FILE

    +     By default, the first call to gl_get_line() looks for a file
    +     called .teclarc in your home directory (ie. ~/.teclarc).  If
    +     it finds this file, it reads it, interpreting each  line  as
    +     defining  a  new  key  binding  or  an editing configuration
    +     option.  Since  the  emacs  keybindings  are  installed   by
    +     default, if you want to use the non-default vi editing mode,
    +     the most important item to go in this file is the  following
    +     line:
    +
    +       edit-mode vi
    +
    +     This will re-configure the default bindings for vi-mode. The
    +     complete set of arguments that this command accepts are:
    +
    +       vi     -  Install key-bindings like those of the vi
    +                 editor.
    +       emacs  -  Install key-bindings like those of the emacs
    +                 editor. This is the default.
    +       none   -  Use just the native line editing facilities
    +                 provided by the terminal driver.
    +
    +     To prevent the terminal bell from being rung, such  as  when
    +     an unrecognized control-sequence is typed, place the follow-
    +     ing line in the configuration file:
    +
    +       nobeep
    +
    +     An example of a key binding line in the  configuration  file
    +     is the following.
    +
    +       bind M-[2~ insert-mode
    +
    +     On many keyboards, the above key sequence is generated  when
    +     one presses the insert key, so with this keybinding, one can
    +     toggle between the emacs-mode insert and overwrite modes  by
    +     hitting  one  key.  One  could  also do it by typing out the
    +     above sequence of characters one by one. As explained above,
    +     the M- part of this sequence can be typed either by pressing
    +     the escape key before the following key, or by pressing  the
    +     Meta  key at the same time as the following key. Thus if you
    +     had set the above key binding, and the insert  key  on  your
    +     keyboard  didn't  generate the above key sequence, you could
    +     still type it in either of the following 2 ways.
    +
    +       1. Hit the escape key momentarily, then press '[', then '2', then
    +          finally '~'.
    +
    +       2. Press the meta key at the same time as pressing the '[' key,
    +          then press '2', then '~'.
    +
    +     If you set a keybinding for a key-sequence that  is  already
    +     bound  to a function, the new binding overrides the old one.
    +     If in the new binding you omit the name of the new  function
    +     to  bind  to  the key-sequence, the original binding becomes
    +     undefined.
    +
    +     Starting with versions of libtecla later than  1.3.3  it  is
    +     now  possible  to bind keysequences that begin with a print-
    +     able character. Previously key-sequences  were  required  to
    +     start with a control or meta character.
    +
    +     Note that the special  keywords  "up",  "down",  "left"  and
    +     "right" refer to the arrow keys, and are thus not treated as
    +     keysequences. So, for example, to rebind  the  up  and  down
    +     arrow  keys  to  use the history search mechanism instead of
    +     the simple history recall method, you could place  the  fol-
    +     lowing in your configuration file:
    +
    +       bind up history-search-backwards
    +       bind down history-search-backwards
    +
    +     To unbind an existing binding, you can do this with the bind
    +     command  by  omitting  to  name any action to rebind the key
    +     sequence to.  For example, by not specifying an action func-
    +     tion,  the  following command unbinds the default beginning-
    +     of-line action from the ^A key sequence:
    +
    +       bind ^A
    +
    +
    +

    ALTERNATE CONFIGURATION SOURCES

    +     As mentioned above, by default users have the option of con-
    +     figuring  the  behavior of gl_get_line() via a configuration
    +     file called .teclarc in their  home  directories.  The  fact
    +     that  all applications share this same configuration file is
    +     both an advantage and a disadvantage.  In most cases  it  is
    +     an  advantage, since it encourages uniformity, and frees the
    +     user from having to configure each  application  separately.
    +     In  some  applications, however, this single means of confi-
    +     guration is a problem. This is particularly true of embedded
    +     software,  where  there's no filesystem to read a configura-
    +     tion file from, and also in applications where  a  radically
    +     different  choice  of  keybindings  is  needed  to emulate a
    +     legacy keyboard interface.  To cater  for  such  cases,  the
    +     following  function  allows the application to control where
    +     configuration information is read from.
    +
    +
    +       int gl_configure_getline(GetLine *gl,
    +                                const char *app_string,
    +                                const char *app_file,
    +                                const char *user_file);
    +
    +
    +     It allows the configuration commands that would normally  be
    +     read  from  a user's ~/.teclarc file, to be read from any or
    +     none of, a string,  an  application  specific  configuration
    +     file,  and/or  a  user-specific  configuration file. If this
    +     function is called before the first call  to  gl_get_line(),
    +     the default behavior of reading ~/.teclarc on the first call
    +     to gl_get_line() is disabled, so all configuration  must  be
    +     achieved using the configuration sources specified with this
    +     function.
    +
    +     If app_string != NULL, then it is interpreted  as  a  string
    +     containing  one  or  more  configuration commands, separated
    +     from each other in the string by  embedded  newline  charac-
    +     ters. If app_file != NULL then it is interpreted as the full
    +     pathname of an application-specific configuration  file.  If
    +     user_file  !=  NULL then it is interpreted as the full path-
    +     name  of  a  user-specific  configuration  file,   such   as
    +     ~/.teclarc. For example, in the following call,
    +
    +       gl_configure_getline(gl, "edit-mode vi \n nobeep",
    +                                "/usr/share/myapp/teclarc",
    +                                "~/.teclarc");
    +
    +     the app_string argument causes the  calling  application  to
    +     start  in  vi  edit-mode, instead of the default emacs mode,
    +     and turns off the use of the terminal bell by  the  library.
    +     It  then attempts to read system-wide configuration commands
    +     from an optional file called /usr/share/myapp/teclarc,  then
    +     finally  reads  user-specific configuration commands from an
    +     optional .teclarc file in the user's  home  directory.  Note
    +     that  the  arguments are listed in ascending order of prior-
    +     ity, with the contents of app_string being potentially over-
    +     riden  by  commands  in  app_file,  and commands in app_file
    +     potentially being overriden by commands in user_file.
    +     You can call this function as  many  times  as  needed,  the
    +     results  being  cumulative,  but  note  that  copies  of any
    +     filenames specified via the app_file and user_file arguments
    +     are  recorded  internally  for  subsequent  use by the read-
    +     init-files key-binding function, so if you plan to call this
    +     function  multiple  times, be sure that the last call speci-
    +     fies the filenames that  you  want  re-read  when  the  user
    +     requests that the configuration files be re-read.
    +
    +
    +

    FILENAME AND TILDE COMPLETION

    +     With the default key bindings, pressing the  TAB  key  (aka.
    +     ^I)  results  in  gl_get_line()  attempting  to complete the
    +     incomplete filename that precedes the cursor.  gl_get_line()
    +     searches backwards from the cursor, looking for the start of
    +     the filename, stopping when it hits either a  space  or  the
    +     start  of  the line. If more than one file has the specified
    +     prefix, gl_get_line() completes the filename up to the point
    +     at  which  the ambiguous matches start to differ, then lists
    +     the possible matches.
    +
    +     In addition to literally  written  filenames,  gl_get_line()
    +     can complete files that start with ~/ and ~user/ expressions
    +     and that contain $envvar expressions. In particular, if  you
    +     hit    TAB   within   an   incomplete   ~user,   expression,
    +     gl_get_line() will attempt to complete the username, listing
    +     any ambiguous matches.
    +
    +     The   completion   binding   is   implemented   using    the
    +     cpl_word_completions()  function,  which  is  also available
    +     separately   to   users   of   this   library.    See    the
    +     cpl_word_completions(3) man page for more details.
    +
    +
    +

    CUSTOMIZED WORD COMPLETION

    +     If in your application, you would like to have  TAB  comple-
    +     tion  complete  other  things  in  addition to or instead of
    +     filenames, you can arrange this by registering an  alternate
    +     completion   callback   function,   via   a   call   to  the
    +     gl_customize_completion() function.
    +
    +       int gl_customize_completion(GetLine *gl, void *data,
    +                                   CplMatchFn *match_fn);
    +
    +     The data argument provides a way  for  your  application  to
    +     pass  arbitrary,  application-specific  information  to  the
    +     callback function. This is passed to the callback every time
    +     that it is called. It might for example, point to the symbol
    +     table from which possible completions are to be sought.  The
    +     match_fn  argument  specifies  the  callback  function to be
    +     called.  The  CplMatchFn  function  type   is   defined   in
    +     libtecla.h, as is a CPL_MATCH_FN() macro that you can use to
    +     declare and prototype callback  functions.  The  declaration
    +     and  responsibilities of callback functions are described in
    +     depth in the cpl_complete_word(3) man page.
    +
    +     In brief, the callback function is responsible  for  looking
    +     backwards  in  the  input line, back from the point at which
    +     the user pressed TAB, to find the start of  the  word  being
    +     completed.  It then must lookup possible completions of this
    +     word, and record them  one  by  one  in  the  WordCompletion
    +     object  that  is passed to it as an argument, by calling the
    +     cpl_add_completion()  function.  If  the  callback  function
    +     wishes to provide filename completion in addition to its own
    +     specific completions, it has the option  of  itself  calling
    +     the  builtin  file-name  completion  callback. This also, is
    +     documented in the cpl_complete_word(3) man page.
    +
    +     Note that if you would  like  gl_get_line()  to  return  the
    +     current  input  line  when  a  successful completion is been
    +     made,   you    can    arrange    this    when    you    call
    +     cpl_add_completion(),  by  making  the last character of the
    +     continuation suffix a newline character. If you do this, the
    +     input  line  will  be  updated  to  display  the completion,
    +     together with any contiuation suffix up to the newline char-
    +     acter, then gl_get_line() will return this input line.
    +
    +
    +

    FILENAME EXPANSION

    +     With  the  default  key  bindings,   pressing   ^X*   causes
    +     gl_get_line()  to expand the filename that precedes the cur-
    +     sor,  replacing  ~/  and   ~user/   expressions   with   the
    +     corresponding   home   directories,  and  replacing  $envvar
    +     expressions with the  value  of  the  specified  environment
    +     variable,  then if there are any wildcards, replacing the so
    +     far expanded filename with a  space-separated  list  of  the
    +     files which match the wild cards.
    +
    +     The   expansion   binding   is   implemented    using    the
    +     ef_expand_file()  function.   See  the ef_expand_file(3) man
    +     page for more details.
    +
    +
    +

    RECALLING PREVIOUSLY TYPED LINES

    +     Every time that a new line is entered by  the  user,  it  is
    +     appended  to  a  list  of  historical input lines maintained
    +     within the GetLine resource object. You can traverse up  and
    +     down  this  list  using the up and down arrow keys. Alterna-
    +     tively, you can do the same with the ^P, and ^N keys, and in
    +     vi  command mode you can alternatively use the k and j char-
    +     acters. Thus pressing up-arrow once,  replaces  the  current
    +     input  line  with  the previously entered line. Pressing up-
    +     arrow again, replaces this with the line  that  was  entered
    +     before it, etc.. Having gone back one or more lines into the
    +     history list, one can return  to  newer  lines  by  pressing
    +     down-arrow  one  or  more  times.  If you do this sufficient
    +     times, you will return to the original line  that  you  were
    +     entering when you first hit up-arrow.
    +
    +     Note that in vi mode, all of the  history  recall  functions
    +     switch the library into command mode.
    +
    +     In emacs mode the M-p and M-n keys work just like the ^P and
    +     ^N  keys,  except  that  they  skip all but those historical
    +     lines which share the prefix that precedes the cursor. In vi
    +     command  mode  the upper case K and J characters do the same
    +     thing, except that the string that they search for  includes
    +     the character under the cursor as well as what precedes it.
    +
    +     Thus for example, suppose that you were in emacs  mode,  and
    +     you  had  just entered the following list of commands in the
    +     order shown:
    +
    +       ls ~/tecla/
    +       cd ~/tecla
    +       ls -l getline.c
    +       emacs ~/tecla/getline.c
    +
    +     If you next typed:
    +
    +       ls
    +
    +     and then hit M-p, then rather than returning the  previously
    +     typed   emacs   line,   which   doesn't   start  with  "ls",
    +     gl_get_line() would  recall  the  "ls  -l  getline.c"  line.
    +     Pressing M-p again would recall the "ls ~/tecla/" line.
    +
    +
    +

    HISTORY FILES

    +     To save the contents of the history buffer  before  quitting
    +     your  application,  and  subsequently  restore them when you
    +     next start the application, the following functions are pro-
    +     vided.
    +
    +
    +      int gl_save_history(GetLine *gl, const char *filename,
    +                          const char *comment, int max_lines);
    +      int gl_load_history(GetLine *gl, const char *filename,
    +                          const char *comment);
    +
    +
    +     The filename argument specifies the name to give the history
    +     file  when  saving, or the name of an existing history file,
    +     when loading. This may contain home-directory  and  environ-
    +     ment  variable  expressions,  such  as "~/.myapp_history" or
    +     "$HOME/.myapp_history".
    +     Along with each history line, extra  information  about  it,
    +     such  as when it was entered by the user, and what its nest-
    +     ing level is, is recorded as a comment preceding the line in
    +     the  history file. Writing this as a comment allows the his-
    +     tory file to double as a command file, just in case you wish
    +     to  replay  a whole session using it. Since comment prefixes
    +     differ in different languages, the comment argument is  pro-
    +     vided  for  specifying  the  comment prefix. For example, if
    +     your application were a  unix  shell,  such  as  the  bourne
    +     shell,  you  would specify "#" here. Whatever you choose for
    +     the comment character, you must specify the same  prefix  to
    +     gl_load_history()    that   you   used   when   you   called
    +     gl_save_history() to write the history file.
    +
    +     The max_lines must be either -1 to specify that all lines in
    +     the history list be saved, or a positive number specifying a
    +     ceiling on how many of  the  most  recent  lines  should  be
    +     saved.
    +
    +     Both fuctions return non-zero on  error,  after  writing  an
    +     error  message  to  stderr. Note that gl_load_history() does
    +     not consider the non-existence of a file to be an error.
    +
    +
    +

    MULTIPLE HISTORY LISTS

    +     If your application uses a single GetLine object for  enter-
    +     ing  many  different  types  of  input  lines,  you may wish
    +     gl_get_line() to distinguish the different types of lines in
    +     the  history  list,  and  only  recall  lines that match the
    +     current  type  of  line.  To   support   this   requirement,
    +     gl_get_line() marks lines being recorded in the history list
    +     with an integer identifier chosen by the application.   Ini-
    +     tially  this identifier is set to 0 by new_GetLine(), but it
    +     can be changed subsequently by calling gl_group_history().
    +
    +
    +       int gl_group_history(GetLine *gl, unsigned id);
    +
    +
    +     The integer identifier id can be any number  chosen  by  the
    +     application,    but    note   that   gl_save_history()   and
    +     gl_load_history() preserve the association between  identif-
    +     iers and historical input lines between program invokations,
    +     so you should choose fixed  identifiers  for  the  different
    +     types of input line used by your application.
    +
    +     Whenever gl_get_line() appends a new input line to the  his-
    +     tory  list,  the current history identifier is recorded with
    +     it, and when it is asked to recall a historical input  line,
    +     it only recalls lines that are marked with the current iden-
    +     tifier.
    +
    +

    DISPLAYING HISTORY

    +     The   history   list   can   be   displayed    by    calling
    +     gl_show_history().
    +
    +
    +       int gl_show_history(GetLine *gl, FILE *fp,
    +                           const char *fmt,
    +                           int all_groups,
    +                           int max_lines);
    +
    +
    +     This displays the current contents of the  history  list  to
    +     the  stdio  output  stream  fp. If the max_lines argument is
    +     greater than or equal to zero, then no more than this number
    +     of   the  most  recent  lines  will  be  displayed.  If  the
    +     all_groups argument is  non-zero,  lines  from  all  history
    +     groups  are displayed. Otherwise just those of the currently
    +     selected history group  are  displayed.  The  format  string
    +     argument,  fmt,  determines  how the line is displayed. This
    +     can contain arbitrary characters which are written verbatim,
    +     interleaved with any of the following format directives:
    +
    +       %D  -  The date on which the line was originally
    +              entered, formatted like 2001-11-20.
    +       %T  -  The time of day when the line was entered,
    +              formatted like 23:59:59.
    +       %N  -  The sequential entry number of the line in
    +              the history buffer.
    +       %G  -  The number of the history group which the
    +              line belongs to.
    +       %%  -  A literal % character.
    +       %H  -  The history line itself.
    +
    +     Thus a format string like "%D %T  %H0 would output something
    +     like:
    +
    +       2001-11-20 10:23:34  Hello world
    +
    +     Note the inclusion of an explicit newline character  in  the
    +     format string.
    +
    +
    +

    LOOKING UP HISTORY

    +     The gl_lookup_history() function allows the calling applica-
    +     tion to look up lines in the history list.
    +
    +
    +       typedef struct {
    +         const char *line;    /* The requested historical */
    +                              /*  line. */
    +         unsigned group;      /* The history group to which */
    +                              /*  the line belongs. */
    +         time_t timestamp;    /* The date and time at which */
    +                              /*  the line was originally */
    +                              /*  entered. */
    +       } GlHistoryLine;
    +
    +       int gl_lookup_history(GetLine *gl, unsigned long id,
    +                             GlHistoryLine *hline);
    +
    +
    +     The id argument indicates which line to look up,  where  the
    +     first  line  that  was  entered  in  the  history list after
    +     new_GetLine() was called, is denoted by 0, and  subsequently
    +     entered  lines are denoted with successively higher numbers.
    +     Note that the range of lines currently preserved in the his-
    +     tory    list    can    be    queried    by    calling    the
    +     gl_range_of_history()  function,  described  later.  If  the
    +     requested  line  is  in the history list, the details of the
    +     line are recorded in the variable pointed to  by  the  hline
    +     argument,  and  1  is returned. Otherwise 0 is returned, and
    +     the variable pointed to by hline is left unchanged.
    +
    +     Beware that the string returned in hline->line  is  part  of
    +     the  history  buffer,  so  it  must  not  be modified by the
    +     caller, and will be recycled on the next call to  any  func-
    +     tion  that  takes  gl  as its argument. Therefore you should
    +     make a private copy of this string if you need  to  keep  it
    +     around.
    +
    +
    +

    MISCELLANEOUS HISTORY CONFIGURATION

    +     If you wish to change the size of the  history  buffer  that
    +     was  originally  specified in the call to new_GetLine(), you
    +     can do so with the gl_resize_history() function.
    +
    +
    +       int gl_resize_history(GetLine *gl, size_t histlen);
    +
    +
    +     The histlen argument specifies the new size in bytes, and if
    +     you specify this as 0, the buffer will be deleted.
    +
    +     As mentioned in the discussion of new_GetLine(), the  number
    +     of  lines  that can be stored in the history buffer, depends
    +     on the lengths of the individual lines. For example, a  1000
    +     byte  buffer  could equally store 10 lines of average length
    +     100 bytes, or 2 lines of average length 50  bytes.  Although
    +     the  buffer  is  never  expanded when new lines are added, a
    +     list of pointers into the  buffer  does  get  expanded  when
    +     needed to accomodate the number of lines currently stored in
    +     the buffer. To place an upper limit on the number  of  lines
    +     in  the  buffer,  and thus a ceiling on the amount of memory
    +     used in this  list,  you  can  call  the  gl_limit_history()
    +     function.
    +
    +
    +       void gl_limit_history(GetLine *gl, int max_lines);
    +
    +
    +     The max_lines should either  be  a  positive  number  >=  0,
    +     specifying  an  upper  limit  on  the number of lines in the
    +     buffer, or be -1 to cancel any previously  specified  limit.
    +     When  a limit is in effect, only the max_lines most recently
    +     appended lines are kept in the buffer. Older lines are  dis-
    +     carded.
    +
    +     To  discard  lines  from  the  history   buffer,   use   the
    +     gl_clear_history() function.
    +
    +       void gl_clear_history(GetLine *gl, int all_groups);
    +
    +     The all_groups argument tells the function whether to delete
    +     just  the  lines  associated  with the current history group
    +     (see gl_group_history()), or all  historical  lines  in  the
    +     buffer.
    +
    +     The gl_toggle_history() function allows you to  toggle  his-
    +     tory  on  and off without losing the current contents of the
    +     history list.
    +
    +
    +       void gl_toggle_history(GetLine *gl, int enable);
    +
    +
    +     Setting the enable argument  to  0  turns  off  the  history
    +     mechanism,  and  setting it to 1 turns it back on. When his-
    +     tory is turned off, no new lines will be added to  the  his-
    +     tory  list,  and  history  lookup  key-bindings  will act as
    +     though there is nothing in the history buffer.
    +
    +
    +

    QUERYING HISTORY INFORMATION

    +     The configured state of the history list can be queried with
    +     the gl_history_state() function.
    +
    +
    +       typedef struct {
    +         int enabled;     /* True if history is enabled */
    +         unsigned group;  /* The current history group */
    +         int max_lines;   /* The current upper limit on the */
    +                          /*  number of lines in the history */
    +                          /*  list, or -1 if unlimited. */
    +       } GlHistoryState;
    +
    +       void gl_state_of_history(GetLine *gl,
    +                                GlHistoryState *state);
    +
    +     On return, the status information is recorded in  the  vari-
    +     able pointed to by the state argument.
    +
    +     The gl_range_of_history() function returns  the  number  and
    +     range of lines in the history list.
    +
    +
    +     typedef struct {
    +       unsigned long oldest;  /* The sequential entry number */
    +                              /*  of the oldest line in the */
    +                              /*  history list. */
    +       unsigned long newest;  /* The sequential entry number */
    +                              /*  of the newest line in the */
    +                              /*  history list. */
    +       int nlines;            /* The number of lines in the */
    +                              /*  history list. */
    +     } GlHistoryRange;
    +
    +     void gl_range_of_history(GetLine *gl, GlHistoryRange *range);
    +
    +     The return values are recorded in the variable pointed to by
    +     the  range  argument. If the nlines member of this structure
    +     is greater than zero, then the  oldest  and  newest  members
    +     report    the    range   of   lines   in   the   list,   and
    +     newest=oldest+nlines-1.  Otherwise they are both zero.
    +
    +     The gl_size_of_history() function returns the total size  of
    +     the  history  buffer  and  the  amount of the buffer that is
    +     currently occupied.
    +
    +       typedef struct {
    +         size_t size;      /* The size of the history buffer */
    +                           /*  (bytes). */
    +         size_t used;      /* The number of bytes of the */
    +                           /*  history buffer that are */
    +                           /*  currently occupied. */
    +       } GlHistorySize;
    +
    +       void gl_size_of_history(GetLine *gl, GlHistorySize *size);
    +
    +     On return, the size information is recorded in the  variable
    +     pointed to by the size argument.
    +
    +
    +

    CHANGING TERMINALS

    +     The new_GetLine() constructor function assumes that input is
    +     to  be  read  from  stdin, and output written to stdout. The
    +     following function allows you to switch to  different  input
    +     and output streams.
    +
    +       int gl_change_terminal(GetLine *gl, FILE *input_fp,
    +                              FILE *output_fp, const char *term);
    +
    +     The  gl  argument  is  the  object  that  was  returned   by
    +     new_GetLine().   The  input_fp argument specifies the stream
    +     to read from, and output_fp specifies the stream to be writ-
    +     ten  to.  Only  if  both  of these refer to a terminal, will
    +     interactive   terminal   input   be   enabled.     Otherwise
    +     gl_get_line()  will  simply  call  fgets()  to  read command
    +     input. If both streams refer to a terminal, then  they  must
    +     refer  to  the  same terminal, and the type of this terminal
    +     must be specified via the term argument. The  value  of  the
    +     term argument is looked up in the terminal information data-
    +     base (terminfo or termcap), in order to determine which spe-
    +     cial control sequences are needed to control various aspects
    +     of the  terminal.  new_GetLine()  for  example,  passes  the
    +     return  value  of getenv("TERM") in this argument. Note that
    +     if one or both of input_fp and output_fp don't  refer  to  a
    +     terminal,  then it is legal to pass NULL instead of a termi-
    +     nal type.
    +
    +     Note  that  if  you  want  to  pass  file   descriptors   to
    +     gl_change_terminal(),  you  can  do  this  by creating stdio
    +     stream wrappers using the POSIX fdopen() function.
    +
    +
    +

    EXTERNAL EVENT HANDLING

    +     While gl_get_line() is waiting for keyboard input  from  the
    +     user, you can ask it to also watch for activity on arbitrary
    +     file descriptors, such as network sockets,  pipes  etc,  and
    +     have  it  call  functions  of your choosing when activity is
    +     seen. This works on any system that has the select()  system
    +     call, which is most, if not all flavors of unix. Registering
    +     a file descriptor to be watched  by  gl_get_line()  involves
    +     calling the gl_watch_fd() function.
    +
    +
    +       int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
    +                       GlFdEventFn *callback, void *data);
    +
    +
    +     If this returns non-zero, then it  means  that  either  your
    +     arguments are invalid, or that this facility isn't supported
    +     on the host system.
    +
    +     The fd argument is the file descriptor to  be  watched.  The
    +     event  argument  specifies  what  type  of  activity  is  of
    +     interest, chosen from the following enumerated values:
    +
    +
    +       GLFD_READ   -  Watch for the arrival of data to be read.
    +       GLFD_WRITE  -  Watch for the ability to write to the file
    +                      descriptor without blocking.
    +       GLFD_URGENT -  Watch for the arrival of urgent
    +                      out-of-band data on the file descriptor.
    +
    +
    +     The callback argument is  the  function  to  call  when  the
    +     selected  activity  is  seen.  It should be defined with the
    +     following macro, which is defined in libtecla.h.
    +
    +
    +       #define GL_FD_EVENT_FN(fn) GlFdStatus (fn)(GetLine *gl, \
    +                                           void *data, int fd, \
    +                                           GlFdEvent event)
    +
    +     The data argument of the gl_watch_fd() function is passed to
    +     the callback function for its own use, and can point to any-
    +     thing you like, including NULL. The file descriptor and  the
    +     event argument are also passed to the callback function, and
    +     this potentially allows the same  callback  function  to  be
    +     registered  to  more than one type of event and/or more than
    +     one file descriptor. The return value of the callback  func-
    +     tion should be one of the following values.
    +
    +
    +       GLFD_ABORT    -  Tell gl_get_line() to abort with an
    +                        error (errno won't be set, so set it
    +                        appropriately yourself if you need it).
    +       GLFD_REFRESH  -  Redraw the input line then continue
    +                        waiting for input. Return this if
    +                        your callback wrote to the terminal.
    +       GLFD_CONTINUE -  Continue to wait for input, without
    +                        redrawing the line.
    +
    +     Note that before calling the callback, gl_get_line()  blocks
    +     most  signals, and leaves its own signal handlers installed,
    +     so if you need to catch a particular signal you will need to
    +     both  temporarily  install  your  own  signal  handler,  and
    +     unblock the signal. Be sure to re-block the  signal  (if  it
    +     was  originally  blocked)  and reinstate the original signal
    +     handler, if any, before returning.
    +
    +     Your callback shouldn't try to read from the terminal, which
    +     is  left  in  raw mode as far as input is concerned. You can
    +     however write to the terminal as usual, since features  like
    +     conversion  of  newline  to carriage-return/linefeed are re-
    +     enabled while the callback  is  running.  If  your  callback
    +     function  does  write  to  the terminal, be sure to output a
    +     newline  first,  and  when  your  callback   returns,   tell
    +     gl_get_line()  that  the  input line needs to be redrawn, by
    +     returning the GLFD_REFRESH status code.
    +
    +     To remove a callback function that you previously registered
    +     for   a   given  file  descriptor  and  event,  simply  call
    +     gl_watch_fd() with the same file descriptor and event  argu-
    +     ments,  but with a callback argument of 0. The data argument
    +     is ignored in this case.
    +
    +
    +

    SIGNAL HANDLING DEFAULTS

    +     By default, the gl_get_line() function intercepts  a  number
    +     of signals. This is particularly important for signals which
    +     would by default terminate the process, since  the  terminal
    +     needs  to be restored to a usable state before this happens.
    +     In this section, the signals that are  trapped  by  default,
    +     and how gl_get_line() responds to them, is described. Chang-
    +     ing these defaults is the topic of the following section.
    +
    +     When  the  following   subset   of   signals   are   caught,
    +     gl_get_line()  first restores the terminal settings and sig-
    +     nal handling to  how  they  were  before  gl_get_line()  was
    +     called,   resends   the   signal,   to   allow  the  calling
    +     application's signal handlers to handle it, then if the pro-
    +     cess still exists, gl_get_line() returns NULL and sets errno
    +     as specified below.
    +
    +
    +      SIGINT  -  This signal is generated both by the keyboard
    +                 interrupt key (usually ^C), and the keyboard
    +                 break key.
    +
    +                 errno=EINTR
    +
    +      SIGHUP  -  This signal is generated when the controlling
    +                 terminal exits.
    +
    +                 errno=ENOTTY
    +
    +      SIGPIPE -  This signal is generated when a program attempts
    +                 to write to a pipe who's remote end isn't being
    +                 read by any process. This can happen for example
    +                 if you have called gl_change_terminal() to
    +                 redirect output to a pipe hidden under a pseudo
    +                 terminal.
    +
    +                 errno=EPIPE
    +
    +      SIGQUIT -  This signal is generated by the keyboard quit
    +                 key (usually ^\).
    +
    +                 errno=EINTR
    +
    +      SIGABRT -  This signal is generated by the standard C,
    +                 abort() function. By default it both
    +                 terminates the process and generates a core
    +                 dump.
    +
    +                 errno=EINTR
    +
    +      SIGTERM -  This is the default signal that the UN*X
    +                 kill command sends to processes.
    +
    +                 errno=EINTR
    +
    +     Note that in the case of all of  the  above  signals,  POSIX
    +     mandates that by default the process is terminated, with the
    +     addition of a core dump in the case of the  SIGQUIT  signal.
    +     In  other words, if the calling application doesn't override
    +     the default handler by supplying  its  own  signal  handler,
    +     receipt  of  the  corresponding  signal  will  terminate the
    +     application before gl_get_line() returns.
    +
    +     If gl_get_line() aborts with errno set  to  EINTR,  you  can
    +     find out what signal caused it to abort, by calling the fol-
    +     lowing function.
    +
    +       int gl_last_signal(const GetLine *gl);
    +
    +     This returns the numeric code (eg. SIGINT) of the last  sig-
    +     nal  that  was  received  during  the  most  recent  call to
    +     gl_get_line(), or -1 if no signals were received.
    +
    +     On systems that support it, when a SIGWINCH (window  change)
    +     signal  is  received,  gl_get_line() queries the terminal to
    +     find out its new size, redraws the  current  input  line  to
    +     accomodate  the  new  size, then returns to waiting for key-
    +     board input from the user. Unlike other signals, this signal
    +     isn't resent to the application.
    +
    +     Finally, the following signals cause gl_get_line() to  first
    +     restore  the  terminal  and signal environment to that which
    +     prevailed before gl_get_line() was called, then  resend  the
    +     signal to the application. If the process still exists after
    +     the signal has been delivered, then gl_get_line()  then  re-
    +     establishes  its  own signal handlers, switches the terminal
    +     back to raw mode, redisplays the input line, and  goes  back
    +     to awaiting terminal input from the user.
    +
    +      SIGCONT    -  This signal is generated when a suspended
    +                    process is resumed.
    +
    +      SIGPWR     -  This signal is generated when a power failure
    +                    occurs (presumably when the system is on a
    +                    UPS).
    +
    +      SIGALRM    -  This signal is generated when a timer
    +                    expires.
    +      SIGUSR1    -  An application specific signal.
    +
    +      SIGUSR2    -  Another application specific signal.
    +
    +      SIGVTALRM  -  This signal is generated when a virtual
    +                    timer expires (see man setitimer(2)).
    +
    +      SIGXCPU    -  This signal is generated when a process
    +                    exceeds its soft CPU time limit.
    +
    +      SIGTSTP    -  This signal is generated by the terminal
    +                    suspend key, which is usually ^Z, or the
    +                    delayed terminal suspend key, which is
    +                    usually ^Y.
    +
    +      SIGTTIN    -  This signal is generated if the program
    +                    attempts to read from the terminal while the
    +                    program is running in the background.
    +
    +      SIGTTOU    -  This signal is generated if the program
    +                    attempts to write to the terminal while the
    +                    program is running in the background.
    +
    +
    +     Obviously not all of the above signals are supported on  all
    +     systems,  so  code to support them is conditionally compiled
    +     into the tecla library.
    +
    +     Note that if SIGKILL, which by definition can't  be  caught,
    +     or  any of the hardware generated exception signals, such as
    +     SIGSEGV, SIGBUS and SIGFPE, are received and unhandled while
    +     gl_get_line() has the terminal in raw mode, the program will
    +     be terminated without the terminal having been restored to a
    +     usable  state. In practice, job-control shells usually reset
    +     the terminal settings when a process relinquishes  the  con-
    +     trolling  terminal,  so  this  is  only a problem with older
    +     shells.
    +
    +
    +

    CUSTOMIZED SIGNAL HANDLING

    +     The previous section listed the signals  that  gl_get_line()
    +     traps  by  default,  and  described how it responds to them.
    +     This section describes how to both add  and  remove  signals
    +     from  the  list  of  trapped signals, and how to specify how
    +     gl_get_line() should respond to a given signal.
    +
    +     If you don't need gl_get_line() to do anything  in  response
    +     to  a  signal  that  it  normally  traps,  you  can  tell to
    +     gl_get_line()   to   ignore   that   signal    by    calling
    +     gl_ignore_signal().
    +
    +       int gl_ignore_signal(GetLine *gl, int signo);
    +     The signo argument is the number of the signal (eg.  SIGINT)
    +     that you want to have ignored. If the specified signal isn't
    +     currently one of those being  trapped,  this  function  does
    +     nothing.
    +
    +     The gl_trap_signal() function allows you to either add a new
    +     signal  to  the list that gl_get_line() traps, or modify how
    +     it responds to a signal that it already traps.
    +
    +       int gl_trap_signal(GetLine *gl, int signo, unsigned flags,
    +                          GlAfterSignal after, int errno_value);
    +
    +     The signo argument is the number of the signal that you wish
    +     to  have trapped. The flags argument is a set of flags which
    +     determine the environment in which the application's  signal
    +     handler  is  invoked, the after argument tells gl_get_line()
    +     what to do after the application's signal  handler  returns,
    +     and  errno_value tells gl_get_line() what to set errno to if
    +     told to abort.
    +
    +     The flags argument is a bitwise OR of zero or  more  of  the
    +     following enumerators:
    +
    +       GLS_RESTORE_SIG  -  Restore the caller's signal
    +                           environment while handling the
    +                           signal.
    +
    +       GLS_RESTORE_TTY  -  Restore the caller's terminal settings
    +                           while handling the signal.
    +
    +       GLS_RESTORE_LINE -  Move the cursor to the start of the
    +                           line following the input line before
    +                           invoking the application's signal
    +                           handler.
    +
    +       GLS_REDRAW_LINE  -  Redraw the input line when the
    +                           application's signal handler returns.
    +
    +       GLS_UNBLOCK_SIG  -  Normally, if the calling program has
    +                           a signal blocked (man sigprocmask),
    +                           gl_get_line() does not trap that
    +                           signal. This flag tells gl_get_line()
    +                           to trap the signal and unblock it for
    +                           the duration of the call to
    +                           gl_get_line().
    +
    +       GLS_DONT_FORWARD -  If this flag is included, the signal
    +                           will not be forwarded to the signal
    +                           handler of the calling program.
    +
    +     Two commonly useful flag combinations are also enumerated as
    +     follows:
    +       GLS_RESTORE_ENV   = GLS_RESTORE_SIG | GLS_RESTORE_TTY |
    +                           GLS_REDRAW_LINE
    +
    +       GLS_SUSPEND_INPUT = GLS_RESTORE_ENV | GLS_RESTORE_LINE
    +
    +
    +     If your signal handler, or the default system signal handler
    +     for  this  signal, if you haven't overriden it, never either
    +     writes to the terminal, nor suspends or terminates the  cal-
    +     ling  program, then you can safely set the flags argument to
    +     0.
    +
    +     If your signal handler always writes to the terminal,  reads
    +     from  it,  or suspends or terminates the program, you should
    +     specify the flags argument as GL_SUSPEND_INPUT, so that:
    +
    +     1. The cursor doesn't get left in the middle of the input
    +        line.
    +     2. So that the user can type in input and have it echoed.
    +     3. So that you don't need to end each output line with
    +        \r\n, instead of just \n.
    +
    +     The   GL_RESTORE_ENV   combination   is    the    same    as
    +     GL_SUSPEND_INPUT,  except  that  it doesn't move the cursor,
    +     and if your signal handler doesn't read or write anything to
    +     the terminal, the user won't see any visible indication that
    +     a signal was caught. This can be useful if you have a signal
    +     handler that only occasionally writes to the terminal, where
    +     using GL_SUSPEND_LINE would  cause  the  input  line  to  be
    +     unnecessarily  duplicated  when  nothing had been written to
    +     the terminal.  Such a signal handler, when it does write  to
    +     the  terminal,  should  be  sure  to start a new line at the
    +     start of its first write,  by  writing  a  new  line  before
    +     returning.  If the signal arrives while the user is entering
    +     a line that only occupies a signal terminal line, or if  the
    +     cursor  is on the last terminal line of a longer input line,
    +     this will have the same effect as  GL_SUSPEND_INPUT.  Other-
    +     wise  it  will start writing on a line that already contains
    +     part of the displayed input line.  This doesn't do any harm,
    +     but  it  looks a bit ugly, which is why the GL_SUSPEND_INPUT
    +     combination is better if you know that you are always  going
    +     to be writting to the terminal.
    +
    +     The after argument, which determines what gl_get_line() does
    +     after  the  application's  signal  handler  returns  (if  it
    +     returns), can take any one of the following values:
    +
    +       GLS_RETURN   - Return the completed input line, just as
    +                      though the user had pressed the return
    +                      key.
    +
    +       GLS_ABORT    - Cause gl_get_line() to return NULL.
    +       GLS_CONTINUE - Resume command line editing.
    +
    +     The errno_value argument is intended to be combined with the
    +     GLS_ABORT  option,  telling  gl_get_line()  what  to set the
    +     standard errno variable to before returning NULL to the cal-
    +     ling  program.  It  can  also,  however,  be  used  with the
    +     GL_RETURN option, in case you wish to have a way to  distin-
    +     guish  between  an  input  line  that  was entered using the
    +     return key, and one that was entered by  the  receipt  of  a
    +     signal.
    +
    +
    +

    THE TERMINAL SIZE

    +     On most systems the combination of the TIOCGWINSZ ioctl  and
    +     the  SIGWINCH signal is used to maintain an accurate idea of
    +     the terminal size. The terminal size is newly queried  every
    +     time  that  gl_get_line()  is called and whenever a SIGWINCH
    +     signal is received.
    +
    +     On the few systems where this mechanism isn't available,  at
    +     startup  new_GetLine() first looks for the LINES and COLUMNS
    +     environment variables.  If these aren't found, or they  con-
    +     tain  unusable  values, then if a terminal information data-
    +     base like terminfo or termcap is available, the default size
    +     of  the  terminal is looked up in this database. If this too
    +     fails to provide the terminal size, a  default  size  of  80
    +     columns by 24 lines is used. If this default isn't appropri-
    +     ate for your system, gl_terminal_size() can be used to  sup-
    +     ply a different fallback.
    +
    +     The gl_terminal_size() function  allows  you  to  query  the
    +     current size of the terminal, and install an alternate fall-
    +     back size for cases where the size isn't available.   Beware
    +     that  the terminal size won't be available if reading from a
    +     pipe or a file, so the default values can be important  even
    +     on  systems that do support ways of finding out the terminal
    +     size.
    +
    +       typedef struct {
    +         int nline;        /* The terminal has nline lines */
    +         int ncolumn;      /* The terminal has ncolumn columns */
    +       } GlTerminalSize;
    +
    +       GlTerminalSize gl_terminal_size(GetLine *gl,
    +                                       int def_ncolumn,
    +                                       int def_nline);
    +
    +     This function first updates gl_get_line()'s idea of the ter-
    +     minal size, then records its findings in the return value.
    +
    +     The def_ncolumn and def_nline specify the default number  of
    +     terminal columns and lines to use if the terminal size can't
    +     be determined.
    +
    +
    +

    HIDING WHAT YOU TYPE

    +     When entering sensitive information, such as  passwords,  it
    +     is best not to have the text that you are entering echoed on
    +     the terminal.  Furthermore, such text should not be recorded
    +     in  the  history  list, since somebody finding your terminal
    +     unattended  could  then  recall  it,  or  somebody  snooping
    +     through  your directories could see it in your history file.
    +     With this in mind, the gl_echo_mode() function allows you to
    +     toggle  on and off the display and archival of any text that
    +     is subsequently entered in calls to gl_get_line().
    +
    +
    +       int gl_echo_mode(GetLine *gl, int enable);
    +
    +
    +     The enable argument specifies whether entered text should be
    +     visible  or not. If it is 0, then subsequently entered lines
    +     will not be  visible  on  the  terminal,  and  will  not  be
    +     recorded  in  the  history list. If it is 1, then subsequent
    +     input lines will be displayed as they are entered, and  pro-
    +     vided  that  history  hasn't  been  turned off via a call to
    +     gl_toggle_history(), then they will also be archived in  the
    +     history  list.  Finally,  if the enable argument is -1, then
    +     the echoing mode is left  unchanged,  which  allows  you  to
    +     non-destructively  query  the current setting via the return
    +     value. In all cases, the return value of the function  is  0
    +     if  echoing was disabled before the function was called, and
    +     1 if it was enabled.
    +
    +     When echoing is turned off, note that although  tab  comple-
    +     tion will invisibly complete your prefix as far as possible,
    +     ambiguous completions will not be displayed.
    +
    +
    +

    CALLBACK FUNCTION FACILITIES

    +     Unless otherwise stated, callback  functions,  such  as  tab
    +     completion callbacks and event callbacks should not call any
    +     functions in this module. The following functions,  however,
    +     are designed specifically to be used by callback functions.
    +
    +     Calling the gl_replace_prompt()  function  from  a  callback
    +     tells  gl_get_line()  to display a different prompt when the
    +     callback  returns.  It  has  no  effect   if   called   when
    +     gl_get_line() is not being called.
    +
    +       void gl_replace_prompt(GetLine *gl, const char *prompt);
    +
    +
    +
    +

    INTERNATIONAL CHARACTER SETS

    +     Since libtecla version 1.4.0, gl_get_line() has  been  8-bit
    +     clean.  This means that all 8-bit characters that are print-
    +     able in the user's current locale are now displayed verbatim
    +     and  included in the returned input line.  Assuming that the
    +     calling program correctly contains a call like  the  follow-
    +     ing,
    +
    +       setlocale(LC_CTYPE, "");
    +
    +     then the current locale is determined by the  first  of  the
    +     environment  variables  LC_CTYPE,  LC_ALL, and LANG, that is
    +     found to contain a valid locale name. If none of these vari-
    +     ables  are  defined,  or the program neglects to call setlo-
    +     cale, then the default C locale is used, which is  US  7-bit
    +     ASCII.  On  most  unix-like platforms, you can get a list of
    +     valid locales by typing the command:
    +
    +       locale -a
    +
    +     at the shell prompt.
    +
    +
    +

    Meta keys and locales

    +     Beware that in most locales other than the default C locale,
    +     meta  characters  become  printable,  and  they  are then no
    +     longer considered to match  M-c  style  key  bindings.  This
    +     allows  international characters to be entered with the com-
    +     pose key without unexpectedly triggering meta key  bindings.
    +     You can still invoke meta bindings, since there are actually
    +     two ways to do this. For example the binding M-c can also be
    +     invoked  by pressing the escape key momentarily, then press-
    +     ing the c key, and this  will  work  regardless  of  locale.
    +     Moreover,  many  modern  terminal emulators, such as gnome's
    +     gnome-terminal's and KDE's konsole terminals,  already  gen-
    +     erate  escape  pairs  like  this  when you use the meta key,
    +     rather than a real meta character, and other emulators  usu-
    +     ally  have  a  way to request this behavior, so you can con-
    +     tinue to use the meta key on most systems.
    +
    +     For example, although xterm terminal emulators generate real
    +     8-bit  meta characters by default when you use the meta key,
    +     they can be configured to output the equivalent escape  pair
    +     by  setting their EightBitInput X resource to False. You can
    +     either do this by placing a line like the following in  your
    +     ~/.Xdefaults file,
    +
    +       XTerm*EightBitInput: False
    +
    +     or by starting an xterm with an -xrm '*EightBitInput: False'
    +     command-line  argument.  In recent versions of xterm you can
    +     toggle this feature on and off with the "Meta Sends  Escape"
    +     option in the menu that is displayed when you press the left
    +     mouse button and the control key within an xterm window.  In
    +     CDE,  dtterms  can  be  similarly coerced to generate escape
    +     pairs  in  place  of  meta  characters,   by   setting   the
    +     Dtterm*KshMode resource to True.
    +
    +
    +

    Entering international characters

    +     If you don't have a  keyboard  that  generates  all  of  the
    +     international  characters  that you need, there is usually a
    +     compose key that will allow you to enter special characters,
    +     or  a  way  to  create  one. For example, under X windows on
    +     unix-like systems, if your keyboard doesn't have  a  compose
    +     key, you can designate a redundant key to serve this purpose
    +     with the xmodmap command. For example, on many PC  keyboards
    +     there is a microsoft-windows key, which is otherwise useless
    +     under Linux. On my PC the xev program reports that  pressing
    +     this  key  generates keycode 115, so to turn this key into a
    +     compose key, I do the following:
    +
    +       xmodmap -e 'keycode 115 = Multi_key'
    +
    +     I can then enter an i with a umlaut over it by  typing  this
    +     key, followed by ", followed by i.
    +
    +
    +

    THREAD SAFETY

    +     In a multi-threaded program, you should use the libtecla_r.a
    +     version of the library. This uses reentrant versions of sys-
    +     tem functions, where available. Unfortunately  neither  ter-
    +     minfo  nor  termcap  were  designed  to be reentrant, so you
    +     can't safely use the functions of the getline module in mul-
    +     tiple  threads  (you can use the separate file-expansion and
    +     word-completion  modules  in  multiple  threads,   see   the
    +     corresponding man pages for details). However due to the use
    +     of POSIX reentrant functions for looking up home directories
    +     etc, it is safe to use this module from a single thread of a
    +     multi-threaded program, provided  that  your  other  threads
    +     don't use any termcap or terminfo functions.
    +
    +
    +

    FILES

    +     libtecla.a      -    The tecla library
    +     libtecla.h      -    The tecla header file.
    +     ~/.teclarc      -    The personal tecla customization file.
    +
    +
    +

    SEE ALSO

    +     libtecla(3),    ef_expand_file(3),     cpl_complete_word(3),
    +     pca_lookup_file(3)
    +
    +
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/index.html b/libtecla-1.4.1/html/index.html new file mode 100644 index 0000000..f75a90f --- /dev/null +++ b/libtecla-1.4.1/html/index.html @@ -0,0 +1,116 @@ +The tecla command-line editing library. + +

    The Tecla command-line editing library.

    + +The tecla library provides UNIX and LINUX programs with interactive +command line editing facilities, similar to those of the UNIX tcsh +shell. In addition to simple command-line editing, it supports recall +of previously entered command lines, TAB completion of file names or +other tokens, and in-line wild-card expansion of filenames. The +internal functions which perform file-name completion and wild-card +expansion are also available externally for optional use by programs. +

    +In addition, the library includes a path-searching module. This +allows an application to provide completion and lookup of files +located in UNIX style paths. Although not built into the line editor +by default, it can easily be called from custom tab-completion +callback functions. This was originally conceived for completing the +names of executables and providing a way to look up their locations in +the user's PATH environment variable, but it can easily be asked to +look up and complete other types of files in any list of directories. + +

    +Note that special care has been taken to allow the use of this library +in threaded programs. The option to enable this is discussed in the +Makefile, and specific discussions of thread safety are presented in +the included man pages. +

    +The current version is version 1.4.1. This may be obtained from: +

    + http://www.astro.caltech.edu/~mcs/tecla/libtecla-1.4.1.tar.gz +

    + +For the sake of automated scripts, the following URL always points to +the latest version. Note that the version number can be found in the +README file. + +

    + http://www.astro.caltech.edu/~mcs/tecla/libtecla.tar.gz +

    + +The library is distributed under a permissive non-copyleft +free software license (the X11 license with +the name of the copyright holder changed). This is compatible with, +but not as restrictive as the GNU GPL. + +

    Release notes

    + +The list of major changes that accompany each new release can be found +here. + +

    Modifications

    + +The gory details of changes in the latest and previous versions of the +library can be found here. + +

    Library documentation

    + +The following are html versions of the libtecla man pages: + + + +

    Portability

    + +In principle, the standard version of the library should compile +without any problems on any UNIX or UNIX like system. So far it has +been reported to work on the following systems: + +
    +  Sun Solaris 2.5,2.6,7,8, with any of gcc, Sun C, or g++.
    +  Mandrake Linux 7.1 etc.., gcc
    +  Red Hat Linux 7 etc.., gcc
    +  Suse Linux 6.4, gcc
    +  IBM AIX 4.3.3, gcc
    +  HP-UX 10.20, HP-UX 11, gcc, c89
    +  SCO UnixWare 7.1.1
    +  FreeBSD, gcc
    +  Alpha OSF1, cc, gcc
    +  Mac OS X
    +  Cygwin (running under Windows)
    +  QNX
    +
    + +There haven't been many reports concerning the POSIX reentrant +version, so the absence of any of the above from the following list of +systems on which the reentrant version is known to work, shouldn't be +taken as an indication that the reentrant version doesn't work. + +
    +  Sun Solaris 2.5,2.6,7,8, with any of gcc, Sun C, or g++.
    +  Mandrake Linux 7.1, gcc
    +  RedHat Linux 7.0,7.1, gcc
    +  SuSe Linux 6.4, gcc
    +  HP-UX 11, gcc
    +  IBM AIX 4.3.3, gcc
    +  Alpha OSF1, cc
    +
    + +The only system that is known to have issues with the reentrant +version of the library is SCO UnixWare 7.1.1. The problem is in the +system provided signal.h, which breaks when POSIX_C_SOURCE is +defined. It has been reported that this can be fixed by editing +signal.h. + +

    +If you compile the library on a system that isn't mentioned above, +please send E-mail to mcs@astro.caltech.edu. +


    +Martin Shepherd (25-May-2002) + diff --git a/libtecla-1.4.1/html/libtecla.html b/libtecla-1.4.1/html/libtecla.html new file mode 100644 index 0000000..914c1e9 --- /dev/null +++ b/libtecla-1.4.1/html/libtecla.html @@ -0,0 +1,163 @@ + +Manual Page + + +
    +

    NAME

    +     libtecla - An interactive command-line input library.
    +
    +

    SYNOPSIS

    +     gcc ... -ltecla -lcurses
    +
    +
    +

    DESCRIPTION

    +     The tecla library provides programs with interactive command
    +     line  editing  facilities, similar to those of the unix tcsh
    +     shell. In addition to simple command-line editing,  it  sup-
    +     ports  recall  of previously entered command lines, TAB com-
    +     pletion of file names or other tokens, and in-line wild-card
    +     expansion of filenames. The internal functions which perform
    +     file-name completion and wild-card expansion are also avail-
    +     able externally for optional use by the calling program.
    +
    +     The various parts of the library are documented in the  fol-
    +     lowing man pages:
    +
    +       gl_get_line(3)        -  The interactive line-input module.
    +       cpl_complete_word(3)  -  The word completion module.
    +       ef_expand_file(3)     -  The filename expansion module.
    +       pca_lookup_file(3)    -  A directory-list based filename
    +                                lookup and completion module.
    +
    +     In addition there is one  optional  application  distributed
    +     with the library:
    +
    +       enhance(3)            -  Add command-line editing to third
    +                                party applications.
    +
    +
    +

    THREAD SAFETY

    +     If the library is compiled  with  -D_POSIX_C_SOURCE=199506L,
    +     reentrant  versions  of  as  many  functions as possible are
    +     used. This  includes  using  getpwuid_r()  and  getpwnam_r()
    +     instead  of  getpwuid()  and  getpwnam() when looking up the
    +     home directories of specific users in the password file (for
    +     ~user/  expansion), and readdir_r() instead of readdir() for
    +     reading directory entries when  doing  filename  completion.
    +     The  reentrant  version  of  the  library  is usually called
    +     libtecla_r.a instead of libtecla.a, so if only the latter is
    +     available,  it  probably  isn't  the correct version to link
    +     with threaded programs.
    +
    +     Reentrant functions for iterating through the password  file
    +     aren't  available,  so  when  the  library is compiled to be
    +     reentrant, TAB completion of incomplete usernames in  ~user-
    +     name/  expressions  is disabled. This doesn't disable expan-
    +     sion of complete ~username expressions, which  can  be  done
    +     reentrantly,  or  expansion  of  the parts of filenames that
    +     follow them, so this doesn't remove much functionality.
    +
    +     The terminfo functions setupterm(),  tigetstr(),  tigetnum()
    +     and  tputs()  also  aren't  reentrant, but very few programs
    +     will want to  interact  with  multiple  terminals,  so  this
    +     shouldn't  prevent  this library from being used in threaded
    +     programs.
    +
    +
    +

    LIBRARY VERSION NUMBER

    +     The version number of the library can be queried  using  the
    +     following function.
    +
    +      void libtecla_version(int *major, int *minor, int *micro);
    +
    +
    +     On return, this function records the three components of the
    +     libtecla  version number in *major, *minor, *micro. The for-
    +     mal meaning of the three components is as follows.
    +
    +
    +      major - Incrementing this number implies that a change has
    +              been made to the library's public interface, which
    +              makes it binary incompatible  with programs that
    +              were linked with previous shared versions of the
    +              tecla library.
    +
    +      minor - This number is incremented by one whenever
    +              additional functionality, such as new functions or
    +              modules, are added to the library.
    +
    +      micro - This is incremented whenever modifications to the
    +              library are made which make no changes to the
    +              public interface, but which fix bugs and/or improve
    +              the behind-the-scenes implementation.
    +
    +
    +
    +

    TRIVIA

    +     In Spanish, a "tecla" is the key of a keyboard.  Since  this
    +     library  centers  on  keyboard input, and given that I wrote
    +     much of the library while working in Chile, this seemed like
    +     a suitable name.
    +
    +
    +

    FILES

    +     libtecla.a    -   The tecla library.
    +     libtecla.h    -   The tecla header file.
    +     ~/.teclarc    -   The tecla personal customization file.
    +
    +
    +
    +

    SEE ALSO

    +     gl_get_line(3),   ef_expand_file(3),   cpl_complete_word(3),
    +     pca_lookup_file(3), enhance(3)
    +
    +
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +

    ACKNOWLEDGMENTS

    +     Markus Gyger  - Lots of assistance, including help with
    +                     shared libraries, configuration information,
    +                     particularly for Solaris; modifications to
    +                     support C++ compilers, improvements for ksh
    +                     users, faster cursor motion, output
    +                     buffering, and changes to make gl_get_line()
    +                     8-bit clean.
    +     Mike MacFaden - Suggestions, feedback and testing that led
    +                     to many of the major new functions that were
    +                     added in version 1.4.0.
    +     Tim Eliseo    - Many vi-mode bindings and fixes.
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/pca_lookup_file.html b/libtecla-1.4.1/html/pca_lookup_file.html new file mode 100644 index 0000000..40c9f2b --- /dev/null +++ b/libtecla-1.4.1/html/pca_lookup_file.html @@ -0,0 +1,371 @@ + +Manual Page + + +
    +

    NAME

    +     pca_lookup_file,       del_PathCache,       del_PcaPathConf,
    +     new_PathCache,        new_PcaPathConf,       pca_last_error,
    +     pca_path_completions,    pca_scan_path,    pca_set_check_fn,
    +     ppc_file_start,  ppc_literal_escapes  -  lookup  a file in a
    +     list of directories
    +
    +

    SYNOPSIS

    +     #include <libtecla.h>
    +
    +     PathCache *new_PathCache(void);
    +
    +     PathCache *del_PathCache(PathCache *pc);
    +
    +     int pca_scan_path(PathCache *pc, const char *path);
    +
    +     void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn,
    +                           void *data);
    +
    +     char *pca_lookup_file(PathCache *pc, const char *name,
    +                           int name_len, int literal);
    +
    +     const char *pca_last_error(PathCache *pc);
    +
    +     CPL_MATCH_FN(pca_path_completions);
    +
    +
    +
    +

    DESCRIPTION

    +     The PathCache object is part of the tecla library  (see  the
    +     libtecla(3) man page).
    +
    +     PathCache objects allow an application to search  for  files
    +     in any colon separated list of directories, such as the unix
    +     execution  PATH  environment  variable.  Files  in  absolute
    +     directories  are cached in a PathCache object, whereas rela-
    +     tive directories are scanned as needed.  Using  a  PathCache
    +     object,  you  can  look  up  the  full  pathname of a simple
    +     filename, or you can obtain a list of the  possible  comple-
    +     tions  of  a  given filename prefix. By default all files in
    +     the list of directories are targets for lookup  and  comple-
    +     tion, but a versatile mechanism is provided for only select-
    +     ing specific types of files. The obvious application of this
    +     facility  is to provide Tab-completion and lookup of execut-
    +     able commands in the unix  PATH,  so  an  optional  callback
    +     which rejects all but executable files, is provided.
    +
    +
    +

    AN EXAMPLE

    +     Under UNIX, the  following  example  program  looks  up  and
    +     displays  the full pathnames of each of the command names on
    +     the command line.
    +       #include <stdio.h>
    +       #include <stdlib.h>
    +       #include <libtecla.h>
    +
    +       int main(int argc, char *argv[])
    +       {
    +         int i;
    +       /*
    +        * Create a cache for executable files.
    +        */
    +         PathCache *pc = new_PathCache();
    +         if(!pc)
    +           exit(1);
    +       /*
    +        * Scan the user's PATH for executables.
    +        */
    +         if(pca_scan_path(pc, getenv("PATH"))) {
    +           fprintf(stderr, "%s\n", pca_last_error(pc));
    +           exit(1);
    +         }
    +       /*
    +        * Arrange to only report executable files.
    +        */
    +        pca_set_check_fn(pc, cpl_check_exe, NULL);
    +       /*
    +        * Lookup and display the full pathname of each of the
    +        * commands listed on the command line.
    +        */
    +         for(i=1; i<argc; i++) {
    +           char *cmd = pca_lookup_file(pc, argv[i], -1, 0);
    +           printf("The full pathname of '%s' is %s\n", argv[i],
    +                  cmd ? cmd : "unknown");
    +         }
    +         pc = del_PathCache(pc);  /* Clean up */
    +         return 0;
    +       }
    +
    +     The following is an example of what this does on  my  laptop
    +     under linux:
    +
    +       $ ./example less more blob
    +       The full pathname of 'less' is /usr/bin/less
    +       The full pathname of 'more' is /bin/more
    +       The full pathname of 'blob' is unknown
    +       $
    +
    +
    +

    FUNCTION DESCRIPTIONS

    +     In order to use the facilities  of  this  module,  you  must
    +     first   allocate   a   PathCache   object   by  calling  the
    +     new_PathCache() constructor function.
    +
    +       PathCache *new_PathCache(void)
    +
    +     This function creates the  resources  needed  to  cache  and
    +     lookup  files  in  a list of directories. It returns NULL on
    +     error.
    +
    +
    +

    POPULATING THE CACHE

    +     Once you have created a cache, it needs to be populated with
    +     files.  To do this, call the pca_scan_path() function.
    +
    +       int pca_scan_path(PathCache *pc, const char *path);
    +
    +     Whenever this function is called, it  discards  the  current
    +     contents  of  the  cache, then scans the list of directories
    +     specified in its path argument for files. The path  argument
    +     must be a string containing a colon-separated list of direc-
    +     tories, such as "/usr/bin:/home/mcs/bin:.". This can include
    +     directories   specified   by   absolute  pathnames  such  as
    +     "/usr/bin", as well as sub-directories specified by relative
    +     pathnames such as "." or "bin". Files in the absolute direc-
    +     tories are immediately cached  in  the  specified  PathCache
    +     object,  whereas sub-directories, whose identities obviously
    +     change whenever the current working  directory  is  changed,
    +     are  marked  to  be  scanned  on  the fly whenever a file is
    +     looked up.
    +
    +     On success this function return 0. On error  it  returns  1,
    +     and  a  description  of the error can be obtained by calling
    +     pca_last_error(pc).
    +
    +
    +

    LOOKING UP FILES

    +     Once the cache has been populated with files, you  can  look
    +     up  the  full  pathname  of a file, simply by specifying its
    +     filename to pca_lookup_file().
    +
    +       char *pca_lookup_file(PathCache *pc, const char *name,
    +                             int name_len, int literal);
    +
    +     To make it possible to pass this function a  filename  which
    +     is  actually  part of a longer string, the name_len argument
    +     can be used to specify the length of  the  filename  at  the
    +     start  of  the  name[]  argument.  If  you  pass -1 for this
    +     length, the length of the string  will  be  determined  with
    +     strlen().  If  the  name[]  string might contain backslashes
    +     that escape the special meanings of spaces and  tabs  within
    +     the filename, give the literal argument, the value 0. Other-
    +     wise, if backslashes should be treated as normal characters,
    +     pass 1 for the value of the literal argument.
    +
    +
    +

    FILENAME COMPLETION

    +     Looking up the potential completions of a filename-prefix in
    +     the  filename  cache,  is  achieved  by passing the provided
    +     pca_path_completions()    callback    function    to     the
    +     cpl_complete_word()  function  (see the cpl_complete_word(3)
    +     man page).
    +
    +       CPL_MATCH_FN(pca_path_completions);
    +
    +     This callback requires that its data argument be  a  pointer
    +     to  a PcaPathConf object. Configuration objects of this type
    +     are allocated by calling new_PcaPathConf().
    +
    +       PcaPathConf *new_PcaPathConf(PathCache *pc);
    +
    +     This function returns an  object  initialized  with  default
    +     configuration    parameters,   which   determine   how   the
    +     cpl_path_completions() callback function behaves. The  func-
    +     tions  which  allow you to individually change these parame-
    +     ters are discussed below.
    +
    +     By default,  the  pca_path_completions()  callback  function
    +     searches  backwards for the start of the filename being com-
    +     pleted, looking for the first un-escaped space or the  start
    +     of  the input line. If you wish to specify a different loca-
    +     tion, call ppc_file_start() with  the  index  at  which  the
    +     filename  starts  in  the input line. Passing start_index=-1
    +     re-enables the default behavior.
    +
    +       void ppc_file_start(PcaPathConf *ppc, int start_index);
    +
    +     By default, when pca_path_completions() looks at a  filename
    +     in  the input line, each lone backslash in the input line is
    +     interpreted as being a special character which  removes  any
    +     special significance of the character which follows it, such
    +     as a space which should be taken as  part  of  the  filename
    +     rather  than  delimiting  the  start  of the filename. These
    +     backslashes are thus ignored while looking for  completions,
    +     and  subsequently  added  before  spaces,  tabs  and literal
    +     backslashes in the list of completions.  To  have  unescaped
    +     backslashes    treated    as    normal    characters,   call
    +     ppc_literal_escapes() with a non-zero value in  its  literal
    +     argument.
    +
    +       void ppc_literal_escapes(PcaPathConf *ppc, int literal);
    +
    +     When you have finished with a PcaPathConf variable, you  can
    +     pass  it  to  the  del_PcaPathConf()  destructor function to
    +     reclaim its memory.
    +
    +       PcaPathConf *del_PcaPathConf(PcaPathConf *ppc);
    +
    +

    BEING SELECTIVE

    +     If you are only interested in certain types or  files,  such
    +     as,  for example, executable files, or files whose names end
    +     in a particular suffix, you can arrange for the file comple-
    +     tion  and  lookup functions to be selective in the filenames
    +     that they return.  This is done by  registering  a  callback
    +     function  with your PathCache object. Thereafter, whenever a
    +     filename is found which  either  matches  a  filename  being
    +     looked  up,  or  matches  a prefix which is being completed,
    +     your callback function will be called with the full pathname
    +     of  the  file,  plus  any application-specific data that you
    +     provide, and if the callback returns 1 the filename will  be
    +     reported  as  a  match,  and  if  it  returns  0, it will be
    +     ignored.  Suitable callback functions and  their  prototypes
    +     should  be declared with the following macro. The CplCheckFn
    +     typedef is  also  provided  in  case  you  wish  to  declare
    +     pointers to such functions.
    +
    +       #define CPL_CHECK_FN(fn) int (fn)(void *data, \
    +                                         const char *pathname)
    +       typedef CPL_CHECK_FN(CplCheckFn);
    +
    +     Registering one of  these  functions  involves  calling  the
    +     pca_set_check_fn()  function.  In  addition  to the callback
    +     function, passed via the check_fn argument, you can  pass  a
    +     pointer to anything via the data argument. This pointer will
    +     be passed on to your callback function,  via  its  own  data
    +     argument,  whenever  it is called, so this provides a way to
    +     pass appplication specific data to your callback.
    +
    +       void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn,
    +                             void *data);
    +
    +     Note that these callbacks are passed the  full  pathname  of
    +     each  matching file, so the decision about whether a file is
    +     of interest can be based on any property of  the  file,  not
    +     just   its   filename.   As   an   example,   the   provided
    +     cpl_check_exe() callback function looks  at  the  executable
    +     permissions  of  the  file and the permissions of its parent
    +     directories, and only returns 1 if the user has execute per-
    +     mission to the file. This callback function can thus be used
    +     to lookup or complete command names found in the directories
    +     listed  in the user's PATH environment variable. The example
    +     program given earlier in this man page provides a demonstra-
    +     tion of this.
    +
    +     Beware that if somebody tries to complete an  empty  string,
    +     your  callback  will  get  called once for every file in the
    +     cache, which could number in the thousands. If your callback
    +     does  anything time consuming, this could result in an unac-
    +     ceptable delay for the user, so  callbacks  should  be  kept
    +     short.
    +     To improve performance, whenever one of these  callbacks  is
    +     called,  the  choice  that  it makes is cached, and the next
    +     time the corresponding file is looked up, instead of calling
    +     the  callback  again,  the  cached  record of whether it was
    +     accepted or rejected is used. Thus if somebody tries to com-
    +     plete an empty string, and hits tab a second time when noth-
    +     ing appears to happen, there will only be  one  long  delay,
    +     since  the second pass will operate entirely from the cached
    +     dispositions of the files. These cached dipositions are dis-
    +     carded  whenever  pca_scan_path()  is  called,  and whenever
    +     pca_set_check_fn() is called with changed callback  function
    +     or data arguments.
    +
    +
    +

    ERROR HANDLING

    +     If pca_scan_path() reports that an error occurred by return-
    +     ing  1,  you  can obtain a terse description of the error by
    +     calling pca_last_error(pc). This returns an internal  string
    +     containing an error message.
    +
    +       const char *pca_last_error(PathCache *pc);
    +
    +
    +
    +

    CLEANING UP

    +     Once you have finished using a  PathCache  object,  you  can
    +     reclaim  its  resources by passing it to the del_PathCache()
    +     destructor function. This takes a pointer to  one  of  these
    +     objects, and always returns NULL.
    +
    +       PathCache *del_PathCache(PathCache *pc);
    +
    +
    +

    THREAD SAFETY

    +     In multi-threaded programs, you should use the  libtecla_r.a
    +     version  of the library. This uses POSIX reentrant functions
    +     where available (hence the _r suffix), and disables features
    +     that  rely on non-reentrant system functions. In the case of
    +     this module, the only disabled feature is  username  comple-
    +     tion in ~username/ expressions, in cpl_path_completions().
    +
    +     Using the libtecla_r.a version of the library, it is safe to
    +     use  the facilities of this module in multiple threads, pro-
    +     vided that each thread uses a separately allocated PathCache
    +     object.  In  other  words,  if  two  threads want to do path
    +     searching, they should each call new_PathCache() to allocate
    +     their own caches.
    +
    +
    +

    FILES

    +     libtecla.a    -    The tecla library
    +     libtecla.h    -    The tecla header file.
    +

    SEE ALSO

    +     libtecla(3),       gl_get_line(3),        ef_expand_file(3),
    +     cpl_complete_word(3)
    +
    +
    +

    AUTHOR

    +     Martin Shepherd  (mcs@astro.caltech.edu)
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + diff --git a/libtecla-1.4.1/html/release.html b/libtecla-1.4.1/html/release.html new file mode 100644 index 0000000..e0d219c --- /dev/null +++ b/libtecla-1.4.1/html/release.html @@ -0,0 +1,360 @@ +The tecla library release notes +
    +This file lists major changes which accompany each new release.
    +
    +Version 1.4.1:
    +
    +  This is a maintenance release. It includes minor changes to support
    +  Mac OS X (Darwin), the QNX real-time operating system, and Cygwin
    +  under Windows. It also fixes an oversight that was preventing the
    +  tab key from inserting tab characters when users unbound the
    +  complete-word action from it.
    +
    +Version 1.4.0:
    +
    +  The contents of the history list can now be saved and restored with
    +  the new gl_save_history() and gl_load_history() functions.
    +
    +  Event handlers can now be registered to watch for and respond to I/O
    +  on arbitrary file descriptors while gl_get_line() is waiting for
    +  terminal input from the user. See the gl_get_line(3) man page
    +  for details on gl_watch_fd().
    +
    +  As an optional alternative to getting configuration information only
    +  from ~/.teclarc, the new gl_configure_getline() function allows
    +  configuration commands to be taken from any of, a string, a
    +  specified application-specific file, and/or a specified
    +  user-specific file. See the gl_get_line(3) man page for details.
    +
    +  The version number of the library can now be queried using the
    +  libtecla_version() function. See the libtecla(3) man page.
    +
    +  The new gl_group_history() function allows applications to group
    +  different types of input line in the history buffer, and arrange for
    +  only members of the appropriate group to be recalled on a given call
    +  to gl_get_line(). See the gl_get_line(3) man page.
    +
    +  The new gl_show_history() function displays the current history list
    +  to a given stdio output stream. See the gl_get_line(3) man page.
    +
    +  new_GetLine() now allows you to specify a history buffer size of
    +  zero, thus requesting that no history buffer be allocated. You can
    +  subsequently resize or delete the history buffer at any time, by
    +  calling gl_resize_history(), limit the number of lines that are
    +  allowed in the buffer by calling gl_limit_history(), clear either
    +  all history lines from the history list, or just the history lines
    +  that are associated with the current history group, by calling
    +  gl_clear_history, and toggle the history mechanism on and off by
    +  calling gl_toggle_history().
    +
    +  The new gl_terminal_size() function can be used to query the
    +  current terminal size. It can also be used to supply a default
    +  terminal size on systems where no mechanism is available for
    +  looking up the size.
    +
    +  The contents and configuration of the history list can now be
    +  obtained by the calling application, by calling the new
    +  gl_lookup_history(), gl_state_of_history(), gl_range_of_history()
    +  and gl_size_of_history() functions. See the gl_get_line(3) man page.
    +
    +  Echoing of the input line as it is typed, can now be turned on and
    +  off via the new gl_echo_mode() function. While echoing is disabled,
    +  newly entered input lines are omitted from the history list.  See
    +  the gl_get_line(3) man page.
    +
    +  While the default remains to display the prompt string literally,
    +  the new gl_prompt_style() function can be used to enable text
    +  attribute formatting directives in prompt strings, such as
    +  underlining, bold font, and highlighting directives.
    +
    +  Signal handling in gl_get_line() is now customizable. The default
    +  signal handling behavior remains essentially the same, except that
    +  the SIGTSTP, SIGTTIN and SIGTTOU are now forwarded to the
    +  corresponding signal handler of the calling program, instead of
    +  causing a SIGSTOP to be sent to the application.  It is now possible
    +  to remove signals from the list that are trapped by gl_get_line(),
    +  as well as add new signals to this list. The signal and terminal
    +  environments in which the signal handler of the calling program is
    +  invoked, and what gl_get_line() does after the signal handler
    +  returns, is now customizable on a per signal basis. You can now also
    +  query the last signal that was caught by gl_get_line(). This is
    +  useful when gl_get_line() aborts with errno=EINTR, and you need to
    +  know which signal caused it to abort.
    +
    +  Key-sequences bound to action functions can now start with printable
    +  characters. Previously only keysequences starting with control or
    +  meta characters were permitted.
    +
    +  gl_get_line() is now 8-bit clean. If the calling program has
    +  correctly called setlocale(LC_CTYPE,""), then the user can select an
    +  alternate locale by setting the standard LC_CTYPE, LC_ALL, or LANG
    +  environment variables, and international characters can then be
    +  entered directly, either by using a non-US keyboard, or by using a
    +  compose key on a standard US keyboard. Note that in locales in which
    +  meta characters become printable, meta characters no longer match
    +  M-c bindings, which then have to be entered using their escape-c
    +  equivalents.  Fortunately most modern terminal emulators either
    +  output the escape-c version by default when the meta key is used, or
    +  can be configured to do so (see the gl_get_line(3) man page), so in
    +  most cases you can continue to use the meta key.
    +
    +  Completion callback functions can now tell gl_get_line() to return
    +  the input line immediately after a successful tab completion, simply
    +  by setting the last character of the optional continuation suffix to
    +  a newline character (ie. in the call to cpl_add_completion()).
    +
    +  It is now safe to create and use multiple GetLine objects, albeit
    +  still only from a single thread. In conjunction with the new
    +  gl_configure_getline() function, this optionally allows multiple
    +  GetLine objects with different bindings to be used to implement
    +  different input modes.
    +
    +  The edit-mode configuration command now accepts the argument,
    +  none. This tells gl_get_line() to revert to using just the native
    +  line editing facilities provided by the terminal driver. This could
    +  be used if the termcap or terminfo entry of the host terminal were
    +  badly corrupted.
    +
    +  Application callback functions invoked by gl_get_line() can now
    +  change the displayed prompt using the gl_replace_prompt() function.
    +
    +  Their is now an optional program distributed with the library. This
    +  is a beta release of a program which adds tecla command-line editing
    +  to virtually any third party application without the application
    +  needing to be linked to the library. See the enhance(3) man page for
    +  further details. Although built and installed by default, the
    +  INSTALL document explains how to prevent this.
    +
    +  The INSTALL document now explains how you can stop the demo programs
    +  from being built and installed.
    +
    +  NetBSD/termcap fixes. Mike MacFaden reported two problems that he
    +  saw when compiling libtecla under NetBSD. Both cases were related to
    +  the use of termcap.  Most systems use terminfo, so this problem has
    +  gone unnoticed until now, and won't have affected the grand majority
    +  of users.  The configure script had a bug which prevented the check
    +  for CPP working properly, and getline.c wouldn't compile due to an
    +  undeclared variable when USE_TERMCAP was defined. Both problems have
    +  now been fixed. Note that if you successfully compiled version
    +  1.3.3, this problem didn't affect you.
    +
    +  An unfortunate and undocumented binding of the key-sequence M-O was
    +  shadowing the arrow-key bindings on systems that use ^[OA etc. I
    +  have removed this binding (the documented lower case M-o binding
    +  remains bound). Under the KDE konsole terminal this was causing the
    +  arrow keys to do something other than expected.
    +
    +  There was a bug in the history list code which could result in
    +  strange entries appearing at the start of the history list once
    +  enough history lines had been added to the list to cause the
    +  circular history buffer to wrap. This is now fixed.
    + 
    +Version 1.3.3:
    +
    +  Signal handling has been re-written, and documentation of its
    +  behaviour has been added to the gl_get_line(3) man page. In addition
    +  to eliminating race conditions, and appropriately setting errno for
    +  those signals that abort gl_get_line(), many more signals are now
    +  intercepted, making it less likely that the terminal will be left in
    +  raw mode by a signal that isn't trapped by gl_get_line().
    +
    +  A bug was also fixed that was leaving the terminal in raw mode if
    +  the editing mode was changed interactively between vi and emacs.
    +  This was only noticeable when running programs from old shells that
    +  don't reset terminal modes.
    +
    +Version 1.3.2:
    +
    +  Tim Eliseo contributed a number of improvements to vi mode,
    +  including a fuller set of vi key-bindings, implementation of the vi
    +  constraint that the cursor can't backup past the point at which
    +  input mode was entered, and restoration of overwritten characters
    +  when backspacing in overwrite mode. There are also now new bindings
    +  to allow users to toggle between vi and emacs modes interactively.
    +  The terminal bell is now used in some circumstances, such as when an
    +  unrecognized key sequence is entered. This can be turned off by the
    +  new nobeep option in the tecla configuration file.
    +
    +  Unrelated to the above, a problem under Linux which prevented ^Q
    +  from being used to resume terminal output after the user had pressed
    +  ^S, has been fixed.
    +
    +Version 1.3.1:
    +
    +  In vi mode a bug was preventing the history-search-backward and
    +  history-search-forward actions from doing anything when invoked on
    +  empty lines. On empty lines they now act like up-history and
    +  down-history respectively, as in emacs mode.
    +
    +  When creating shared libraries under Linux, the -soname directive
    +  was being used incorrectly. The result is that Linux binaries linked
    +  with the 1.2.3, 1.2.4 and 1.3.0 versions of the tecla shared
    +  libraries, will refuse to see other versions of the shared library
    +  until relinked with version 1.3.1 or higher.
    +
    +  The configure script can now handle the fact that under Solaris-2.6
    +  and earlier, the only curses library is a static one that hides in
    +  /usr/ccs/lib. Under Linux it now also caters for old versions of GNU
    +  ld which don't accept version scripts.
    +
    +  The demos are now linked against the shared version of the library
    +  if possible. Previously they were always linked with the static
    +  version.
    +
    +Version 1.3.0:
    +
    +  The major change in this release is the addition of an optional vi
    +  command-line editing mode in gl_get_line(), along with lots of new
    +  action functions to support its bindings. To enable this, first
    +  create a ~/.teclarc file if you don't already have one, then add the
    +  following line to it.
    +
    +   edit-mode vi
    +
    +  The default vi bindings, which are designed to mimic those of the vi
    +  editor as closely as possible, are described in the gl_get_line(3)
    +  man page.
    +
    +  A new convenience function called ef_list_expansions() has been
    +  added for listing filename expansions. See the ef_list_expansions(3)
    +  man page for details. This is used in a new list-glob binding, bound
    +  to ^Xg in emacs mode, and ^G in vi input mode.
    +
    +  A bug has been fixed in the key-binding table expansion code. This
    +  bug would have caused problems to anybody who defined more than
    +  about 18 personalized key-bindings in their ~/.teclarc file.
    +
    +Version 1.2.4:
    +
    +  Buffered I/O is now used for writing to terminals, and where
    +  supported, cursor motion is done with move-n-positions terminfo
    +  capabilities instead of doing lots of move-1-position requests. This
    +  greatly improves how the library feels over slow links.
    +
    +  You can now optionally compile different architectures in different
    +  directories, without having to make multiple copies of the
    +  distribution. This is documented in the INSTALL file.
    +
    +  The ksh ~+ directive is now supported.
    +
    +  Thanks to Markus Gyger for the above improvements.
    +
    +  Documentation has been added to the INSTALL file describing features
    +  designed to facilitate configuration and installation of the library
    +  as part of larger packages. These features are intended to remove
    +  the need to modify the tecla distribution's configuration and build
    +  procedures when embedding the libtecla distribution in other package
    +  distributions.
    +
    +  A previous fix to stop the cursor from warping when the last
    +  character of the input line was in the last column of the terminal,
    +  was only being used for the first terminal line of the input line.
    +  It is now used for all subsequent lines as well, as originally
    +  intended.
    +  
    +Version 1.2.3:
    +
    +  The installation procedure has been better automated with the
    +  addition of an autoconf configure script. This means that installers
    +  can now compile and install the library by typing:
    +
    +    ./configure
    +    make
    +    make install
    +
    +  On all systems this makes at least the normal static version of the
    +  tecla library. It also makes the reentrant version if reentrant
    +  POSIX functions are detected.  Under Solaris, Linux and HP-UX the
    +  configuration script arranges for shared libraries to be compiled in
    +  addition to the static libraries.  It is hoped that installers will
    +  return information about how to compile shared libraries on other
    +  systems, for inclusion in future releases, and to this end, a new
    +  PORTING guide has been provided.
    +
    +  The versioning number scheme has been changed. This release would
    +  have been 1.2c, but instead will be refered to as 1.2.3. The
    +  versioning scheme, based on conventions used by Sun Microsystems, is
    +  described in configure.in.
    +
    +  The library was also tested under HP-UX, and this revealed two
    +  serious bugs, both of which have now been fixed.
    +  
    +  The first bug prevented the library from writing control codes to
    +  terminals on big-endian machines, with the exception of those
    +  running under Solaris. This was due to an int variable being used
    +  where a char was needed.
    +
    +  The second bug had the symptom that on systems that don't use the
    +  newline character as the control code for moving the cursor down a
    +  line, a newline wasn't started when the user hit enter.
    +
    +Version 1.2b:
    +
    +  Two more minor bug fixes:
    +
    +  Many terminals don't wrap the cursor to the next line when a
    +  character is written to the rightmost terminal column. Instead, they
    +  delay starting a new line until one more character is written, at
    +  which point they move the cursor two positions.  gl_get_line()
    +  wasn't aware of this, so cursor repositionings just after writing
    +  the last character of a column, caused it to erroneously go up a
    +  line. This has now been remedied, using a method that should work
    +  regardless of whether a terminal exhibits this behavior or not.
    +
    +  Some systems dynamically record the current terminal dimensions in
    +  environment variables called LINES and COLUMNS. On such systems,
    +  during the initial terminal setup, these values should override the
    +  static values read from the terminal information databases, and now
    +  do.  Previously they were only used if the dimensions returned by
    +  terminfo/termcap looked bogus.
    +
    +Version 1.2a:
    +
    +  This minor release fixes the following two bugs:
    +
    +  The initial terminal size and subsequent changes thereto, weren't
    +  being noticed by gl_get_line(). This was because the test for the
    +  existence of TIOCWINSZ was erroneously placed before the inclusion
    +  of termios.h. One of the results was that on input lines that
    +  spanned more than one terminal line, the cursor occasionally jumped
    +  unexpectedly to the previous terminal line.
    +
    +  On entering a line that wrapped over multiple terminal lines,
    +  gl_get_line() simply output a carriage-return line-feed at the point
    +  at which the user pressed return. Thus if one typed in such a line,
    +  then moved back onto one of the earlier terminal lines before
    +  hitting return, the cursor was left on a line containing part of the
    +  line that had just been entered. This didn't do any harm, but it
    +  looked a mess.
    +
    +Version 1.2:
    +
    +  A new facility for looking up and completing filenames in UNIX-style
    +  paths has now been added (eg. you can search for, or complete
    +  commands using the UNIX PATH environment variable). See the
    +  pca_lookup_file(3) man page.
    +
    +  The already existing filename completion callback can now be made
    +  selective in what types of files it lists. See the
    +  cpl_complete_word(3) man page.
    +
    +  Due to its potential to break applications when changed, the use of
    +  the publically defined CplFileArgs structure to configure the
    +  cpl_file_completions() callback is now deprecated.  The definition
    +  of this structure has been frozen, and its documentation has been
    +  removed from the man pages.  It will remain supported, but if you
    +  have used it, you are recommended to switch to the new method, which
    +  involves a new opaque configuration object, allocated via a provided
    +  constructor function, configured via accessor functions, and
    +  eventually deleted with a provided destructor function. The
    +  cpl_file_completions() callback distinguishes which structure type
    +  it has been sent by virtue of a code placed at the start of the new
    +  structure by the constructor.  It is assumed that no existing
    +  applications set the boolean 'escaped' member of the CplFileArgs
    +  structure to 4568.  The new method is documented in the
    +  cpl_complete_word(3) man page.
    +
    +Version 1.1j
    +
    +  This was the initial public release on freshmeat.org.
    +
    diff --git a/libtecla-1.4.1/install-sh b/libtecla-1.4.1/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/libtecla-1.4.1/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/libtecla-1.4.1/keytab.c b/libtecla-1.4.1/keytab.c new file mode 100644 index 0000000..b2bab8b --- /dev/null +++ b/libtecla-1.4.1/keytab.c @@ -0,0 +1,827 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include +#include + +#include "keytab.h" +#include "getline.h" +#include "strngmem.h" + +static int _kt_extend_table(KeyTab *kt); +static int _kt_parse_keybinding_string(const char *keyseq, + char *binary, int *nc); +static int _kt_compare_strings(const char *s1, int n1, const char *s2, int n2); +static void _kt_assign_action(KeySym *sym, KtBinder binder, KtKeyFn *keyfn); +static char _kt_backslash_escape(const char *string, const char **endp); +static int _kt_is_emacs_meta(const char *string); +static int _kt_is_emacs_ctrl(const char *string); + +/*....................................................................... + * Create a new key-binding symbol table. + * + * Output: + * return KeyTab * The new object, or NULL on error. + */ +KeyTab *_new_KeyTab(void) +{ + KeyTab *kt; /* The object to be returned */ +/* + * Allocate the container. + */ + kt = (KeyTab *) malloc(sizeof(KeyTab)); + if(!kt) { + fprintf(stderr, "new_KeyTab: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_KeyTab(). + */ + kt->size = KT_TABLE_INC; + kt->nkey = 0; + kt->table = NULL; + kt->actions = NULL; + kt->smem = NULL; +/* + * Allocate the table. + */ + kt->table = (KeySym *) malloc(sizeof(kt->table[0]) * kt->size); + if(!kt->table) { + fprintf(stderr, "new_KeyTab: Insufficient memory for table of size %d.\n", + kt->size); + return _del_KeyTab(kt); + }; +/* + * Allocate a hash table of actions. + */ + kt->actions = _new_HashTable(NULL, KT_HASH_SIZE, IGNORE_CASE, NULL, 0); + if(!kt->actions) + return _del_KeyTab(kt); +/* + * Allocate a string allocation object. This allows allocation of + * small strings without fragmenting the heap. + */ + kt->smem = _new_StringMem("new_KeyTab", KT_TABLE_INC); + if(!kt->smem) + return _del_KeyTab(kt); + return kt; +} + +/*....................................................................... + * Delete a KeyTab object. + * + * Input: + * kt KeyTab * The object to be deleted. + * Output: + * return KeyTab * The deleted object (always NULL). + */ +KeyTab *_del_KeyTab(KeyTab *kt) +{ + if(kt) { + if(kt->table) + free(kt->table); + kt->actions = _del_HashTable(kt->actions); + kt->smem = _del_StringMem("del_KeyTab", kt->smem, 1); + free(kt); + }; + return NULL; +} + +/*....................................................................... + * Increase the size of the table to accomodate more keys. + * + * Input: + * kt KeyTab * The table to be extended. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _kt_extend_table(KeyTab *kt) +{ +/* + * Attempt to increase the size of the table. + */ + KeySym *newtab = (KeySym *) realloc(kt->table, sizeof(kt->table[0]) * + (kt->size + KT_TABLE_INC)); +/* + * Failed? + */ + if(!newtab) { + fprintf(stderr, + "getline(): Insufficient memory to extend keybinding table.\n"); + return 1; + }; +/* + * Install the resized table. + */ + kt->table = newtab; + kt->size += KT_TABLE_INC; + return 0; +} + +/*....................................................................... + * Add, update or remove a keybinding to the table. + * + * Input: + * kt KeyTab * The table to add the binding to. + * binder KtBinder The source of the binding. + * keyseq const char * The key-sequence to bind. + * action char * The action to associate with the key sequence, or + * NULL to remove the action associated with the + * key sequence. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _kt_set_keybinding(KeyTab *kt, KtBinder binder, const char *keyseq, + const char *action) +{ + KtKeyFn *keyfn; /* The action function */ +/* + * Check arguments. + */ + if(kt==NULL || !keyseq) { + fprintf(stderr, "kt_set_keybinding: NULL argument(s).\n"); + return 1; + }; +/* + * Lookup the function that implements the specified action. + */ + if(!action) { + keyfn = 0; + } else { + Symbol *sym = _find_HashSymbol(kt->actions, action); + if(!sym) { + fprintf(stderr, "getline: Unknown key-binding action: %s\n", action); + return 1; + }; + keyfn = (KtKeyFn *) sym->fn; + }; +/* + * Record the action in the table. + */ + return _kt_set_keyfn(kt, binder, keyseq, keyfn); +} + +/*....................................................................... + * Add, update or remove a keybinding to the table, specifying an action + * function directly. + * + * Input: + * kt KeyTab * The table to add the binding to. + * binder KtBinder The source of the binding. + * keyseq char * The key-sequence to bind. + * keyfn KtKeyFn * The action function, or NULL to remove any existing + * action function. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _kt_set_keyfn(KeyTab *kt, KtBinder binder, const char *keyseq, + KtKeyFn *keyfn) +{ + const char *kptr; /* A pointer into keyseq[] */ + char *binary; /* The binary version of keyseq[] */ + int nc; /* The number of characters in binary[] */ + int first,last; /* The first and last entries in the table which */ + /* minimally match. */ + int size; /* The size to allocate for the binary string */ +/* + * Check arguments. + */ + if(kt==NULL || !keyseq) { + fprintf(stderr, "kt_set_keybinding: NULL argument(s).\n"); + return 1; + }; +/* + * Work out a pessimistic estimate of how much space will be needed + * for the binary copy of the string, noting that binary meta characters + * embedded in the input string get split into two characters. + */ + for(size=0,kptr = keyseq; *kptr; kptr++) + size += IS_META_CHAR(*kptr) ? 2 : 1; +/* + * Allocate a string that has the length of keyseq[]. + */ + binary = _new_StringMemString(kt->smem, size + 1); + if(!binary) { + fprintf(stderr, + "gl_get_line: Insufficient memory to record key sequence.\n"); + return 1; + }; +/* + * Convert control and octal character specifications to binary characters. + */ + if(_kt_parse_keybinding_string(keyseq, binary, &nc)) { + binary = _del_StringMemString(kt->smem, binary); + return 1; + }; +/* + * Lookup the position in the table at which to insert the binding. + */ + switch(_kt_lookup_keybinding(kt, binary, nc, &first, &last)) { +/* + * If an exact match for the key-sequence is already in the table, + * simply replace its binding function (or delete the entry if + * the new binding is 0). + */ + case KT_EXACT_MATCH: + if(keyfn) { + _kt_assign_action(kt->table + first, binder, keyfn); + } else { + _del_StringMemString(kt->smem, kt->table[first].keyseq); + memmove(kt->table + first, kt->table + first + 1, + (kt->nkey - first - 1) * sizeof(kt->table[0])); + kt->nkey--; + }; + binary = _del_StringMemString(kt->smem, binary); + break; +/* + * If an ambiguous match has been found and we are installing a + * callback, then our new key-sequence would hide all of the ambiguous + * matches, so we shouldn't allow it. + */ + case KT_AMBIG_MATCH: + if(keyfn) { + fprintf(stderr, + "getline: Can't bind \"%s\", because it's a prefix of another binding.\n", + keyseq); + binary = _del_StringMemString(kt->smem, binary); + return 1; + }; + break; +/* + * If the entry doesn't exist, create it. + */ + case KT_NO_MATCH: +/* + * Add a new binding? + */ + if(keyfn) { + KeySym *sym; +/* + * We will need a new entry, extend the table if needed. + */ + if(kt->nkey + 1 > kt->size) { + if(_kt_extend_table(kt)) { + binary = _del_StringMemString(kt->smem, binary); + return 1; + }; + }; +/* + * Make space to insert the new key-sequence before 'last'. + */ + if(last < kt->nkey) { + memmove(kt->table + last + 1, kt->table + last, + (kt->nkey - last) * sizeof(kt->table[0])); + }; +/* + * Insert the new binding in the vacated position. + */ + sym = kt->table + last; + sym->keyseq = binary; + sym->nc = nc; + sym->user_fn = sym->term_fn = sym->norm_fn = sym->keyfn = 0; + _kt_assign_action(sym, binder, keyfn); + kt->nkey++; + }; + break; + case KT_BAD_MATCH: + binary = _del_StringMemString(kt->smem, binary); + return 1; + break; + }; + return 0; +} + +/*....................................................................... + * Perform a min-match lookup of a key-binding. + * + * Input: + * kt KeyTab * The keybinding table to lookup in. + * binary_keyseq char * The binary key-sequence to lookup. + * nc int the number of characters in keyseq[]. + * Input/Output: + * first,last int * If there is an ambiguous or exact match, the indexes + * of the first and last symbols that minimally match + * will be assigned to *first and *last respectively. + * If there is no match, then first and last will + * bracket the location where the symbol should be + * inserted. + * + * Output: + * return KtKeyMatch One of the following enumerators: + * KT_EXACT_MATCH - An exact match was found. + * KT_AMBIG_MATCH - An ambiguous match was found. + * KT_NO_MATCH - No match was found. + * KT_BAD_MATCH - An error occurred while searching. + */ +KtKeyMatch _kt_lookup_keybinding(KeyTab *kt, const char *binary_keyseq, int nc, + int *first, int *last) +{ + int mid; /* The index at which to bisect the table */ + int bot; /* The lowest index of the table not searched yet */ + int top; /* The highest index of the table not searched yet */ + int test; /* The return value of strcmp() */ +/* + * Check the arguments. + */ + if(!kt || !binary_keyseq || !first || !last || nc < 0) { + fprintf(stderr, "kt_lookup_keybinding: NULL argument(s).\n"); + return KT_BAD_MATCH; + }; +/* + * Perform a binary search for the key-sequence. + */ + bot = 0; + top = kt->nkey - 1; + while(top >= bot) { + mid = (top + bot)/2; + test = _kt_compare_strings(kt->table[mid].keyseq, kt->table[mid].nc, + binary_keyseq, nc); + if(test > 0) + top = mid - 1; + else if(test < 0) + bot = mid + 1; + else { + *first = *last = mid; + return KT_EXACT_MATCH; + }; + }; +/* + * An exact match wasn't found, but top is the index just below the + * index where a match would be found, and bot is the index just above + * where the match ought to be found. + */ + *first = top; + *last = bot; +/* + * See if any ambiguous matches exist, and if so make *first and *last + * refer to the first and last matches. + */ + if(*last < kt->nkey && kt->table[*last].nc > nc && + _kt_compare_strings(kt->table[*last].keyseq, nc, binary_keyseq, nc)==0) { + *first = *last; + while(*last+1 < kt->nkey && kt->table[*last+1].nc > nc && + _kt_compare_strings(kt->table[*last+1].keyseq, nc, binary_keyseq, nc)==0) + (*last)++; + return KT_AMBIG_MATCH; + }; +/* + * No match. + */ + return KT_NO_MATCH; +} + +/*....................................................................... + * Convert a keybinding string into a uniq binary representation. + * + * Control characters can be given directly in their binary form, + * expressed as either ^ or C-, followed by the character, expressed in + * octal, like \129 or via C-style backslash escapes, with the addition + * of '\E' to denote the escape key. Similarly, meta characters can be + * given directly in binary or expressed as M- followed by the character. + * Meta characters are recorded as two characters in the binary output + * string, the first being the escape key, and the second being the key + * that was modified by the meta key. This means that binding to + * \EA or ^[A or M-A are all equivalent. + * + * Input: + * keyseq char * The key sequence being added. + * Input/Output: + * binary char * The binary version of the key sequence will be + * assigned to binary[], which must have at least + * as many characters as keyseq[] plus the number + * of embedded binary meta characters. + * nc int * The number of characters assigned to binary[] + * will be recorded in *nc. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int _kt_parse_keybinding_string(const char *keyseq, char *binary, + int *nc) +{ + const char *iptr = keyseq; /* Pointer into keyseq[] */ + char *optr = binary; /* Pointer into binary[] */ +/* + * Parse the input characters until they are exhausted or the + * output string becomes full. + */ + while(*iptr) { +/* + * Check for special characters. + */ + switch(*iptr) { + case '^': /* A control character specification */ +/* + * Convert the caret expression into the corresponding control + * character unless no character follows the caret, in which case + * record a literal caret. + */ + if(iptr[1]) { + *optr++ = MAKE_CTRL(iptr[1]); + iptr += 2; + } else { + *optr++ = *iptr++; + }; + break; +/* + * A backslash-escaped character? + */ + case '\\': +/* + * Convert the escape sequence to a binary character. + */ + *optr++ = _kt_backslash_escape(iptr+1, &iptr); + break; +/* + * Possibly an emacs-style meta character? + */ + case 'M': + if(_kt_is_emacs_meta(iptr)) { + *optr++ = GL_ESC_CHAR; + iptr += 2; + } else { + *optr++ = *iptr++; + }; + break; +/* + * Possibly an emacs-style control character specification? + */ + case 'C': + if(_kt_is_emacs_ctrl(iptr)) { + *optr++ = MAKE_CTRL(iptr[2]); + iptr += 3; + } else { + *optr++ = *iptr++; + }; + break; + default: + +/* + * Convert embedded meta characters into an escape character followed + * by the meta-unmodified character. + */ + if(IS_META_CHAR(*iptr)) { + *optr++ = GL_ESC_CHAR; + *optr++ = META_TO_CHAR(*iptr); + iptr++; +/* + * To allow keysequences that start with printable characters to + * be distinguished from the cursor-key keywords, prepend a backslash + * to the former. This same operation is performed in gl_interpret_char() + * before looking up a keysequence that starts with a printable character. + */ + } else if(iptr==keyseq && !IS_CTRL_CHAR(*iptr) && + strcmp(keyseq, "up") != 0 && strcmp(keyseq, "down") != 0 && + strcmp(keyseq, "left") != 0 && strcmp(keyseq, "right") != 0) { + *optr++ = '\\'; + *optr++ = *iptr++; + } else { + *optr++ = *iptr++; + }; + }; + }; +/* + * How many characters were placed in the output array? + */ + *nc = optr - binary; + return 0; +} + +/*....................................................................... + * Add, remove or modify an action. + * + * Input: + * kt KeyTab * The key-binding table. + * action char * The name of the action. + * fn KtKeyFn * The function that implements the action, or NULL + * to remove an existing action. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _kt_set_action(KeyTab *kt, const char *action, KtKeyFn *fn) +{ + Symbol *sym; /* The symbol table entry of the action */ +/* + * Check the arguments. + */ + if(!kt || !action) { + fprintf(stderr, "kt_set_action: NULL argument(s).\n"); + return 1; + }; +/* + * If no function was provided, delete an existing action. + */ + if(!fn) { + sym = _del_HashSymbol(kt->actions, action); + return 0; + }; +/* + * If the action already exists, replace its action function. + */ + sym = _find_HashSymbol(kt->actions, action); + if(sym) { + sym->fn = (void (*)(void))fn; + return 0; + }; +/* + * Add a new action. + */ + if(!_new_HashSymbol(kt->actions, action, 0, (void (*)(void))fn, NULL, 0)) { + fprintf(stderr, "Insufficient memory to record new key-binding action.\n"); + return 1; + }; + return 0; +} + +/*....................................................................... + * Compare two strings of specified length which may contain embedded + * ascii NUL's. + * + * Input: + * s1 char * The first of the strings to be compared. + * n1 int The length of the string in s1. + * s2 char * The second of the strings to be compared. + * n2 int The length of the string in s2. + * Output: + * return int < 0 if(s1 < s2) + * 0 if(s1 == s2) + * > 0 if(s1 > s2) + */ +static int _kt_compare_strings(const char *s1, int n1, const char *s2, int n2) +{ + int i; +/* + * Find the first character where the two strings differ. + */ + for(i=0; iuser_fn = keyfn; + break; + case KTB_TERM: + sym->term_fn = keyfn; + break; + case KTB_NORM: + default: + sym->norm_fn = keyfn; + break; + }; +/* + * Which of the current set of bindings should be used? + */ + if(sym->user_fn) + sym->keyfn = sym->user_fn; + else if(sym->norm_fn) + sym->keyfn = sym->norm_fn; + else + sym->keyfn = sym->term_fn; + return; +} + +/*....................................................................... + * Remove all key bindings that came from a specified source. + * + * Input: + * kt KeyTab * The table of key bindings. + * binder KtBinder The source of the bindings to be cleared. + */ +void _kt_clear_bindings(KeyTab *kt, KtBinder binder) +{ + int oldkey; /* The index of a key in the original binding table */ + int newkey; /* The index of a key in the updated binding table */ +/* + * If there is no table, then no bindings exist to be deleted. + */ + if(!kt) + return; +/* + * Clear bindings of the given source. + */ + for(oldkey=0; oldkeynkey; oldkey++) + _kt_assign_action(kt->table + oldkey, binder, 0); +/* + * Delete entries that now don't have a binding from any source. + */ + newkey = 0; + for(oldkey=0; oldkeynkey; oldkey++) { + KeySym *sym = kt->table + oldkey; + if(!sym->keyfn) { + _del_StringMemString(kt->smem, sym->keyseq); + } else { + if(oldkey != newkey) + kt->table[newkey] = *sym; + newkey++; + }; + }; +/* + * Record the number of keys that were kept. + */ + kt->nkey = newkey; + return; +} + +/*....................................................................... + * Translate a backslash escape sequence to a binary character. + * + * Input: + * string const char * The characters that follow the backslash. + * Input/Output: + * endp const char ** If endp!=NULL, on return *endp will be made to + * point to the character in string[] which follows + * the escape sequence. + * Output: + * return char The binary character. + */ +static char _kt_backslash_escape(const char *string, const char **endp) +{ + char c; /* The output character */ +/* + * Is the backslash followed by one or more octal digits? + */ + switch(*string) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c = strtol(string, (char **)&string, 8); + break; + case 'a': + c = '\a'; + string++; + break; + case 'b': + c = '\b'; + string++; + break; + case 'e': case 'E': /* Escape */ + c = GL_ESC_CHAR; + string++; + break; + case 'f': + c = '\f'; + string++; + break; + case 'n': + c = '\n'; + string++; + break; + case 'r': + c = '\r'; + string++; + break; + case 't': + c = '\t'; + string++; + break; + case 'v': + c = '\v'; + string++; + break; + case '\0': + c = '\\'; + break; + default: + c = *string++; + break; + }; +/* + * Report the character which follows the escape sequence. + */ + if(endp) + *endp = string; + return c; +} + +/*....................................................................... + * Return non-zero if the next two characters are M- and a third character + * follows. Otherwise return 0. + * + * Input: + * string const char * The sub-string to scan. + * Output: + * return int 1 - The next two characters are M- and these + * are followed by at least one character. + * 0 - The next two characters aren't M- or no + * character follows a M- pair. + */ +static int _kt_is_emacs_meta(const char *string) +{ + return *string++ == 'M' && *string++ == '-' && *string; +} + +/*....................................................................... + * Return non-zero if the next two characters are C- and a third character + * follows. Otherwise return 0. + * + * Input: + * string const char * The sub-string to scan. + * Output: + * return int 1 - The next two characters are C- and these + * are followed by at least one character. + * 0 - The next two characters aren't C- or no + * character follows a C- pair. + */ +static int _kt_is_emacs_ctrl(const char *string) +{ + return *string++ == 'C' && *string++ == '-' && *string; +} + +/*....................................................................... + * Merge an array of bindings with existing bindings. + * + * Input: + * kt KeyTab * The table of key bindings. + * binder KtBinder The source of the bindings. + * bindings const KtKeyBinding * The array of bindings. + * n int The number of bindings in bindings[]. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int _kt_add_bindings(KeyTab *kt, KtBinder binder, const KtKeyBinding *bindings, + unsigned n) +{ + int i; +/* + * Check the arguments. + */ + if(!kt || !bindings) { + fprintf(stderr, "_kt_add_bindings: NULL argument(s).\n"); + return 1; + }; +/* + * Install the array of bindings. + */ + for(i=0; i /* FILE * */ +#include /* size_t */ +#include /* time_t */ + +/* + * The following are the three components of the libtecla version number. + * Note that it is better to use the libtecla_version() function than these + * macros since the macros only tell you which version of the library your + * code was compiled against, whereas the libtecla_version() function + * tells you which version of the shared tecla library your program is + * actually linked to. + */ +#define TECLA_MAJOR_VER 1 +#define TECLA_MINOR_VER 4 +#define TECLA_MICRO_VER 1 + +/*....................................................................... + * Query the version number of the tecla library. + * + * Input: + * major int * The major version number of the library + * will be assigned to *major. This number is + * only incremented when a change to the library is + * made that breaks binary (shared library) and/or + * compilation backwards compatibility. + * minor int * The minor version number of the library + * will be assigned to *minor. This number is + * incremented whenever new functions are added to + * the public API. + * micro int * The micro version number of the library will be + * assigned to *micro. This number is incremented + * whenever internal changes are made that don't + * change the public API, such as bug fixes and + * performance enhancements. + */ +void libtecla_version(int *major, int *minor, int *micro); + +/*----------------------------------------------------------------------- + * The getline module provides interactive command-line input, recall + * and editing by users at terminals. See the gl_getline(3) man page for + * more details. + *-----------------------------------------------------------------------*/ + +/* + * Provide an opaque handle for the resource object that is defined in + * getline.h. + */ +typedef struct GetLine GetLine; + +/* + * The following two functions are used to create and delete the + * resource objects that are used by the gl_getline() function. + */ +GetLine *new_GetLine(size_t linelen, size_t histlen); +GetLine *del_GetLine(GetLine *gl); + +/* + * Read a line into an internal buffer of gl. + */ +char *gl_get_line(GetLine *gl, const char *prompt, const char *start_line, + int start_pos); + +/* + * Configure the application specific and/or user-specific behavior of + * gl_get_line(). + */ +int gl_configure_getline(GetLine *gl, const char *app_string, + const char *app_file, const char *user_file); + +/*----------------------------------------------------------------------- + * The file-expansion module provides facilities for expanding ~user/ and + * $envvar expressions, and for expanding glob-style wildcards. + * See the ef_expand_file(3) man page for more details. + *-----------------------------------------------------------------------*/ + +/* + * ExpandFile objects contain the resources needed to expand pathnames. + */ +typedef struct ExpandFile ExpandFile; + +/* + * The following functions are used to create and delete the resource + * objects that are used by the ef_expand_file() function. + */ +ExpandFile *new_ExpandFile(void); +ExpandFile *del_ExpandFile(ExpandFile *ef); + +/* + * A container of the following type is returned by ef_expand_file(). + */ +typedef struct { + int exists; /* True if the files in files[] currently exist. */ + /* This only time that this may not be true is if */ + /* the input filename didn't contain any wildcards */ + /* and thus wasn't matched against existing files. */ + /* In this case the single entry in 'nfile' may not */ + /* refer to an existing file. */ + int nfile; /* The number of files in files[] */ + char **files; /* An array of 'nfile' filenames. */ +} FileExpansion; + +/* + * The ef_expand_file() function expands a specified pathname, converting + * ~user/ and ~/ patterns at the start of the pathname to the + * corresponding home directories, replacing $envvar with the value of + * the corresponding environment variable, and then, if there are any + * wildcards, matching these against existing filenames. + * + * If no errors occur, a container is returned containing the array of + * files that resulted from the expansion. If there were no wildcards + * in the input pathname, this will contain just the original pathname + * after expansion of ~ and $ expressions. If there were any wildcards, + * then the array will contain the files that matched them. Note that + * if there were any wildcards but no existing files match them, this + * is counted as an error and NULL is returned. + * + * The supported wildcards and their meanings are: + * * - Match any sequence of zero or more characters. + * ? - Match any single character. + * [chars] - Match any single character that appears in 'chars'. + * If 'chars' contains an expression of the form a-b, + * then any character between a and b, including a and b, + * matches. The '-' character looses its special meaning + * as a range specifier when it appears at the start + * of the sequence of characters. + * [^chars] - The same as [chars] except that it matches any single + * character that doesn't appear in 'chars'. + * + * Wildcard expressions are applied to individual filename components. + * They don't match across directory separators. A '.' character at + * the beginning of a filename component must also be matched + * explicitly by a '.' character in the input pathname, since these + * are UNIX's hidden files. + * + * Input: + * fe ExpandFile * The pathname expansion resource object. + * path const char * The path name to be expanded. + * pathlen int The length of the suffix of path[] that + * constitutes the filename to be expanded, + * or -1 to specify that the whole of the + * path string should be used. + * Output: + * return FileExpansion * A pointer to a results container within the + * given ExpandFile object. This contains an + * array of the pathnames that resulted from + * expanding ~ and $ expressions and from + * matching any wildcards, sorted into lexical + * order. + * + * This container and its contents will be + * recycled on subsequent calls, so if you need + * to keep the results of two successive runs, + * you will either have to allocate a private + * copy of the array, or use two ExpandFile + * objects. + * + * On error, NULL is returned. A description + * of the error can be acquired by calling the + * ef_last_error() function. + */ +FileExpansion *ef_expand_file(ExpandFile *ef, const char *path, int pathlen); + +/*....................................................................... + * Print out an array of matching files. + * + * Input: + * result FileExpansion * The container of the sorted array of + * expansions. + * fp FILE * The output stream to write to. + * term_width int The width of the terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int ef_list_expansions(FileExpansion *result, FILE *fp, int term_width); + +/* + * The ef_last_error() function returns a description of the last error + * that occurred in a call ef_expand_file(). Note that this message is + * contained in an array which is allocated as part of *ef, and its + * contents thus potentially change on every call to ef_expand_file(). + */ +const char *ef_last_error(ExpandFile *ef); + +/*----------------------------------------------------------------------- + * The WordCompletion module is used for completing incomplete words, such + * as filenames. Programs can use functions within this module to register + * their own customized completion functions. + *-----------------------------------------------------------------------*/ + +/* + * Ambiguous completion matches are recorded in objects of the + * following type. + */ +typedef struct WordCompletion WordCompletion; + +/* + * Create a new completion object. + */ +WordCompletion *new_WordCompletion(void); + +/* + * Delete a redundant completion object. + */ +WordCompletion *del_WordCompletion(WordCompletion *cpl); + +/*....................................................................... + * Callback functions declared and prototyped using the following macro + * are called upon to return an array of possible completion suffixes + * for the token that precedes a specified location in the given + * input line. It is up to this function to figure out where the token + * starts, and to call cpl_add_completion() to register each possible + * completion before returning. + * + * Input: + * cpl WordCompletion * An opaque pointer to the object that will + * contain the matches. This should be filled + * via zero or more calls to cpl_add_completion(). + * data void * The anonymous 'data' argument that was + * passed to cpl_complete_word() or + * gl_customize_completion()). + * line const char * The current input line. + * word_end int The index of the character in line[] which + * follows the end of the token that is being + * completed. + * Output + * return int 0 - OK. + * 1 - Error. + */ +#define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, void *data, \ + const char *line, int word_end) +typedef CPL_MATCH_FN(CplMatchFn); + +/*....................................................................... + * Optional callback functions declared and prototyped using the + * following macro are called upon to return non-zero if a given + * file, specified by its pathname, is to be included in a list of + * completions. + * + * Input: + * data void * The application specified pointer which + * was specified when this callback function + * was registered. This can be used to have + * anything you like passed to your callback. + * pathname const char * The pathname of the file to be checked to + * see if it should be included in the list + * of completions. + * Output + * return int 0 - Ignore this file. + * 1 - Do include this file in the list + * of completions. + */ +#define CPL_CHECK_FN(fn) int (fn)(void *data, const char *pathname) +typedef CPL_CHECK_FN(CplCheckFn); + +/* + * You can use the following CplCheckFn callback function to only + * have executables included in a list of completions. + */ +CPL_CHECK_FN(cpl_check_exe); + +/* + * cpl_file_completions() is the builtin filename completion callback + * function. This can also be called by your own custom CPL_MATCH_FN() + * callback functions. To do this pass on all of the arguments of your + * custom callback function to cpl_file_completions(), with the exception + * of the (void *data) argument. The data argument should either be passed + * NULL to request the default behaviour of the file-completion function, + * or be passed a pointer to a CplFileConf structure (see below). In the + * latter case the contents of the structure modify the behavior of the + * file-completer. + */ +CPL_MATCH_FN(cpl_file_completions); + +/* + * Objects of the following type can be used to change the default + * behavior of the cpl_file_completions() callback function. + */ +typedef struct CplFileConf CplFileConf; + +/* + * If you want to change the behavior of the cpl_file_completions() + * callback function, call the following function to allocate a + * configuration object, then call one or more of the subsequent + * functions to change any of the default configuration parameters + * that you don't want. This function returns NULL when there is + * insufficient memory. + */ +CplFileConf *new_CplFileConf(void); + +/* + * If backslashes in the prefix being passed to cpl_file_completions() + * should be treated as literal characters, call the following function + * with literal=1. Otherwise the default is to treat them as escape + * characters which remove the special meanings of spaces etc.. + */ +void cfc_literal_escapes(CplFileConf *cfc, int literal); + +/* + * Before calling cpl_file_completions(), call this function if you + * know the index at which the filename prefix starts in the input line. + * Otherwise by default, or if you specify start_index to be -1, the + * filename is taken to start after the first unescaped space preceding + * the cursor, or the start of the line, which ever comes first. + */ +void cfc_file_start(CplFileConf *cfc, int start_index); + +/* + * If you only want certain types of files to be included in the + * list of completions, use the following function to specify a + * callback function which will be called to ask whether a given file + * should be included. The chk_data argument is will be passed to the + * callback function whenever it is called and can be anything you want. + */ +void cfc_set_check_fn(CplFileConf *cfc, CplCheckFn *chk_fn, void *chk_data); + +/* + * The following function deletes a CplFileConf objects previously + * returned by new_CplFileConf(). It always returns NULL. + */ +CplFileConf *del_CplFileConf(CplFileConf *cfc); + +/* + * The following configuration structure is deprecated. Do not change + * its contents, since this will break any programs that still use it, + * and don't use it in new programs. Instead use opaque CplFileConf + * objects as described above. cpl_file_completions() figures out + * what type of structure you pass it, by virtue of a magic int code + * placed at the start of CplFileConf object by new_CplFileConf(). + */ +typedef struct { + int escaped; /* Opposite to the argument of cfc_literal_escapes() */ + int file_start; /* Equivalent to the argument of cfc_file_start() */ +} CplFileArgs; +/* + * This initializes the deprecated CplFileArgs structures. + */ +void cpl_init_FileArgs(CplFileArgs *cfa); + +/*....................................................................... + * When an error occurs while performing a completion, custom completion + * callback functions should register a terse description of the error + * by calling cpl_record_error(). This message will then be returned on + * the next call to cpl_last_error() and used by getline to display an + * error message to the user. + * + * Input: + * cpl WordCompletion * The string-completion resource object that was + * originally passed to the callback. + * errmsg const char * The description of the error. + */ +void cpl_record_error(WordCompletion *cpl, const char *errmsg); + +/*....................................................................... + * This function can be used to replace the builtin filename-completion + * function with one of the user's choice. The user's completion function + * has the option of calling the builtin filename-completion function + * if it believes that the token that it has been presented with is a + * filename (see cpl_file_completions() above). + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * data void * This is passed to match_fn() whenever it is + * called. It could, for example, point to a + * symbol table that match_fn() would look up + * matches in. + * match_fn CplMatchFn * The function that will identify the prefix + * to be completed from the input line, and + * report matching symbols. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_customize_completion(GetLine *gl, void *data, CplMatchFn *match_fn); + +/*....................................................................... + * Change the terminal (or stream) that getline interacts with. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * input_fp FILE * The stdio stream to read from. + * output_fp FILE * The stdio stream to write to. + * term const char * The terminal type. This can be NULL if + * either or both of input_fp and output_fp don't + * refer to a terminal. Otherwise it should refer + * to an entry in the terminal information database. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp, + const char *term); + +/*....................................................................... + * The following functions can be used to save and restore the contents + * of the history buffer. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * filename const char * The name of the new file to write to. + * comment const char * Extra information such as timestamps will + * be recorded on a line started with this + * string, the idea being that the file can + * double as a command file. Specify "" if + * you don't care. Be sure to specify the + * same string to both functions. + * max_lines int The maximum number of lines to save, or -1 + * to save all of the lines in the history + * list. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_save_history(GetLine *gl, const char *filename, const char *comment, + int max_lines); +int gl_load_history(GetLine *gl, const char *filename, const char *comment); + +/* + * Enumerate file-descriptor events that can be waited for. + */ +typedef enum { + GLFD_READ, /* Watch for data waiting to be read from a file descriptor */ + GLFD_WRITE, /* Watch for ability to write to a file descriptor */ + GLFD_URGENT /* Watch for urgent out-of-band data on the file descriptor */ +} GlFdEvent; + +/* + * The following enumeration is used for the return status of file + * descriptor event callbacks. + */ +typedef enum { + GLFD_ABORT, /* Cause gl_get_line() to abort with an error */ + GLFD_REFRESH, /* Redraw the input line and continue waiting for input */ + GLFD_CONTINUE /* Continue to wait for input, without redrawing the line */ +} GlFdStatus; + +/*....................................................................... + * While gl_get_line() is waiting for terminal input, it can also be + * asked to listen for activity on arbitrary file descriptors. + * Callback functions of the following type can be registered to be + * called when activity is seen. If your callback needs to write to + * the terminal or use signals, please see the gl_get_line(3) man + * page. + * + * Input: + * gl GetLine * The gl_get_line() resource object. You can use + * this safely to call gl_watch_fd() or + * gl_watch_time(). The effect of calling other + * functions that take a gl argument is undefined, + * and must be avoided. + * data void * A pointer to arbitrary callback data, as originally + * registered with gl_watch_fd(). + * fd int The file descriptor that has activity. + * event GlFdEvent The activity seen on the file descriptor. The + * inclusion of this argument allows the same + * callback to be registered for multiple events. + * Output: + * return GlFdStatus GLFD_ABORT - Cause gl_get_line() to abort with + * an error (set errno if you need it). + * GLFD_REFRESH - Redraw the input line and continue + * waiting for input. Use this if you + * wrote something to the terminal. + * GLFD_CONTINUE - Continue to wait for input, without + * redrawing the line. + */ +#define GL_FD_EVENT_FN(fn) GlFdStatus (fn)(GetLine *gl, void *data, int fd, \ + GlFdEvent event) +typedef GL_FD_EVENT_FN(GlFdEventFn); + +/*....................................................................... + * Where possible, register a function and associated data to be called + * whenever a specified event is seen on a file descriptor. + * + * Input: + * gl GetLine * The resource object of the command-line input + * module. + * fd int The file descriptor to watch. + * event GlFdEvent The type of activity to watch for. + * callback GlFdEventFn * The function to call when the specified + * event occurs. Setting this to 0 removes + * any existing callback. + * data void * A pointer to arbitrary data to pass to the + * callback function. + * Output: + * return int 0 - OK. + * 1 - Either gl==NULL, or this facility isn't + * available on the the host system + * (ie. select() isn't available). No + * error message is generated in the latter + * case. + */ +int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); + +/*....................................................................... + * Switch history streams. History streams represent separate history + * lists recorded within a single history buffer. Different streams + * are distinguished by integer identifiers chosen by the calling + * appplicaton. Initially new_GetLine() sets the stream identifier to + * 0. Whenever a new line is appended to the history list, the current + * stream identifier is recorded with it, and history lookups only + * consider lines marked with the current stream identifier. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * id unsigned The new history stream identifier. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_group_history(GetLine *gl, unsigned id); + +/*....................................................................... + * Display the contents of the history list. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * fp FILE * The stdio output stream to write to. + * fmt const char * A format string. This containing characters to be + * written verbatim, plus any of the following + * format directives: + * %D - The date, formatted like 2001-11-20 + * %T - The time of day, formatted like 23:59:59 + * %N - The sequential entry number of the + * line in the history buffer. + * %G - The number of the history group that + * the line belongs to. + * %% - A literal % character. + * %H - The history line itself. + * Note that a '\n' newline character is not + * appended by default. + * all_groups int If true, display history lines from all + * history groups. Otherwise only display + * those of the current history group. + * max_lines int If max_lines is < 0, all available lines + * are displayed. Otherwise only the most + * recent max_lines lines will be displayed. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_show_history(GetLine *gl, FILE *fp, const char *fmt, int all_groups, + int max_lines); + +/*....................................................................... + * Resize or delete the history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * bufsize size_t The number of bytes in the history buffer, or 0 + * to delete the buffer completely. + * Output: + * return int 0 - OK. + * 1 - Insufficient memory (the previous buffer + * will have been retained). No error message + * will be displayed. + */ +int gl_resize_history(GetLine *gl, size_t bufsize); + +/*....................................................................... + * Set an upper limit to the number of lines that can be recorded in the + * history list, or remove a previously specified limit. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * max_lines int The maximum number of lines to allow, or -1 to + * cancel a previous limit and allow as many lines + * as will fit in the current history buffer size. + */ +void gl_limit_history(GetLine *gl, int max_lines); + +/*....................................................................... + * Discard either all historical lines, or just those associated with the + * current history group. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * all_groups int If true, clear all of the history. If false, + * clear only the stored lines associated with the + * currently selected history group. + */ +void gl_clear_history(GetLine *gl, int all_groups); + +/*....................................................................... + * Temporarily enable or disable the gl_get_line() history mechanism. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * enable int If true, turn on the history mechanism. If + * false, disable it. + */ +void gl_toggle_history(GetLine *gl, int enable); + +/* + * Objects of the following type are returned by gl_terminal_size(). + */ +typedef struct { + int nline; /* The terminal has nline lines */ + int ncolumn; /* The terminal has ncolumn columns */ +} GlTerminalSize; + +/*....................................................................... + * Update if necessary, and return the current size of the terminal. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * def_ncolumn int If the number of columns in the terminal + * can't be determined, substitute this number. + * def_nline int If the number of lines in the terminal can't + * be determined, substitute this number. + * Output: + * return GlTerminalSize The current terminal size. + */ +GlTerminalSize gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline); + +/* + * The gl_lookup_history() function returns information in an + * argument of the following type. + */ +typedef struct { + const char *line; /* The requested history line */ + unsigned group; /* The history group to which the */ + /* line belongs. */ + time_t timestamp; /* The date and time at which the */ + /* line was originally entered. */ +} GlHistoryLine; + +/*....................................................................... + * Lookup a history line by its sequential number of entry in the + * history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * id unsigned long The identification number of the line to + * be returned, where 0 denotes the first line + * that was entered in the history list, and + * each subsequently added line has a number + * one greater than the previous one. For + * the range of lines currently in the list, + * see the gl_range_of_history() function. + * Input/Output: + * line GlHistoryLine * A pointer to the variable in which to + * return the details of the line. + * Output: + * return int 0 - The line is no longer in the history + * list, and *line has not been changed. + * 1 - The requested line can be found in + * *line. Note that the string in + * line->line is part of the history + * buffer and will change, so a private + * copy should be made if you wish to + * use it after subsequent calls to any + * functions that take gl as an argument. + */ +int gl_lookup_history(GetLine *gl, unsigned long id, GlHistoryLine *line); + +/* + * The gl_state_of_history() function returns information in an argument + * of the following type. + */ +typedef struct { + int enabled; /* True if history is enabled */ + unsigned group; /* The current history group */ + int max_lines; /* The current upper limit on the number of lines */ + /* in the history list, or -1 if unlimited. */ +} GlHistoryState; + +/*....................................................................... + * Query the state of the history list. Note that any of the input/output + * pointers can be specified as NULL. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Input/Output: + * state GlHistoryState * A pointer to the variable in which to record + * the return values. + */ +void gl_state_of_history(GetLine *gl, GlHistoryState *state); + +/* + * The gl_range_of_history() function returns information in an argument + * of the following type. + */ +typedef struct { + unsigned long oldest; /* The sequential entry number of the oldest */ + /* line in the history list. */ + unsigned long newest; /* The sequential entry number of the newest */ + /* line in the history list. */ + int nlines; /* The number of lines in the history list */ +} GlHistoryRange; + +/*....................................................................... + * Query the number and range of lines in the history buffer. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * range GlHistoryRange * A pointer to the variable in which to record + * the return values. If range->nline=0, the + * range of lines will be given as 0-0. + */ +void gl_range_of_history(GetLine *gl, GlHistoryRange *range); + +/* + * The gl_size_of_history() function returns information in an argument + * of the following type. + */ +typedef struct { + size_t size; /* The size of the history buffer (bytes) */ + size_t used; /* The number of bytes of the history buffer */ + /* that are currently occupied. */ +} GlHistorySize; + +/*....................................................................... + * Return the size of the history buffer and the amount of the + * buffer that is currently in use. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Input/Output: + * GlHistorySize size * A pointer to the variable in which to return + * the results. + */ +void gl_size_of_history(GetLine *gl, GlHistorySize *size); + +/*....................................................................... + * Specify whether text that users type should be displayed or hidden. + * In the latter case, only the prompt is displayed, and the final + * input line is not archived in the history list. + * + * Input: + * gl GetLine * The input-line history maintenance object. + * enable int 0 - Disable echoing. + * 1 - Enable echoing. + * -1 - Just query the mode without changing it. + * Output: + * return int The echoing disposition that was in effect + * before this function was called: + * 0 - Echoing was disabled. + * 1 - Echoing was enabled. + */ +int gl_echo_mode(GetLine *gl, int enable); + +/*....................................................................... + * This function can be called from gl_get_line() callbacks to have + * the prompt changed when they return. It has no effect if gl_get_line() + * is not currently being invoked. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * prompt const char * The new prompt. + */ +void gl_replace_prompt(GetLine *gl, const char *prompt); + +/* + * Enumerate the available prompt formatting styles. + */ +typedef enum { + GL_LITERAL_PROMPT, /* Display the prompt string literally */ + GL_FORMAT_PROMPT /* The prompt string can contain any of the */ + /* following formatting directives: */ + /* %B - Display subsequent characters */ + /* with a bold font. */ + /* %b - Stop displaying characters */ + /* with the bold font. */ + /* %U - Underline subsequent characters. */ + /* %u - Stop underlining characters. */ + /* %S - Highlight subsequent characters */ + /* (also known as standout mode). */ + /* %s - Stop highlighting characters */ + /* %% - Display a single % character. */ +} GlPromptStyle; + +/*....................................................................... + * Specify whether to heed text attribute directives within prompt + * strings. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * style GlPromptStyle The style of prompt (see the definition of + * GlPromptStyle in libtecla.h for details). + */ +void gl_prompt_style(GetLine *gl, GlPromptStyle style); + +/*....................................................................... + * Remove a signal from the list of signals that gl_get_line() traps. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * signo int The number of the signal to be ignored. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int gl_ignore_signal(GetLine *gl, int signo); + +/* + * A bitwise union of the following enumerators is passed to + * gl_trap_signal() to specify the environment in which the + * application's signal handler is to be called. + */ +typedef enum { + GLS_RESTORE_SIG=1, /* Restore the caller's signal environment */ + /* while handling the signal. */ + GLS_RESTORE_TTY=2, /* Restore the caller's terminal settings */ + /* while handling the signal. */ + GLS_RESTORE_LINE=4, /* Move the cursor to the start of the next line */ + GLS_REDRAW_LINE=8, /* Redraw the input line when the signal handler */ + /* returns. */ + GLS_UNBLOCK_SIG=16, /* Normally a signal who's delivery is found to */ + /* be blocked by the calling application is not */ + /* trapped by gl_get_line(). Including this flag */ + /* causes it to be temporarily unblocked and */ + /* trapped while gl_get_line() is executing. */ + GLS_DONT_FORWARD=32,/* Don't forward the signal to the signal handler */ + /* of the calling program. */ + GLS_RESTORE_ENV = GLS_RESTORE_SIG | GLS_RESTORE_TTY | GLS_REDRAW_LINE, + GLS_SUSPEND_INPUT = GLS_RESTORE_ENV | GLS_RESTORE_LINE +} GlSignalFlags; + +/* + * The following enumerators are passed to gl_trap_signal() to tell + * it what to do after the application's signal handler has been called. + */ +typedef enum { + GLS_RETURN, /* Return the line as though the user had pressed the */ + /* return key. */ + GLS_ABORT, /* Cause gl_get_line() to return NULL */ + GLS_CONTINUE /* After handling the signal, resume command line editing */ +} GlAfterSignal; + +/*....................................................................... + * Tell gl_get_line() how to respond to a given signal. This can be used + * both to override the default responses to signals that gl_get_line() + * normally catches and to add new signals to the list that are to be + * caught. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * signo int The number of the signal to be caught. + * flags unsigned A bitwise union of GlSignalFlags enumerators. + * after GlAfterSignal What to do after the application's signal + * handler has been called. + * errno_value int The value to set errno to. + * Output: + * return int 0 - OK. + * 1 - Insufficient memory to record the + * new signal disposition. + */ +int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); + +/*....................................................................... + * Return the last signal that was caught by the most recent call to + * gl_get_line(), or -1 if no signals were caught. This is useful if + * gl_get_line() returns errno=EINTR and you need to find out what signal + * caused it to abort. + * + * Input: + * gl GetLine * The resource object of gl_get_line(). + * Output: + * return int The last signal caught by the most recent + * call to gl_get_line(), or -1 if no signals + * were caught. + */ +int gl_last_signal(const GetLine *gl); + +/*....................................................................... + * This function is designed to be called by CPL_MATCH_FN() callback + * functions. It adds one possible completion of the token that is being + * completed to an array of completions. If the completion needs any + * special quoting to be valid when displayed in the input line, this + * quoting must be included in the string. + * + * Input: + * cpl WordCompletion * The argument of the same name that was passed + * to the calling CPL_MATCH_FN() callback function. + * line const char * The input line, as received by the callback + * function. + * word_start int The index within line[] of the start of the + * word that is being completed. If an empty + * string is being completed, set this to be + * the same as word_end. + * word_end int The index within line[] of the character which + * follows the incomplete word, as received by the + * callback function. + * suffix const char * The appropriately quoted string that could + * be appended to the incomplete token to complete + * it. A copy of this string will be allocated + * internally. + * type_suffix const char * When listing multiple completions, gl_get_line() + * appends this string to the completion to indicate + * its type to the user. If not pertinent pass "". + * Otherwise pass a literal or static string. + * cont_suffix const char * If this turns out to be the only completion, + * gl_get_line() will append this string as + * a continuation. For example, the builtin + * file-completion callback registers a directory + * separator here for directory matches, and a + * space otherwise. If the match were a function + * name you might want to append an open + * parenthesis, etc.. If not relevant pass "". + * Otherwise pass a literal or static string. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int cpl_add_completion(WordCompletion *cpl, const char *line, + int word_start, int word_end, const char *suffix, + const char *type_suffix, const char *cont_suffix); + +/* + * Each possible completion string is recorded in an array element of + * the following type. + */ +typedef struct { + char *completion; /* The matching completion string */ + char *suffix; /* The pointer into completion[] at which the */ + /* string was extended. */ + const char *type_suffix; /* A suffix to be added when listing completions */ + /* to indicate the type of the completion. */ +} CplMatch; + +/* + * Completions are returned in a container of the following form. + */ +typedef struct { + char *suffix; /* The common initial part of all of the */ + /* completion suffixes. */ + const char *cont_suffix; /* Optional continuation string to be appended to */ + /* the sole completion when nmatch==1. */ + CplMatch *matches; /* The array of possible completion strings, */ + /* sorted into lexical order. */ + int nmatch; /* The number of elements in matches[] */ +} CplMatches; + +/*....................................................................... + * Given an input line and the point at which completion is to be + * attempted, return an array of possible completions. + * + * Input: + * cpl WordCompletion * The word-completion resource object. + * line const char * The current input line. + * word_end int The index of the character in line[] which + * follows the end of the token that is being + * completed. + * data void * Anonymous 'data' to be passed to match_fn(). + * match_fn CplMatchFn * The function that will identify the prefix + * to be completed from the input line, and + * record completion suffixes. + * Output: + * return CplMatches * The container of the array of possible + * completions. The returned pointer refers + * to a container owned by the parent Completion + * object, and its contents thus potentially + * change on every call to cpl_matches(). + */ +CplMatches *cpl_complete_word(WordCompletion *cpl, const char *line, + int word_end, void *data, + CplMatchFn *match_fn); + +/*....................................................................... + * Print out an array of matching completions. + * + * Input: + * result CplMatches * The container of the sorted array of + * completions. + * fp FILE * The output stream to write to. + * term_width int The width of the terminal. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +int cpl_list_completions(CplMatches *result, FILE *fp, int term_width); + +/*....................................................................... + * Return a description of the error that occurred on the last call to + * cpl_complete_word() or cpl_add_completion(). + * + * Input: + * cpl WordCompletion * The string-completion resource object. + * Output: + * return const char * The description of the last error. + */ +const char *cpl_last_error(WordCompletion *cpl); + +/* + * PathCache objects encapsulate the resources needed to record + * files of interest from comma-separated lists of directories. + */ +typedef struct PathCache PathCache; + +/*....................................................................... + * Create an object who's function is to maintain a cache of filenames + * found within a list of directories, and provide quick lookup and + * completion of selected files in this cache. + * + * Output: + * return PathCache * The new, initially empty cache, or NULL + * on error. + */ +PathCache *new_PathCache(void); + +/*....................................................................... + * Delete a given cache of files, returning the resources that it + * was using to the system. + * + * Input: + * pc PathCache * The cache to be deleted (can be NULL). + * Output: + * return PathCache * The deleted object (ie. allways NULL). + */ +PathCache *del_PathCache(PathCache *pc); + +/*....................................................................... + * Return a description of the last path-caching error that occurred. + * + * Input: + * pc PathCache * The filename cache that suffered the error. + * Output: + * return char * The description of the last error. + */ +const char *pca_last_error(PathCache *pc); + +/*....................................................................... + * Build the list of files of interest contained in a given + * colon-separated list of directories. + * + * Input: + * pc PathCache * The cache in which to store the names of + * the files that are found in the list of + * directories. + * path const char * A colon-separated list of directory + * paths. Under UNIX, when searching for + * executables, this should be the return + * value of getenv("PATH"). + * Output: + * return int 0 - OK. + * 1 - An error occurred. + */ +int pca_scan_path(PathCache *pc, const char *path); + +/*....................................................................... + * If you want subsequent calls to pca_lookup_file() and + * pca_path_completions() to only return the filenames of certain + * types of files, for example executables, or filenames ending in + * ".ps", call this function to register a file-selection callback + * function. This callback function takes the full pathname of a file, + * plus application-specific data, and returns 1 if the file is of + * interest, and zero otherwise. + * + * Input: + * pc PathCache * The filename cache. + * check_fn CplCheckFn * The function to call to see if the name of + * a given file should be included in the + * cache. This determines what type of files + * will reside in the cache. To revert to + * selecting all files, regardless of type, + * pass 0 here. + * data void * You can pass a pointer to anything you + * like here, including NULL. It will be + * passed to your check_fn() callback + * function, for its private use. + */ +void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn, void *data); + +/*....................................................................... + * Given the simple name of a file, search the cached list of files + * in the order in which they where found in the list of directories + * previously presented to pca_scan_path(), and return the pathname + * of the first file which has this name. + * + * Input: + * pc PathCache * The cached list of files. + * name const char * The name of the file to lookup. + * name_len int The length of the filename substring at the + * beginning of name[], or -1 to assume that the + * filename occupies the whole of the string. + * literal int If this argument is zero, lone backslashes + * in name[] are ignored during comparison + * with filenames in the cache, under the + * assumption that they were in the input line + * soley to escape the special significance of + * characters like spaces. To have them treated + * as normal characters, give this argument a + * non-zero value, such as 1. + * Output: + * return char * The pathname of the first matching file, + * or NULL if not found. Note that the returned + * pointer points to memory owned by *pc, and + * will become invalid on the next call. + */ +char *pca_lookup_file(PathCache *pc, const char *name, int name_len, + int literal); + +/* + * Objects of the following type can be used to change the default + * behavior of the pca_path_completions() callback function. + */ +typedef struct PcaPathConf PcaPathConf; + +/* + * pca_path_completions() is a completion callback function for use directly + * with cpl_complete_word() or gl_customize_completions(), or indirectly + * from your own completion callback function. It requires that a PcaPathConf + * object be passed via its 'void *data' argument (see below). + */ +CPL_MATCH_FN(pca_path_completions); + +/*....................................................................... + * Allocate and initialize a pca_path_completions() configuration object. + * + * Input: + * pc PathCache * The filename cache in which to look for + * file name completions. + * Output: + * return PcaPathConf * The new configuration structure, or NULL + * on error. + */ +PcaPathConf *new_PcaPathConf(PathCache *pc); + +/*....................................................................... + * Deallocate memory, previously allocated by new_PcaPathConf(). + * + * Input: + * ppc PcaPathConf * Any pointer previously returned by + * new_PcaPathConf() [NULL is allowed]. + * Output: + * return PcaPathConf * The deleted structure (always NULL). + */ +PcaPathConf *del_PcaPathConf(PcaPathConf *ppc); + +/* + * If backslashes in the prefix being passed to pca_path_completions() + * should be treated as literal characters, call the following function + * with literal=1. Otherwise the default is to treat them as escape + * characters which remove the special meanings of spaces etc.. + */ +void ppc_literal_escapes(PcaPathConf *ppc, int literal); + +/* + * Before calling pca_path_completions, call this function if you know + * the index at which the filename prefix starts in the input line. + * Otherwise by default, or if you specify start_index to be -1, the + * filename is taken to start after the first unescaped space preceding + * the cursor, or the start of the line, whichever comes first. + */ +void ppc_file_start(PcaPathConf *ppc, int start_index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libtecla-1.4.1/libtecla.map b/libtecla-1.4.1/libtecla.map new file mode 100644 index 0000000..7e774b7 --- /dev/null +++ b/libtecla-1.4.1/libtecla.map @@ -0,0 +1,124 @@ +# This mapfile (or version script) lists the public symbols that are +# publically exported by each version of the tecla library. This file +# has the format required by the Sun and Linux linkers, and also acts +# as a template from which map files for other systems can be derived +# with awk or sed. +# +# Under Solaris and Linux, this map file is used by ld during shared +# library creation. It has two purposes: +# +# 1. It specifies which symbols in the library are to be made visible +# to applications. This has the dual benefits of reducing namespace +# polution, and of preventing applications from using private +# internal library functions that might change or disappear in +# future releases. +# +# 2. The information listed in this file is recorded in the shared +# library, such that when an application is linked against it, the +# linker can record a dependency in the application which says +# which is the earliest library version which included all of the +# symbols that the application needs. This means that if the +# application is copied to another system that has an earlier +# version of the library, the linker can quickly determine whether +# the earlier version contains all of the symbols that it needs. +# +# Under Linux, mapfiles can also be used to allow multiple +# incompatible versions of a given function to exist in a library, +# thus supporting applications that were compiled against different +# incompatible versions of the library. Since this feature (and the +# inclusion of .symver directives) isn't supported by Solaris, it +# can't be included in this file. Non backwards compatibility in the +# ABI must instead be handled in the more traditional way, by +# incrementing the major version number. +# +# When a new minor release is made, a new tecla_1.x specification +# should be added which inherits the symbols of the previous release +# and lists newly added functions. For example, below you will find +# the following clause: +# +# tecla_1.3 { +# global: +# ef_list_expansions; +# } tecla_1.2; +# +# This says that ef_list_expansions is the name of a public function +# that was added in the 1.3 release, and that the symbols defined in +# the previous tecla_1.2 clause have been inherited by tecla_1.3. +# +# For more details see the following URL: +# +# http://www.usenix.org/publications/library/proceedings/als2000/browndavid.html +#------------------------------------------------------------------------------- + +tecla_1.2 { + global: + cfc_file_start; + cfc_literal_escapes; + cfc_set_check_fn; + cpl_add_completion; + cpl_check_exe; + cpl_complete_word; + cpl_file_completions; + cpl_init_FileArgs; + cpl_last_error; + cpl_list_completions; + cpl_record_error; + del_CplFileConf; + del_ExpandFile; + del_GetLine; + del_PathCache; + del_PcaPathConf; + del_WordCompletion; + ef_expand_file; + ef_last_error; + gl_change_terminal; + gl_customize_completion; + gl_get_line; + new_CplFileConf; + new_ExpandFile; + new_GetLine; + new_PathCache; + new_PcaPathConf; + new_WordCompletion; + pca_last_error; + pca_lookup_file; + pca_path_completions; + pca_scan_path; + pca_set_check_fn; + ppc_file_start; + ppc_literal_escapes; + + local: + *; +}; + +tecla_1.3 { + global: + ef_list_expansions; +} tecla_1.2; + +tecla_1.4 { + global: + gl_configure_getline; + gl_save_history; + gl_load_history; + gl_group_history; + gl_show_history; + gl_resize_history; + gl_limit_history; + gl_clear_history; + gl_toggle_history; + gl_watch_fd; + libtecla_version; + gl_terminal_size; + gl_state_of_history; + gl_range_of_history; + gl_size_of_history; + gl_lookup_history; + gl_echo_mode; + gl_replace_prompt; + gl_prompt_style; + gl_ignore_signal; + gl_trap_signal; + gl_last_signal; +} tecla_1.3; diff --git a/libtecla-1.4.1/man3/cfc_file_start.3 b/libtecla-1.4.1/man3/cfc_file_start.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cfc_file_start.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cfc_literal_escapes.3 b/libtecla-1.4.1/man3/cfc_literal_escapes.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cfc_literal_escapes.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cfc_set_check_fn.3 b/libtecla-1.4.1/man3/cfc_set_check_fn.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cfc_set_check_fn.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cpl_add_completion.3 b/libtecla-1.4.1/man3/cpl_add_completion.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_add_completion.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cpl_complete_word.3 b/libtecla-1.4.1/man3/cpl_complete_word.3 new file mode 100644 index 0000000..ae76439 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_complete_word.3 @@ -0,0 +1,405 @@ +.\" Copyright (C) 2000, 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH cpl_complete_word 3 +.SH NAME +cpl_complete_word, cfc_file_start, cfc_literal_escapes, cfc_set_check_fn, cpl_add_completion, cpl_file_completions, cpl_last_error, cpl_list_completions, cpl_record_error, del_CplFileConf, del_WordCompletion, new_CplFileConf, new_WordCompletion \- lookup possible completions for a word +.SH SYNOPSIS +.nf +#include +#include + +WordCompletion *new_WordCompletion(void); + +WordCompletion *del_WordCompletion(WordCompletion *cpl); + +#define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \\ + void *data, \\ + const char *line, \\ + int word_end) +typedef CPL_MATCH_FN(CplMatchFn); + +CPL_MATCH_FN(cpl_file_completions); + +CplMatches *cpl_complete_word(WordCompletion *cpl, + const char *line, + int word_end, void *data, + CplMatchFn *match_fn); + +int cpl_list_completions(CplMatches *result, FILE *fp, + int term_width); + +int cpl_add_completion(WordCompletion *cpl, + const char *line, int word_start, + int word_end, const char *suffix, + const char *type_suffix, + const char *cont_suffix); + +void cpl_record_error(WordCompletion *cpl, + const char *errmsg); + +const char *cpl_last_error(WordCompletion *cpl); + +.fi + +.SH DESCRIPTION + +The \f3cpl_complete_word()\f1 function is part of the tecla library +(see the libtecla(3) man page). It is usually called behind the scenes +by \f3gl_get_line(3)\f1, but can also be called separately. + +Given an input line containing an incomplete word to be completed, it +calls a user-provided callback function (or the provided +file-completion callback function) to look up all possible completion +suffixes for that word. The callback function is expected to look +backward in the line, starting from the specified cursor position, to +find the start of the word to be completed, then to look up all +possible completions of that word and record them, one at a time by +calling \f3cpl_add_completion()\f1. + +.sp +Descriptions of the functions of this module are as follows: +.sp +.nf + CompleteWord *new_CompleteWord(void) +.fi +.sp +This function creates the resources used by the \f3cpl_complete_word()\f1 +function. In particular, it maintains the memory that is used to +return the results of calling \f3cpl_complete_word()\f1. +.sp +.nf + CompleteWord *del_CompleteWord(CompleteWord *cpl) +.fi +.sp +This function deletes the resources that were returned by a previous +call to \f3new_CompleteWord()\f1. It always returns \f3NULL\f1 (ie. a +deleted object). It does nothing if the \f3cpl\f1 argument is +\f3NULL\f1. +.sp +The callback functions which lookup possible completions should be +defined with the following macro (which is defined in libtecla.h). +.sp +.nf + #define CPL_MATCH_FN(fn) int (fn)(WordCompletion *cpl, \\ + void *data, \\ + const char *line, \\ + int word_end) +.fi +.sp +Functions of this type are called by \f3cpl_complete_word()\f1, and +all of the arguments of the callback are those that were passed to +said function. In particular, the \f3line\f1 argument contains the +input line containing the word to be completed, and \f3word_end\f1 is +the index of the character that follows the last character of the +incomplete word within this string. The callback is expected to look +backwards from \f3word_end\f1 for the start of the incomplete +word. What constitutes the start of a word clearly depends on the +application, so it makes sense for the callback to take on this +responsibility. For example, the builtin filename completion function +looks backwards until it hits an unescaped space, or the start of the +line. Having found the start of the word, the callback should then +lookup all possible completions of this word, and record each +completion via separate calls to \f3cpl_add_completion()\f1. If the +callback needs access to an application-specific symbol table, it can +pass it and any other data that it needs, via the \f3data\f1 +argument. This removes any need for globals. +.sp +The callback function should return 0 if no errors occur. On failure +it should return 1, and register a terse description of the error by +calling \f3cpl_record_error()\f1. +.sp +.nf + void cpl_record_error(WordCompletion *cpl, + const char *errmsg); +.fi +.sp +The last error message recorded by calling \f3cpl_record_error()\f1, +can subsequently be queried by calling \f3cpl_last_error()\f1, as +described later. +.sp +.nf + int cpl_add_completion(WordCompletion *cpl, + const char *line, int word_start, + int word_end, const char *suffix, + const char *type_suffix, + const char *cont_suffix); +.fi +.sp +The \f3cpl_add_completion()\f1 function is called zero or more times +by the completion callback function to record each possible completion +in the specified \f3WordCompletion\f1 object. These completions are +subsequently returned by \f3cpl_complete_word()\f1, as described +later. The \f3cpl\f1, \f3line\f1, and \f3word_end\f1 arguments should +be those that were passed to the callback function. The +\f3word_start\f1 argument should be the index within the input line +string of the start of the word that is being completed. This should +equal \f3word_end\f1 if a zero-length string is being completed. The +\f3suffix\f1 argument is the string that would have to be appended to +the incomplete word to complete it. If this needs any quoting +(eg. the addition of backslashes before special charaters) to be valid +within the displayed input line, this should be included. A copy of +the suffix string is allocated internally, so there is no need to +maintain your copy of the string after \f3cpl_add_completion()\f1 +returns. +.sp +Note that in the array of possible completions which the +\f3cpl_complete_word()\f1 function returns, the suffix recorded by +\f3cpl_add_completion()\f1 is listed along with the concatentation of +this suffix with the word that lies between \f3word_start\f1 and +\f3word_end\f1 in the input line. +.sp +The \f3type_suffix\f1 argument specifies an optional string to be +appended to the completion if it is displayed as part of a list of +completions by \f3cpl_list_completions()\f1. The intention is that +this indicate to the user the type of each completion. For example, +the file completion function places a directory separator after +completions that are directories, to indicate their nature to the +user. Similary, if the completion were a function, you could indicate +this to the user by setting \f3type_suffix\f1 to "()". Note that the +\f3type_suffix\f1 string isn't copied, so if the argument isn't a +literal string between speech marks, be sure that the string remains +valid for at least as long as the results of \f3cpl_complete_word()\f1 +are needed. +.sp +The \f3cont_suffix\f1 is a continuation suffix to append to the +completed word in the input line if this is the only completion. This +is something that isn't part of the completion itself, but that gives +the user an indication about how they might continue to extend the +token. For example, the file-completion callback function adds a +directory separator if the completed word is a directory. If the +completed word were a function name, you could similarly aid the user +by arranging for an open parenthesis to be appended. +.sp +.nf + CplMatches *cpl_complete_word(WordCompletion *cpl, + const char *line, + int word_end, void *data, + CplMatchFn *match_fn); +.fi +.sp +The \f3cpl_complete_word()\f1 is normally called behind the scenes by +\f3gl_get_line(3)\f1, but can also be called separately if you +separately allocate a \f3WordCompletion\f1 object. It performs word +completion, as described at the beginning of this section. Its first +argument is a resource object previously returned by +\f3new_CompleteWord()\f1. The \f3line\f1 argument is the input line +string, containing the word to be completed. The \f3word_end\f1 +argument contains the index of the character in the input line, that +just follows the last character of the word to be completed. When +called by \f3gl_get_line()\f1, this is the character over which the +user pressed \f3TAB\f1. The \f3match_fn\f3 argument is the function +pointer of the callback function which will lookup possible +completions of the word, as described above, and the \f3data\f1 +argument provides a way for the application to pass arbitrary data to +the callback function. +.sp +If no errors occur, the \f3cpl_complete_word()\f1 function returns a +pointer to a \f3CplMatches\f1 container, as defined below. This +container is allocated as part of the \f3cpl\f1 object that was passed +to \f3cpl_complete_word()\f1, and will thus change on each call which +uses the same \f3cpl\f1 argument. +.sp +.nf + typedef struct { + char *completion; /* A matching completion */ + /* string */ + char *suffix; /* The part of the */ + /* completion string which */ + /* would have to be */ + /* appended to complete the */ + /* original word. */ + const char *type_suffix; /* A suffix to be added when */ + /* listing completions, to */ + /* indicate the type of the */ + /* completion. */ + } CplMatch; + + typedef struct { + char *suffix; /* The common initial part */ + /* of all of the completion */ + /* suffixes. */ + const char *cont_suffix; /* Optional continuation */ + /* string to be appended to */ + /* the sole completion when */ + /* nmatch==1. */ + CplMatch *matches; /* The array of possible */ + /* completion strings, */ + /* sorted into lexical */ + /* order. */ + int nmatch; /* The number of elements in */ + /* the above matches[] */ + /* array. */ + } CplMatches; +.fi +.sp +If an error occurs during completion, \f3cpl_complete_word()\f1 +returns NULL. A description of the error can be acquired by calling +the \f3cpl_last_error()\f3 function. +.sp +.nf + const char *cpl_last_error(WordCompletion *cpl); +.fi +.sp +The \f3cpl_last_error()\f3 function returns a terse description of the +error which occurred on the last call to \f3cpl_complete_word()\f1 or +\f3cpl_add_completion()\f1. +.sp +.nf + int cpl_list_completions(CplMatches *result, FILE *fp, + int terminal_width); +.fi +.sp +When the \f3cpl_complete_word()\f1 function returns multiple possible +completions, the \f3cpl_list_completions()\f1 function can be called +upon to list them, suitably arranged across the available width of the +terminal. It arranges for the displayed columns of completions to all +have the same width, set by the longest completion. It also appends +the \f3type_suffix\f1 strings that were recorded with each completion, +thus indicating their types to the user. + +.SH THE BUILT-IN FILENAME-COMPLETION CALLBACK + +By default the \f3gl_get_line(3)\f1 function, passes the following +completion callback function to \f3cpl_complete_word()\f1. This +function can also be used separately, either by sending it to +\f3cpl_complete_word()\f1, or by calling it directly from your +own completion callback function. +.sp +.nf + CPL_MATCH_FN(cpl_file_completions); +.fi +.sp +Certain aspects of the behavior of this callback can be changed via +its \f3data\f1 argument. If you are happy with its default behavior +you can pass \f3NULL\f1 in this argument. Otherwise it should be a +pointer to a \f3CplFileConf\f1 object, previously allocated by calling +\f3new_CplFileConf()\f1. +.sp +.nf + CplFileConf *new_CplFileConf(void); +.fi +.sp +\f3CplFileConf\f1 objects encapsulate the configuration parameters of +\f3cpl_file_completions()\f1. These parameters, which start out with +default values, can be changed by calling the accessor functions +described below. +.sp +By default, the \f3cpl_file_completions()\f3 callback function +searches backwards for the start of the filename being completed, +looking for the first un-escaped space or the start of the input +line. If you wish to specify a different location, call +\f3cfc_file_start()\f1 with the index at which the filename starts in +the input line. Passing start_index=-1 re-enables the default +behavior. +.sp +.nf + void cfc_file_start(CplFileConf *cfc, int start_index); +.fi +.sp +By default, when \f3cpl_file_completions()\f1 looks at a filename in +the input line, each lone backslash in the input line is interpreted +as being a special character which removes any special significance of +the character which follows it, such as a space which should be taken +as part of the filename rather than delimiting the start of the +filename. These backslashes are thus ignored while looking for +completions, and subsequently added before spaces, tabs and literal +backslashes in the list of completions. To have unescaped backslashes +treated as normal characters, call \f3cfc_literal_escapes()\f1 with a +non-zero value in its \f3literal\f1 argument. +.sp +.nf + void cfc_literal_escapes(CplFileConf *cfc, int literal); +.fi +.sp +By default, \f3cpl_file_completions()\f1 reports all files who's names +start with the prefix that is being completed. If you only want a +selected subset of these files to be reported in the list of +completions, you can arrange this by providing a callback function +which takes the full pathname of a file, and returns \f30\f1 if the +file should be ignored, or \f31\f1 if the file should be included in +the list of completions. To register such a function for use by +\f3cpl_file_completions()\f1, call \f3cfc_set_check_fn()\f1, and pass +it a pointer to the function, together with a pointer to any data that +you would like passed to this callback whenever it is called. Your +callback can make its decisions based on any property of the file, +such as the filename itself, whether the file is readable, writable or +executable, or even based on what the file contains. +.sp +.nf + #define CPL_CHECK_FN(fn) int (fn)(void *data, \\ + const char *pathname) + typedef CPL_CHECK_FN(CplCheckFn); + + void cfc_set_check_fn(CplFileConf *cfc, + CplCheckFn *chk_fn, void *chk_data); +.fi +.sp +The \f3cpl_check_exe()\f1 function is a provided callback of the above +type, for use with \f3cpl_file_completions()\f1. It returns non-zero +if the filename that it is given represents a normal file that the +user has execute permission to. You could use this to have +\f3cpl_file_completions()\f1 only list completions of executable +files. +.sp +When you have finished with a \f3CplFileConf\f1 variable, you can pass +it to the \f3del_CplFileConf()\f1 destructor function to reclaim its +memory. +.sp +.nf + CplFileConf *del_CplFileConf(CplFileConf *cfc); +.fi +.sp + +.SH THREAD SAFETY + +In multi-threaded programs, you should use the \f3libtecla_r.a\f1 +version of the library. This uses POSIX reentrant functions where +available (hence the \f3_r\f1 suffix), and disables features that rely +on non-reentrant system functions. In the case of this module, the +only disabled feature is username completion in \f3~username/\f1 +expressions, in \f3cpl_file_completions()\f1. + +Using the \f3libtecla_r.a\f1 version of the library, it is safe to use +the facilities of this module in multiple threads, provided that each +thread uses a separately allocated \f3WordCompletion\f1 object. In +other words, if two threads want to do word completion, they should +each call \f3new_WordCompletion()\f1 to allocate their own completion +objects. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO +libtecla(3), gl_get_line(3), ef_expand_file(3), pca_lookup_file(3) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.4.1/man3/cpl_file_completions.3 b/libtecla-1.4.1/man3/cpl_file_completions.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_file_completions.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cpl_last_error.3 b/libtecla-1.4.1/man3/cpl_last_error.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_last_error.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cpl_list_completions.3 b/libtecla-1.4.1/man3/cpl_list_completions.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_list_completions.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/cpl_record_error.3 b/libtecla-1.4.1/man3/cpl_record_error.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/cpl_record_error.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/del_CplFileConf.3 b/libtecla-1.4.1/man3/del_CplFileConf.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/del_CplFileConf.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/del_ExpandFile.3 b/libtecla-1.4.1/man3/del_ExpandFile.3 new file mode 100644 index 0000000..f4299df --- /dev/null +++ b/libtecla-1.4.1/man3/del_ExpandFile.3 @@ -0,0 +1 @@ +.so man3/ef_expand_file.3 diff --git a/libtecla-1.4.1/man3/del_GetLine.3 b/libtecla-1.4.1/man3/del_GetLine.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/del_GetLine.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/del_PathCache.3 b/libtecla-1.4.1/man3/del_PathCache.3 new file mode 100644 index 0000000..e5a136e --- /dev/null +++ b/libtecla-1.4.1/man3/del_PathCache.3 @@ -0,0 +1 @@ +.so man3/pca_lookup_file.3 diff --git a/libtecla-1.4.1/man3/del_PcaPathConf.3 b/libtecla-1.4.1/man3/del_PcaPathConf.3 new file mode 100644 index 0000000..e5a136e --- /dev/null +++ b/libtecla-1.4.1/man3/del_PcaPathConf.3 @@ -0,0 +1 @@ +.so man3/pca_lookup_file.3 diff --git a/libtecla-1.4.1/man3/del_WordCompletion.3 b/libtecla-1.4.1/man3/del_WordCompletion.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/del_WordCompletion.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/ef_expand_file.3 b/libtecla-1.4.1/man3/ef_expand_file.3 new file mode 100644 index 0000000..88c2d54 --- /dev/null +++ b/libtecla-1.4.1/man3/ef_expand_file.3 @@ -0,0 +1,245 @@ +.\" Copyright (C) 2000, 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH ef_expand_file 3 +.SH NAME +ef_expand_file, del_ExpandFile, ef_last_error, ef_list_expansions, new_ExpandFile \- expand filenames containing ~user/$envvar and wildcard expressions +.SH SYNOPSIS +.nf +#include + +ExpandFile *new_ExpandFile(void); + +ExpandFile *del_ExpandFile(ExpandFile *ef); + +FileExpansion *ef_expand_file(ExpandFile *ef, + const char *path, + int pathlen); + +int ef_list_expansions(FileExpansion *result, FILE *fp, + int term_width); + +const char *ef_last_error(ExpandFile *ef); +.fi + +.SH DESCRIPTION + +The \f3ef_expand_file()\f1 function is part of the tecla library +(see the libtecla(3) man page). It expands a specified filename, +converting \f3~user/\f1 and \f3~/\f1 expressions at the start of the +filename to the corresponding home directories, replacing +\f3$envvar\f1 with the value of the corresponding environment +variable, and then, if there are any wildcards, matching these against +existing filenames. Backslashes in the input filename are interpreted +as escaping any special meanings of the characters that follow them. +Only backslahes that are themselves preceded by backslashes are +preserved in the expanded filename. +.sp +In the presence of wildcards, the returned list of filenames only +includes the names of existing files which match the +wildcards. Otherwise, the original filename is returned after +expansion of tilde and dollar expressions, and the result is not +checked against existing files. This mimics the file-globbing behavior +of the unix \f3tcsh\f1 shell. +.sp +The supported wildcards and their meanings are: +.nf + * - Match any sequence of zero or more characters. + ? - Match any single character. + [chars] - Match any single character that appears in + 'chars'. If 'chars' contains an expression of + the form a-b, then any character between a and + b, including a and b, matches. The '-' + character looses its special meaning as a + range specifier when it appears at the start + of the sequence of characters. The ']' + character also looses its significance as the + terminator of the range expression if it + appears immediately after the opening '[', at + which point it is treated one of the + characters of the range. If you want both '-' + and ']' to be part of the range, the '-' + should come first and the ']' second. + + [^chars] - The same as [chars] except that it matches any + single character that doesn't appear in + 'chars'. +.fi + +Note that wildcards never match the initial dot in filenames that +start with '.'. The initial '.' must be explicitly specified in the +filename. This again mimics the globbing behavior of most unix shells, +and its rational is based in the fact that in unix, files with names +that start with '.' are usually hidden configuration files, which are +not listed by default by the ls command. +.sp +The following is a complete example of how to use the file expansion +function. + +.nf + #include + #include + + int main(int argc, char *argv[]) + { + ExpandFile *ef; /* The expansion resource object */ + char *filename; /* The filename being expanded */ + FileExpansion *expn; /* The results of the expansion */ + int i; + + ef = new_ExpandFile(); + if(!ef) + return 1; + + for(arg = *(argv++); arg; arg = *(argv++)) { + if((expn = ef_expand_file(ef, arg, -1)) == NULL) { + fprintf(stderr, "Error expanding %s (%s).\\n", arg, + ef_last_error(ef)); + } else { + printf("%s matches the following files:\\n", arg); + for(i=0; infile; i++) + printf(" %s\\n", expn->files[i]); + } + } + + ef = del_ExpandFile(ef); + return 0; + } +.fi +.sp +Descriptions of the functions used above are as follows: +.sp +.nf + ExpandFile *new_ExpandFile(void) +.fi +.sp +This function creates the resources used by the \f3ef_expand_file()\f1 +function. In particular, it maintains the memory that is used to record the +array of matching filenames that is returned by \f3ef_expand_file()\f1. This +array is expanded as needed, so there is no built in limit to the number of +files that can be matched. +.sp +.nf + ExpandFile *del_ExpandFile(ExpandFile *ef) +.fi +.sp +This function deletes the resources that were returned by a previous call to +\f3new_ExpandFile()\f1. It always returns \f3NULL\f1 (ie a deleted object). It +does nothing if the \f3ef\f1 argument is \f3NULL\f1. +.sp +A container of the following type is returned by \f3ef_expand_file()\f1. +.sp +.nf + typedef struct { + int exists; /* True if the files in files[] exist */ + int nfile; /* The number of files in files[] */ + char **files; /* An array of 'nfile' filenames. */ + } FileExpansion; +.fi +.sp +.nf + FileExpansion *ef_expand_file(ExpandFile *ef, + const char *path, + int pathlen) +.fi +.sp +The \f3ef_expand_file()\f1 function performs filename expansion, as documented +at the start of this section. Its first argument is a resource object returned +by \f3new_ExpandFile()\f1. A pointer to the start of the filename to be matched +is passed via the \f3path\f1 argument. This must be a normal \f3NUL\f1 +terminated string, but unless a length of -1 is passed in \f3pathlen\f1, only +the first \f3pathlen\f1 characters will be used in the filename expansion. If +the length is specified as -1, the whole of the string will be +expanded. +.sp +The function returns a pointer to a container who's contents are the +results of the expansion. If there were no wildcards in the filename, +the \f3nfile\f1 member will be 1, and the \f3exists\f1 member should +be queried if it is important to know if the expanded file currently +exists or not. If there were wildcards, then the contained +\f3files[]\f1 array will contain the names of the \f3nfile\f1 existing +files that matched the wildcarded filename, and the \f3exists\f1 +member will have the value 1. Note that the returned container belongs +to the specified \f3ef\f1 object, and its contents will change on each +call, so if you need to retain the results of more than one call to +\f3ef_expand_file()\f1, you should either make a private copy of the +returned results, or create multiple file-expansion resource objects +via multiple calls to \f3new_ExpandFile()\f1. +.sp +On error, \f3NULL\f1 is returned, and an explanation of the error can +be determined by calling \f3ef_last_error(ef)\f1. +.sp +.nf + const char *ef_last_error(ExpandFile *ef) +.fi +.sp +This function returns the message which describes the error that +occurred on the last call to \f3ef_expand_file()\f1, for the given +\f3(ExpandFile *ef)\f1 resource object. +.sp +.nf + int ef_list_expansions(FileExpansion *result, FILE *fp, + int terminal_width); +.fi +.sp +The \f3ef_list_expansions()\f1 function provides a convenient way to +list the filename expansions returned by \f3ef_expand_file()\f1. Like +the unix \f3ls\f1 command, it arranges the filenames into equal width +columns, each column having the width of the largest file. The number +of columns used is thus determined by the length of the longest +filename, and the specified terminal width. Beware that filenames that +are longer than the specified terminal width are printed without being +truncated, so output longer than the specified terminal width can +occur. The list is written to the stdio stream specified by the +\f3fp\f1 argument. + +.SH THREAD SAFETY + +In multi-threaded programs, you should use the \f3libtecla_r.a\f1 +version of the library. This uses POSIX reentrant functions where +available (hence the \f3_r\f1 suffix), and disables features that rely +on non-reentrant system functions. Currently there are no features +disabled in this module. + +Using the \f3libtecla_r.a\f1 version of the library, it is safe to use +the facilities of this module in multiple threads, provided that each +thread uses a separately allocated \f3ExpandFile\f1 object. In other +words, if two threads want to do file expansion, they should each call +\f3new_ExpandFile()\f1 to allocate their own file-expansion objects. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +.fi + +.SH SEE ALSO +libtecla(3), gl_get_line(3), cpl_complete_word(3), pca_lookup_file(3) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.4.1/man3/ef_last_error.3 b/libtecla-1.4.1/man3/ef_last_error.3 new file mode 100644 index 0000000..f4299df --- /dev/null +++ b/libtecla-1.4.1/man3/ef_last_error.3 @@ -0,0 +1 @@ +.so man3/ef_expand_file.3 diff --git a/libtecla-1.4.1/man3/ef_list_expansions.3 b/libtecla-1.4.1/man3/ef_list_expansions.3 new file mode 100644 index 0000000..f4299df --- /dev/null +++ b/libtecla-1.4.1/man3/ef_list_expansions.3 @@ -0,0 +1 @@ +.so man3/ef_expand_file.3 diff --git a/libtecla-1.4.1/man3/enhance.3 b/libtecla-1.4.1/man3/enhance.3 new file mode 100644 index 0000000..648ef34 --- /dev/null +++ b/libtecla-1.4.1/man3/enhance.3 @@ -0,0 +1,86 @@ +.\" Copyright (C) 2000, 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH libtecla 3 +.SH NAME +enhance - A program that adds command-line editing to third party programs. +.SH SYNOPSIS +.nf +enhance command [ argument ... ] +.fi + +.SH DESCRIPTION + +The \f3enhance\f1 program provides enhanced command-line editing +facilities to users of third party applications, to which one doesn't +have any source code. It does this by placing a pseudo-terminal +between the application and the real terminal. It uses the tecla +command-line editing library to read input from the real terminal, +then forwards each just completed input line to the application via +the pseudo-terminal. All output from the application is forwarded +back unchanged to the real terminal. +.sp +Whenever the application stops generating output for more than a tenth +of a second, the \f3enhance\f1 program treats the latest incomplete +output line as the prompt, and redisplays any incompleted input line +that the user has typed after it. Note that the small delay, which is +imperceptible to the user, isn't necessary for correct operation of +the program. It is just an optimization, designed to stop the input +line from being redisplayed so often that it slows down output. + +.SH DEFICIENCIES + +The one major problem that hasn't been solved yet, is how to deal with +applications that change whether typed input is echo'd by their +controlling terminal. For example, programs that ask for a password, +such as ftp and telnet, temporarily tell their controlling terminal +not to echo what the user types. Since this request goes to the +application side of the psuedo terminal, the \f3enhance\f1 program has +no way of knowing that this has happened, and continues to echo typed +input to its controlling terminal, while the user types their +password. +.sp +Furthermore, before executing the host application, the \f3enhance\f1 +program initially sets the pseudo terminal to noecho mode, so that +everything that it sends to the program doesn't get redundantly +echoed. If a program that switches to noecho mode explicitly restores +echoing afterwards, rather than restoring the terminal modes that were +previously in force, then subsequently, every time that you enter a +new input line, a duplicate copy will be displayed on the next line. + +.SH FILES +.nf +libtecla.a - The tecla library. +~/.teclarc - The tecla personal customization file. +.fi + +.SH SEE ALSO +libtecla(3) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.4.1/man3/gl_change_terminal.3 b/libtecla-1.4.1/man3/gl_change_terminal.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_change_terminal.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_clear_history.3 b/libtecla-1.4.1/man3/gl_clear_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_clear_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_configure_getline.3 b/libtecla-1.4.1/man3/gl_configure_getline.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_configure_getline.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_customize_completion.3 b/libtecla-1.4.1/man3/gl_customize_completion.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_customize_completion.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_echo_mode.3 b/libtecla-1.4.1/man3/gl_echo_mode.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_echo_mode.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_get_line.3 b/libtecla-1.4.1/man3/gl_get_line.3 new file mode 100644 index 0000000..51fc9d8 --- /dev/null +++ b/libtecla-1.4.1/man3/gl_get_line.3 @@ -0,0 +1,2329 @@ +.\" Copyright (C) 2000, 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH gl_get_line 3 +.SH NAME +gl_get_line, new_GetLine, del_GetLine, gl_customize_completion, gl_change_terminal, gl_configure_getline, gl_load_history, gl_save_history, gl_group_history, gl_show_history, gl_watch_fd, gl_terminal_size, gl_resize_history, gl_limit_history, gl_clear_history, gl_toggle_history, gl_lookup_history, gl_state_of_history, gl_range_of_history, gl_size_of_history, gl_echo_mode, gl_replace_prompt, gl_prompt_style, gl_ignore_signal, gl_trap_signal, gl_last_signal \- allow the user to compose an input line +.SH SYNOPSIS +.nf +#include +#include + +GetLine *new_GetLine(size_t linelen, size_t histlen); + +GetLine *del_GetLine(GetLine *gl); + +char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); + +int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); + +int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); + +int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); + +int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + +int gl_load_history(GetLine *gl, const char *filename, + const char *comment); + +int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); + +int gl_group_history(GetLine *gl, unsigned stream); + +int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, int all_groups, + int max_lines); + +int gl_resize_history(GetLine *gl, size_t bufsize); + +void gl_limit_history(GetLine *gl, int max_lines); + +void gl_clear_history(GetLine *gl, int all_groups); + +void gl_toggle_history(GetLine *gl, int enable); + +GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); + +int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); + +void gl_state_of_history(GetLine *gl, + GlHistoryState *state); + +void gl_range_of_history(GetLine *gl, + GlHistoryRange *range); + +void gl_size_of_history(GetLine *gl, GlHistorySize *size); + +void gl_echo_mode(GetLine *gl, int enable); + +void gl_replace_prompt(GetLine *gl, const char *prompt); + +void gl_prompt_style(GetLine *gl, GlPromptStyle style); + +int gl_ignore_signal(GetLine *gl, int signo); + +int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); + +int gl_last_signal(const GetLine *gl); + +.fi + +.SH DESCRIPTION + +The \f3gl_get_line()\f1 function is part of the tecla library (see +the libtecla(3) man page). If the user is typing at a terminal, it +prompts them for an line of input, then provides interactive editing +facilities, similar to those of the unix \f3tcsh\f1 shell. In addition +to simple command-line editing, it supports recall of previously +entered command lines, TAB completion of file names, and in-line +wild-card expansion of filenames. +.sp +.SH AN EXAMPLE + +The following shows a complete example of how to use the +\f3gl_get_line()\f1 function to get input from the user: + +.nf + #include + #include + #include + + int main(int argc, char *argv[]) + { + char *line; /* The line that the user typed */ + GetLine *gl; /* The gl_get_line() resource object */ + + setlocale(LC_CTYPE, ""); /* Adopt the user's choice */ + /* of character set. */ + + gl = new_GetLine(1024, 2048); + if(!gl) + return 1; + + while((line=gl_get_line(gl, "$ ", NULL, -1)) != NULL && + strcmp(line, "exit\\n") != 0) + printf("You typed: %s\\n", line); + + gl = del_GetLine(gl); + return 0; + } +.fi +.sp +In the example, first the resources needed by the \f3gl_get_line()\f1 function +are created by calling \f3new_GetLine()\f1. This allocates the memory used in +subsequent calls to the \f3gl_get_line()\f1 function, including the history +buffer for recording previously entered lines. Then one or more lines are read +from the user, until either an error occurs, or the user types \f3exit\f1. Then +finally the resources that were allocated by \f3new_GetLine()\f1, are returned +to the system by calling \f3del_GetLine()\f1. Note the use of the \f3NULL\f1 +return value of \f3del_GetLine()\f1 to make \f3gl\f1 \f3NULL\f1. This is a +safety precaution. If the program subsequently attempts to pass \f3gl\f1 to +\f3gl_get_line()\f1, said function will complain, and return an error, instead of +attempting to use the deleted resource object. + +.sp +.SH THE FUNCTIONS USED IN THE EXAMPLE +The descriptions of the functions used in the example are as follows: +.sp +.nf + GetLine *new_GetLine(size_t linelen, size_t histlen) +.fi +.sp +This function creates the resources used by the \f3gl_get_line()\f1 +function and returns an opaque pointer to the object that contains +them. The maximum length of an input line is specified via the +\f3linelen\f1 argument, and the number of bytes to allocate for +storing history lines is set by the \f3histlen\f1 argument. History +lines are stored back-to-back in a single buffer of this size. Note +that this means that the number of history lines that can be stored at +any given time, depends on the lengths of the individual lines. If +you want to place an upper limit on the number of lines that can be +stored, see the \f3gl_limit_history()\f1 function described later. If +you don't want history at all, specify \f3histlen\f1 as zero, and no +history buffer will be allocated. +.sp +On error, a message is printed to \f3stderr\f1 and \f3NULL\f1 is returned. +.sp +.nf + GetLine *del_GetLine(GetLine *gl) +.fi +.sp +This function deletes the resources that were returned by a previous +call to \f3new_GetLine()\f1. It always returns \f3NULL\f1 (ie a +deleted object). It does nothing if the \f3gl\f1 argument is +\f3NULL\f1. +.sp +.nf + char *gl_get_line(GetLine *gl, const char *prompt, + const char *start_line, int start_pos); +.fi +.sp +The \f3gl_get_line()\f1 function can be called any number of +times to read input from the user. The \f3gl\f1 argument +must have been previously returned by a call to +\f3new_GetLine()\f1. The \f3prompt\f1 argument should be a +normal \f3NUL\f1 terminated string, specifying the prompt to +present the user with. By default prompts are displayed +literally, but if enabled with the \f3gl_prompt_style()\f1 +function (see later), prompts can contain directives to do +underlining, switch to and from bold fonts, or turn +highlighting on and off. + +If you want to specify the initial contents of the line, for +the user to edit, pass the desired string via the +\f3start_line\f1 argument. You can then specify which +character of this line the cursor is initially positioned +over, using the \f3start_pos\f1 argument. This should be -1 +if you want the cursor to follow the last character of the +start line. If you don't want to preload the line in this +manner, send \f3start_line\f1 as \f3NULL\f1, and set +\f3start_pos\f1 to -1. + +The \f3gl_get_line()\f1 function returns a pointer to the line entered +by the user, or \f3NULL\f1 on error or at the end of the input. The +returned pointer is part of the specified \f3gl\f1 resource object, +and thus should not be free'd by the caller, or assumed to be +unchanging from one call to the next. When reading from a user at a +terminal, there will always be a newline character at the end of the +returned line. When standard input is being taken from a pipe or a +file, there will similarly be a newline unless the input line was too +long to store in the internal buffer. In the latter case you should +call \f3gl_get_line()\f1 again to read the rest of the line. Note that +this behavior makes \f3gl_get_line()\f1 similar to \f3fgets()\f1. In +fact when \f3stdin\f1 isn't connected to a terminal,\f3gl_get_line()\f1 +just calls \f3fgets()\f1. + +.SH OPTIONAL PROMPT FORMATTING + +Whereas by default the prompt string that you specify is +displayed literally, without any special interpretation of +the characters within it, the \f3gl_prompt_style()\f1 +function can be used to enable optional formatting +directives within the prompt. +.sp +.nf + void gl_prompt_style(GetLine *gl, GlPromptStyle style); +.fi +.sp +The \f3style\f1 argument, which specifies the formatting +style, can take any of the following values: +.sp +.nf + GL_FORMAT_PROMPT - In this style, the formatting + directives described below, when + included in prompt strings, are + interpreted as follows: + + %B - Display subsequent + characters with a bold + font. + %b - Stop displaying characters + with the bold font. + %F - Make subsequent characters + flash. + %f - Turn off flashing + characters. + %U - Underline subsequent + characters. + %u - Stop underlining + characters. + %P - Switch to a pale (half + brightness) font. + %p - Stop using the pale font. + %S - Highlight subsequent + characters (also known as + standout mode). + %s - Stop highlighting + characters. + %V - Turn on reverse video. + %v - Turn off reverse video. + %% - Display a single % + character. + + For example, in this mode, a prompt + string like \f3"%UOK%u$ "\f1 would + display the prompt \f3"OK$ "\f1, + but with the \f3OK\f1 part + underlined. + + Note that although a pair of + characters that starts with a % + character, but doesn't match any of + the above directives is displayed + literally, if a new directive is + subsequently introduced which does + match, the displayed prompt will + change, so it is better to always + use %% to display a literal %. + + Also note that not all terminals + support all of these text + attributes, and that some substitute + a different attribute for missing + ones. + + GL_LITERAL_PROMPT - In this style, the prompt string is + printed literally. This is the + default style. +.fi +.sp + +.SH THE AVAILABLE KEY BINDING FUNCTIONS + +The \f3gl_get_line()\f1 function provides a number of functions which +can be bound to key sequences. The names of these functions, and what +they do, are given below. + +.nf + user-interrupt - Send a SIGINT signal to the + parent process. + abort - Send a SIGABRT signal to the + parent process. + suspend - Suspend the parent process. + stop-output - Pause terminal output. + start-output - Resume paused terminal output. + literal-next - Arrange for the next character + to be treated as a normal + character. This allows control + characters to be entered. + cursor-right - Move the cursor one character + right. + cursor-left - Move the cursor one character + left. + insert-mode - Toggle between insert mode and + overwrite mode. + beginning-of-line - Move the cursor to the + beginning of the line. + end-of-line - Move the cursor to the end of + the line. + delete-line - Delete the contents of the + current line. + kill-line - Delete everything that follows + the cursor. + backward-kill-line - Delete all characters between + the cursor and the start of the + line. + forward-word - Move to the end of the word + which follows the cursor. + forward-to-word - Move the cursor to the start of + the word that follows the + cursor. + backward-word - Move to the start of the word + which precedes the cursor. + goto-column - Move the cursor to the + 1-relative column in the line + specified by any preceding + digit-argument sequences (see + ENTERING REPEAT COUNTS below). + find-parenthesis - If the cursor is currently + over a parenthesis character, + move it to the matching + parenthesis character. If not + over a parenthesis character + move right to the next close + parenthesis. + forward-delete-char - Delete the character under the + cursor. + backward-delete-char - Delete the character which + precedes the cursor. + list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + del-char-or-list-or-eof - This is intended for binding + to ^D. When invoked when the + cursor is within the line it + invokes forward-delete-char. + When invoked at the end of the + line it displays all possible + completions then redisplays + the line unchanged. When + invoked on an empty line, it + signals end-of-input (EOF) to + the caller of gl_get_line(). + forward-delete-word - Delete the word which follows + the cursor. + backward-delete-word - Delete the word which precedes + the cursor. + upcase-word - Convert all of the characters + of the word which follows the + cursor, to upper case. + downcase-word - Convert all of the characters + of the word which follows the + cursor, to lower case. + capitalize-word - Capitalize the word which + follows the cursor. + change-case - If the next character is upper + case, toggle it to lower case + and vice versa. + redisplay - Redisplay the line. + clear-screen - Clear the terminal, then + redisplay the current line. + transpose-chars - Swap the character under the + cursor with the character just + before the cursor. + set-mark - Set a mark at the position of + the cursor. + exchange-point-and-mark - Move the cursor to the last + mark that was set, and move + the mark to where the cursor + used to be. + kill-region - Delete the characters that lie + between the last mark that was + set, and the cursor. + copy-region-as-kill - Copy the text between the mark + and the cursor to the cut + buffer, without deleting the + original text. + yank - Insert the text that was last + deleted, just before the + current position of the cursor. + append-yank - Paste the current contents of + the cut buffer, after the + cursor. + up-history - Recall the next oldest line + that was entered. Note that + in vi mode you are left in + command mode. + down-history - Recall the next most recent + line that was entered. If no + history recall session is + currently active, the next + line from a previous recall + session is recalled. Note that + in vi mode you are left in + command mode. + history-search-backward - Recall the next oldest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-search-forward - Recall the next newest line + who's prefix matches the string + which currently precedes the + cursor (in vi command-mode the + character under the cursor is + also included in the search + string). Note that in vi mode + you are left in command mode. + history-re-search-backward -Recall the next oldest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + history-re-search-forward - Recall the next newest line + who's prefix matches that + established by the last + invocation of either + history-search-forward or + history-search-backward. + complete-word - Attempt to complete the + incomplete word which + precedes the cursor. Unless + the host program has customized + word completion, filename + completion is attempted. In vi + commmand mode the character + under the cursor is also + included in the word being + completed, and you are left in + vi insert mode. + expand-filename - Within the command line, expand + wild cards, tilde expressions + and dollar expressions in the + filename which immediately + precedes the cursor. In vi + commmand mode the character + under the cursor is also + included in the filename being + expanded, and you are left in + vi insert mode. + list-glob - List any filenames which match + the wild-card, tilde and dollar + expressions in the filename + which immediately precedes the + cursor, then redraw the input + line unchanged. + list-history - Display the contents of the + history list for the current + history group. If a repeat + count of > 1 is specified, + only that many of the most + recent lines are displayed. + See the "ENTERING REPEAT + COUNTS" section. + read-from-file - Temporarily switch to reading + input from the file who's + name precedes the cursor. + read-init-files - Re-read teclarc configuration + files. + beginning-of-history - Move to the oldest line in the + history list. Note that in vi + mode you are left in command + mode. + end-of-history - Move to the newest line in the + history list (ie. the current + line). Note that in vi mode + this leaves you in command + mode. + digit-argument - Enter a repeat count for the + next key-binding function. + For details, see the ENTERING + REPEAT COUNTS section. + newline - Terminate and return the + current contents of the + line, after appending a + newline character. The newline + character is normally '\\n', + but will be the first + character of the key-sequence + that invoked the newline + action, if this happens to be + a printable character. If the + action was invoked by the + '\\n' newline character or the + '\\r' carriage return + character, the line is + appended to the history + buffer. + repeat-history - Return the line that is being + edited, then arrange for the + next most recent entry in the + history buffer to be recalled + when \f3gl_get_line()\f1 is + next called. Repeatedly + invoking this action causes + successive historical input + lines to be re-executed. Note + that this action is equivalent + to the 'Operate' action in + ksh. + ring-bell - Ring the terminal bell, unless + the bell has been silenced via + the \f3nobeep\f1 configuration + option (see the THE TECLA + CONFIGURATION FILE section). + forward-copy-char - Copy the next character into + the cut buffer (NB. use repeat + counts to copy more than one). + backward-copy-char - Copy the previous character + into the cut buffer. + forward-copy-word - Copy the next word into the cut + buffer. + backward-copy-word - Copy the previous word into the + cut buffer. + forward-find-char - Move the cursor to the next + occurrence of the next + character that you type. + backward-find-char - Move the cursor to the last + occurrence of the next + character that you type. + forward-to-char - Move the cursor to the + character just before the next + occurrence of the next + character that the user types. + backward-to-char - Move the cursor to the + character just after the last + occurrence before the cursor + of the next character that the + user types. + repeat-find-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char or + forward-to-char. + invert-refind-char - Repeat the last + backward-find-char, + forward-find-char, + backward-to-char, or + forward-to-char in the + opposite direction. + delete-to-column - Delete the characters from the + cursor up to the column that + is specified by the repeat + count. + delete-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis. + forward-delete-find - Delete the characters from the + cursor up to and including the + following occurence of the + next character typed. + backward-delete-find - Delete the characters from the + cursor up to and including the + preceding occurence of the + next character typed. + forward-delete-to - Delete the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed. + backward-delete-to - Delete the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed. + delete-refind - Repeat the last *-delete-find + or *-delete-to action. + delete-invert-refind - Repeat the last *-delete-find + or *-delete-to action, in the + opposite direction. + copy-to-column - Copy the characters from the + cursor up to the column that + is specified by the repeat + count, into the cut buffer. + copy-to-parenthesis - Copy the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, into + the cut buffer. + forward-copy-find - Copy the characters from the + cursor up to and including the + following occurence of the + next character typed, into the + cut buffer. + backward-copy-find - Copy the characters from the + cursor up to and including the + preceding occurence of the + next character typed, into the + cut buffer. + forward-copy-to - Copy the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, into the cut + buffer. + backward-copy-to - Copy the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, into the cut + buffer. + copy-refind - Repeat the last *-copy-find + or *-copy-to action. + copy-invert-refind - Repeat the last *-copy-find + or *-copy-to action, in the + opposite direction. + vi-mode - Switch to vi mode from emacs + mode. + emacs-mode - Switch to emacs mode from vi + mode. + vi-insert - From vi command mode, switch to + insert mode. + vi-overwrite - From vi command mode, switch to + overwrite mode. + vi-insert-at-bol - From vi command mode, move the + cursor to the start of the line + and switch to insert mode. + vi-append-at-eol - From vi command mode, move the + cursor to the end of the line + and switch to append mode. + vi-append - From vi command mode, move the + cursor one position right, and + switch to insert mode. + vi-replace-char - From vi command mode, replace + the character under the cursor + with the the next character + entered. + vi-forward-change-char - From vi command mode, delete + the next character then enter + insert mode. + vi-backward-change-char - From vi command mode, delete + the preceding character then + enter insert mode. + vi-forward-change-word - From vi command mode, delete + the next word then enter + insert mode. + vi-backward-change-word - From vi command mode, delete + the preceding word then + enter insert mode. + vi-change-rest-of-line - From vi command mode, delete + from the cursor to the end of + the line, then enter insert + mode. + vi-change-line - From vi command mode, delete + the current line, then enter + insert mode. + vi-change-to-bol - From vi command mode, delete + all characters between the + cursor and the beginning of + the line, then enter insert + mode. + vi-change-to-column - From vi command mode, delete + the characters from the cursor + up to the column that is + specified by the repeat count, + then enter insert mode. + vi-change-to-parenthesis - Delete the characters from the + cursor up to and including + the matching parenthesis, or + next close parenthesis, then + enter vi insert mode. + vi-forward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + following occurence of the + next character typed, then + enter insert mode. + vi-backward-change-find - From vi command mode, delete + the characters from the + cursor up to and including the + preceding occurence of the + next character typed, then + enter insert mode. + vi-forward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the following + occurence of the next + character typed, then enter + insert mode. + vi-backward-change-to - From vi command mode, delete + the characters from the + cursor up to, but not + including, the preceding + occurence of the next + character typed, then enter + insert mode. + vi-change-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action. + vi-change-invert-refind - Repeat the last + vi-*-change-find or + vi-*-change-to action, in the + opposite direction. + vi-undo - In vi mode, undo the last + editing operation. + vi-repeat-change - In vi command mode, repeat the + last command that modified the + line. +.fi + +.SH DEFAULT KEY BINDINGS IN EMACS MODE + +The following default key bindings, which can be overriden by +the tecla configuration file, are designed to mimic most of +the bindings of the unix \f3tcsh\f1 shell, when it is in +emacs editing mode. +.sp +This is the default editing mode of the tecla library. +.sp +Note that a key sequence like \f3^A\f1 or \f3C-a\f1 means hold the control-key +down while pressing the letter \f3A\f1, and that where you see \f3\\E\f1 or +\f3M-\f1 in a binding, this represents the escape key or the Meta modifier +key. Also note that to \f3gl_get_line()\f1, pressing the escape key before a +key is equivalent to pressing the meta key at the same time as that key. Thus +the key sequence \f3M-p\f1 can be typed in two ways, by pressing the escape +key, followed by pressing \f3p\f1, or by pressing the Meta key at the same time +as \f3p\f1. +.sp +Under UNIX the terminal driver sets a number of special keys for certain +functions. The tecla library attempts to use the same keybindings to maintain +consistency. The key sequences shown for the following 6 bindings are thus just +examples of what they will probably be set to. If you have used the \f3stty\f1 +command to change these keys, then the default bindings should match. + +.nf + ^C -> user-interrupt + ^\\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next +.fi + +The cursor keys are refered to by name, as follows. This is necessary +because different types of terminals generate different key sequences +when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + +The remaining bindings don't depend on the terminal setttings. + +.nf + ^F -> cursor-right + ^B -> cursor-left + M-i -> insert-mode + ^A -> beginning-of-line + ^E -> end-of-line + ^U -> delete-line + ^K -> kill-line + M-f -> forward-word + M-b -> backward-word + ^D -> del-char-or-list-or-eof + ^H -> backward-delete-char + ^? -> backward-delete-char + M-d -> forward-delete-word + M-^H -> backward-delete-word + M-^? -> backward-delete-word + M-u -> upcase-word + M-l -> downcase-word + M-c -> capitalize-word + ^R -> redisplay + ^L -> clear-screen + ^T -> transpose-chars + ^@ -> set-mark + ^X^X -> exchange-point-and-mark + ^W -> kill-region + M-w -> copy-region-as-kill + ^Y -> yank + ^P -> up-history + ^N -> down-history + M-p -> history-search-backward + M-n -> history-search-forward + ^I -> complete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^Xg -> list-glob + ^Xh -> list-history + M-< -> beginning-of-history + M-> -> end-of-history + \\n -> newline + \\r -> newline + M-o -> repeat-history + M-^V -> vi-mode + + M-0, M-1, ... M-9 -> digit-argument (see below) +.fi + +Note that ^I is what the TAB key generates, and that ^@ can be +generated not only by pressing the control key and the @ key +simultaneously, but also by pressing the control key and the space bar +at the same time. + +.SH DEFAULT KEY BINDINGS IN VI MODE + +The following default key bindings are designed to mimic the +vi style of editing as closely as possible. This means that +very few editing functions are provided in the initial +character input mode, editing functions instead being +provided by the vi command mode. Vi command mode is entered +whenever the escape character is pressed, or whenever a +key-sequence that starts with a meta character is entered. In +addition to mimicing vi, libtecla provides bindings for tab +completion, wild-card expansion of file names, and historical +line recall. +.sp +To learn how to tell the tecla library to use vi mode instead +of the default emacs editing mode, see the section entitled +THE TECLA CONFIGURATION FILE. +.sp +As already mentioned above in the emacs section, Note that a +key sequence like \f3^A\f1 or \f3C-a\f1 means hold the +control-key down while pressing the letter \f3A\f1, and that +where you see \f3\\E\f1 or \f3M-\f1 in a binding, this +represents the escape key or the Meta modifier key. Also note +that to \f3gl_get_line()\f1, pressing the escape key before a +key is equivalent to pressing the meta key at the same time +as that key. Thus the key sequence \f3M-p\f1 can be typed in +two ways, by pressing the escape key, followed by pressing +\f3p\f1, or by pressing the Meta key at the same time as +\f3p\f1. +.sp +Under UNIX the terminal driver sets a number of special keys +for certain functions. The tecla library attempts to use the +same keybindings to maintain consistency, binding them both +in input mode and in command mode. The key sequences shown +for the following 6 bindings are thus just examples of what +they will probably be set to. If you have used the \f3stty\f1 +command to change these keys, then the default bindings +should match. + +.nf + ^C -> user-interrupt + ^\\ -> abort + ^Z -> suspend + ^Q -> start-output + ^S -> stop-output + ^V -> literal-next + M-^C -> user-interrupt + M-^\\ -> abort + M-^Z -> suspend + M-^Q -> start-output + M-^S -> stop-output +.fi + +Note that above, most of the bindings are defined twice, once +as a raw control code like \f3^C\f1 and then a second time as +a meta character like \f3M-^C\f1. The former is the binding +for vi input mode, whereas the latter is the binding for vi +command mode. Once in command mode all key-sequences that the +user types that they don't explicitly start with an escape or +a meta key, have their first key secretly converted to a meta +character before the key sequence is looked up in the key +binding table. Thus, once in command mode, when you type the +letter \f3i\f1, for example, the tecla library actually looks +up the binding for \f3M-i\f1. + +The cursor keys are refered to by name, as follows. This is necessary +because different types of terminals generate different key sequences +when their cursor keys are pressed. + + right -> cursor-right + left -> cursor-left + up -> up-history + down -> down-history + +The cursor keys normally generate a keysequence that start +with an escape character, so beware that using the arrow keys +will put you into command mode (if you aren't already in +command mode). +.sp +The following are the terminal-independent key bindings for vi input +mode. + +.nf + ^D -> list-or-eof + ^G -> list-glob + ^H -> backward-delete-char + ^I -> complete-word + \\r -> newline + \\n -> newline + ^L -> clear-screen + ^N -> down-history + ^P -> up-history + ^R -> redisplay + ^U -> backward-kill-line + ^W -> backward-delete-word + ^X* -> expand-filename + ^X^F -> read-from-file + ^X^R -> read-init-files + ^? -> backward-delete-char +.fi + +The following are the key bindings that are defined in vi +command mode, this being specified by them all starting with +a meta character. As mentioned above, once in command mode +the initial meta character is optional. For example, you +might enter command mode by typing Esc, and then press h +twice to move the cursor two positions to the left. Both h +characters get quietly converted to M-h before being compared +to the key-binding table, the first one because Escape +followed by a character is always converted to the equivalent +meta character, and the second because command mode was +already active. + +.nf + M-\\ -> cursor-right (Meta-space) + M-$ -> end-of-line + M-* -> expand-filename + M-+ -> down-history + M-- -> up-history + M-< -> beginning-of-history + M-> -> end-of-history + M-^ -> beginning-of-line + M-; -> repeat-find-char + M-, -> invert-refind-char + M-| -> goto-column + M-~ -> change-case + M-. -> vi-repeat-change + M-% -> find-parenthesis + M-a -> vi-append + M-A -> vi-append-at-eol + M-b -> backward-word + M-B -> backward-word + M-C -> vi-change-rest-of-line + M-cb -> vi-backward-change-word + M-cB -> vi-backward-change-word + M-cc -> vi-change-line + M-ce -> vi-forward-change-word + M-cE -> vi-forward-change-word + M-cw -> vi-forward-change-word + M-cW -> vi-forward-change-word + M-cF -> vi-backward-change-find + M-cf -> vi-forward-change-find + M-cT -> vi-backward-change-to + M-ct -> vi-forward-change-to + M-c; -> vi-change-refind + M-c, -> vi-change-invert-refind + M-ch -> vi-backward-change-char + M-c^H -> vi-backward-change-char + M-c^? -> vi-backward-change-char + M-cl -> vi-forward-change-char + M-c\\ -> vi-forward-change-char (Meta-c-space) + M-c^ -> vi-change-to-bol + M-c0 -> vi-change-to-bol + M-c$ -> vi-change-rest-of-line + M-c| -> vi-change-to-column + M-c% -> vi-change-to-parenthesis + M-dh -> backward-delete-char + M-d^H -> backward-delete-char + M-d^? -> backward-delete-char + M-dl -> forward-delete-char + M-d -> forward-delete-char (Meta-d-space) + M-dd -> delete-line + M-db -> backward-delete-word + M-dB -> backward-delete-word + M-de -> forward-delete-word + M-dE -> forward-delete-word + M-dw -> forward-delete-word + M-dW -> forward-delete-word + M-dF -> backward-delete-find + M-df -> forward-delete-find + M-dT -> backward-delete-to + M-dt -> forward-delete-to + M-d; -> delete-refind + M-d, -> delete-invert-refind + M-d^ -> backward-kill-line + M-d0 -> backward-kill-line + M-d$ -> kill-line + M-D -> kill-line + M-d| -> delete-to-column + M-d% -> delete-to-parenthesis + M-e -> forward-word + M-E -> forward-word + M-f -> forward-find-char + M-F -> backward-find-char + M-- -> up-history + M-h -> cursor-left + M-H -> beginning-of-history + M-i -> vi-insert + M-I -> vi-insert-at-bol + M-j -> down-history + M-J -> history-search-forward + M-k -> up-history + M-K -> history-search-backward + M-l -> cursor-right + M-L -> end-of-history + M-n -> history-re-search-forward + M-N -> history-re-search-backward + M-p -> append-yank + M-P -> yank + M-r -> vi-replace-char + M-R -> vi-overwrite + M-s -> vi-forward-change-char + M-S -> vi-change-line + M-t -> forward-to-char + M-T -> backward-to-char + M-u -> vi-undo + M-w -> forward-to-word + M-W -> forward-to-word + M-x -> forward-delete-char + M-X -> backward-delete-char + M-yh -> backward-copy-char + M-y^H -> backward-copy-char + M-y^? -> backward-copy-char + M-yl -> forward-copy-char + M-y\\ -> forward-copy-char (Meta-y-space) + M-ye -> forward-copy-word + M-yE -> forward-copy-word + M-yw -> forward-copy-word + M-yW -> forward-copy-word + M-yb -> backward-copy-word + M-yB -> backward-copy-word + M-yf -> forward-copy-find + M-yF -> backward-copy-find + M-yt -> forward-copy-to + M-yT -> backward-copy-to + M-y; -> copy-refind + M-y, -> copy-invert-refind + M-y^ -> copy-to-bol + M-y0 -> copy-to-bol + M-y$ -> copy-rest-of-line + M-yy -> copy-line + M-Y -> copy-line + M-y| -> copy-to-column + M-y% -> copy-to-parenthesis + M-^E -> emacs-mode + M-^H -> cursor-left + M-^? -> cursor-left + M-^L -> clear-screen + M-^N -> down-history + M-^P -> up-history + M-^R -> redisplay + M-^D -> list-or-eof + M-^I -> complete-word + M-\\r -> newline + M-\\n -> newline + M-^X^R -> read-init-files + M-^Xh -> list-history + + M-0, M-1, ... M-9 -> digit-argument (see below) +.fi + +Note that ^I is what the TAB key generates. + +.SH ENTERING REPEAT COUNTS + +Many of the key binding functions described previously, take +an optional count, typed in before the target +keysequence. This is interpreted as a repeat count by most +bindings. A notable exception is the goto-column binding, +which interprets the count as a column number. +.sp +By default you can specify this count argument by pressing +the meta key while typing in the numeric count. This relies +on the \f3digit-argument\f1 action being bound to Meta-0, +Meta-1 etc. Once any one of these bindings has been +activated, you can optionally take your finger off the meta +key to type in the rest of the number, since every numeric +digit thereafter is treated as part of the number, unless it +is preceded by the \f3literal-next\f1 binding. As soon as a +non-digit, or literal digit key is pressed the repeat count +is terminated and either causes the just typed character to +be added to the line that many times, or causes the next +key-binding function to be given that argument. +.sp +For example, in emacs mode, typing: +.sp +.nf + M-12a +.fi +.sp +causes the letter 'a' to be added to the line 12 times, +whereas +.sp +.nf + M-4M-c +.fi +.sp +Capitalizes the next 4 words. +.sp +In vi command mode the Meta modifier is automatically added +to all characters typed in, so to enter a count in vi +command-mode, just involves typing in the number, just as at +it does in the vi editor itself. So for example, in vi +command mode, typing: +.sp +.nf + 4w2x +.fi +.sp +moves the cursor four words to the right, then deletes two characters. +.sp +You can also bind \f3digit-argument\f1 to other key sequences. If +these end in a numeric digit, that digit gets appended to the current +repeat count. If it doesn't end in a numeric digit, a new repeat count +is started with a value of zero, and can be completed by typing in the +number, after letting go of the key which triggered the digit-argument +action. + +.SH THE TECLA CONFIGURATION FILE + +By default, the first call to \f3gl_get_line()\f1 looks for a file +called \f3\&.teclarc\f1 in your home directory (ie. \f3~/.teclarc\f1). +If it finds this file, it reads it, interpreting each line as defining +a new key binding or an editing configuration option. Since the emacs +keybindings are installed by default, if you want to use the +non-default vi editing mode, the most important item to go in this +file is the following line: + +.nf + edit-mode vi +.fi + +This will re-configure the default bindings for vi-mode. The +complete set of arguments that this command accepts are: +.sp +.nf + vi - Install key-bindings like those of the vi + editor. + emacs - Install key-bindings like those of the emacs + editor. This is the default. + none - Use just the native line editing facilities + provided by the terminal driver. +.fi +.sp +To prevent the terminal bell from being rung, such as when +an unrecognized control-sequence is typed, place the +following line in the configuration file: + +.nf + nobeep +.fi + +An example of a key binding line in the configuration file is +the following. + +.nf + bind M-[2~ insert-mode +.fi + +On many keyboards, the above key sequence is generated when one +presses the \f3insert\f1 key, so with this keybinding, one can toggle +between the emacs-mode insert and overwrite modes by hitting one +key. One could also do it by typing out the above sequence of +characters one by one. As explained above, the \f3M-\f1 part of this +sequence can be typed either by pressing the escape key before the +following key, or by pressing the Meta key at the same time as the +following key. Thus if you had set the above key binding, and the +insert key on your keyboard didn't generate the above key sequence, +you could still type it in either of the following 2 ways. + +.nf + 1. Hit the escape key momentarily, then press '[', then '2', then + finally '~'. + + 2. Press the meta key at the same time as pressing the '[' key, + then press '2', then '~'. +.fi + +If you set a keybinding for a key-sequence that is already bound to a function, +the new binding overrides the old one. If in the new binding you omit the name +of the new function to bind to the key-sequence, the original binding becomes +undefined. +.sp +Starting with versions of libtecla later than 1.3.3 it is now possible +to bind keysequences that begin with a printable character. Previously +key-sequences were required to start with a control or meta character. +.sp +Note that the special keywords "up", "down", "left" and "right" refer +to the arrow keys, and are thus not treated as keysequences. So, for +example, to rebind the up and down arrow keys to use the history +search mechanism instead of the simple history recall method, you +could place the following in your configuration file: + +.nf + bind up history-search-backwards + bind down history-search-backwards +.fi +.sp +To unbind an existing binding, you can do this with the bind command +by omitting to name any action to rebind the key sequence to. For +example, by not specifying an action function, the following command +unbinds the default beginning-of-line action from the ^A key sequence: + +.nf + bind ^A +.fi + +.SH ALTERNATE CONFIGURATION SOURCES + +As mentioned above, by default users have the option of configuring +the behavior of \f3gl_get_line()\f1 via a configuration file called +\f3\&.teclarc\f1 in their home directories. The fact that all +applications share this same configuration file is both an advantage +and a disadvantage. In most cases it is an advantage, since it +encourages uniformity, and frees the user from having to configure +each application separately. In some applications, however, this +single means of configuration is a problem. This is particularly true +of embedded software, where there's no filesystem to read a +configuration file from, and also in applications where a radically +different choice of keybindings is needed to emulate a legacy keyboard +interface. To cater for such cases, the following function allows the +application to control where configuration information is read from. + +.sp +.nf + int gl_configure_getline(GetLine *gl, + const char *app_string, + const char *app_file, + const char *user_file); +.fi +.sp + +It allows the configuration commands that would normally be read from +a user's \f3~/.teclarc\f1 file, to be read from any or none of, a +string, an application specific configuration file, and/or a +user-specific configuration file. If this function is called before +the first call to \f3gl_get_line()\f1, the default behavior of +reading \f3~/.teclarc\f1 on the first call to \f3gl_get_line()\f1 is +disabled, so all configuration must be achieved using the +configuration sources specified with this function. + +If \f3app_string != NULL\f1, then it is interpreted as a string +containing one or more configuration commands, separated from each +other in the string by embedded newline characters. If \f3app_file != +NULL\f1 then it is interpreted as the full pathname of an +application-specific configuration file. If \f3user_file != NULL\f1 +then it is interpreted as the full pathname of a user-specific +configuration file, such as \f3~/.teclarc\f1. For example, in the +following call, + + gl_configure_getline(gl, "edit-mode vi \\n nobeep", + "/usr/share/myapp/teclarc", + "~/.teclarc"); + +the \f3app_string\f1 argument causes the calling application to start +in vi edit-mode, instead of the default emacs mode, and turns off the +use of the terminal bell by the library. It then attempts to read +system-wide configuration commands from an optional file called +\f3/usr/share/myapp/teclarc\f1, then finally reads user-specific +configuration commands from an optional \f3\&.teclarc\f1 file in the +user's home directory. Note that the arguments are listed in ascending +order of priority, with the contents of \f3app_string\f1 being +potentially overriden by commands in \f3app_file\f1, and commands in +\f3app_file\f1 potentially being overriden by commands in +\f3user_file\f1. +.sp +You can call this function as many times as needed, the results being +cumulative, but note that copies of any filenames specified via the +\f3app_file\f1 and \f3user_file\f1 arguments are recorded internally +for subsequent use by the \f3read-init-files\f1 key-binding function, +so if you plan to call this function multiple times, be sure that the +last call specifies the filenames that you want re-read when the user +requests that the configuration files be re-read. + +.SH FILENAME AND TILDE COMPLETION + +With the default key bindings, pressing the TAB key (aka. ^I) results +in \f3gl_get_line()\f1 attempting to complete the incomplete filename +that precedes the cursor. \f3gl_get_line()\f1 searches backwards from +the cursor, looking for the start of the filename, stopping when it +hits either a space or the start of the line. If more than one file +has the specified prefix, \f3gl_get_line()\f1 completes the filename +up to the point at which the ambiguous matches start to differ, then +lists the possible matches. +.sp +In addition to literally written filenames, \f3gl_get_line()\f1 can +complete files that start with \f3~/\f1 and \f3~user/\f1 expressions +and that contain \f3$envvar\f1 expressions. In particular, if you hit +TAB within an incomplete \f3~user\f1, expression, \f3gl_get_line()\f1 +will attempt to complete the username, listing any ambiguous matches. +.sp +The completion binding is implemented using the +\f3cpl_word_completions()\f1 function, which is also available +separately to users of this library. See the +\f3cpl_word_completions(3)\f1 man page for more details. + +.SH CUSTOMIZED WORD COMPLETION + +If in your application, you would like to have TAB completion complete +other things in addition to or instead of filenames, you can arrange +this by registering an alternate completion callback function, via a +call to the \f3gl_customize_completion()\f1 function. +.sp +.nf + int gl_customize_completion(GetLine *gl, void *data, + CplMatchFn *match_fn); +.fi +.sp +The \f3data\f1 argument provides a way for your application to pass +arbitrary, application-specific information to the callback +function. This is passed to the callback every time that it is +called. It might for example, point to the symbol table from which +possible completions are to be sought. The \f3match_fn\f1 argument +specifies the callback function to be called. The \f3CplMatchFn\f1 +function type is defined in \f3libtecla.h\f1, as is a +\f3CPL_MATCH_FN()\f1 macro that you can use to declare and prototype +callback functions. The declaration and responsibilities of callback +functions are described in depth in the \f1cpl_complete_word(3)\f1 man +page. +.sp +In brief, the callback function is responsible for looking backwards +in the input line, back from the point at which the user pressed TAB, +to find the start of the word being completed. It then must lookup +possible completions of this word, and record them one by one in the +\f3WordCompletion\f1 object that is passed to it as an argument, by +calling the \f3cpl_add_completion()\f1 function. If the callback +function wishes to provide filename completion in addition to its own +specific completions, it has the option of itself calling the builtin +file-name completion callback. This also, is documented in the +\f3cpl_complete_word(3)\f1 man page. +.sp +Note that if you would like \f3gl_get_line()\f1 to return the current +input line when a successful completion is been made, you can arrange +this when you call \f3cpl_add_completion()\f1, by making the last +character of the continuation suffix a newline character. If you do +this, the input line will be updated to display the completion, +together with any contiuation suffix up to the newline character, then +\f3gl_get_line()\f1 will return this input line. + +.SH FILENAME EXPANSION + +With the default key bindings, pressing \f3^X*\f1 causes +\f3gl_get_line()\f1 to expand the filename that precedes the cursor, +replacing \f3~/\f1 and \f3~user/\f1 expressions with the corresponding +home directories, and replacing \f3$envvar\f1 expressions with the +value of the specified environment variable, then if there are any +wildcards, replacing the so far expanded filename with a +space-separated list of the files which match the wild cards. +.sp +The expansion binding is implemented using the \f3ef_expand_file()\f1 function. +See the \f3ef_expand_file(3)\f1 man page for more details. + +.SH RECALLING PREVIOUSLY TYPED LINES + +Every time that a new line is entered by the user, it is appended to a +list of historical input lines maintained within the GetLine resource +object. You can traverse up and down this list using the up and down +arrow keys. Alternatively, you can do the same with the \f3^P\f1, and +\f3^N\f1 keys, and in vi command mode you can alternatively use the k +and j characters. Thus pressing up-arrow once, replaces the current +input line with the previously entered line. Pressing up-arrow again, +replaces this with the line that was entered before it, etc.. Having +gone back one or more lines into the history list, one can return to +newer lines by pressing down-arrow one or more times. If you do this +sufficient times, you will return to the original line that you were +entering when you first hit up-arrow. +.sp +Note that in vi mode, all of the history recall functions switch the +library into command mode. +.sp +In emacs mode the \f3M-p\f1 and \f3M-n\f1 keys work just like the +\f3^P\f1 and \f3^N\f1 keys, except that they skip all but those +historical lines which share the prefix that precedes the cursor. In +vi command mode the upper case \f3K\f1 and \f3J\f1 characters do the +same thing, except that the string that they search for includes the +character under the cursor as well as what precedes it. +.sp +Thus for example, suppose that you were in emacs mode, and you had +just entered the following list of commands in the order shown: + +.nf + ls ~/tecla/ + cd ~/tecla + ls -l getline.c + emacs ~/tecla/getline.c +.fi + +If you next typed: + +.nf + ls +.fi + +and then hit \f3M-p\f1, then rather than returning the previously +typed emacs line, which doesn't start with "ls", \f3gl_get_line()\f1 +would recall the "ls -l getline.c" line. Pressing \f3M-p\f1 again +would recall the "ls ~/tecla/" line. + +.SH HISTORY FILES + +To save the contents of the history buffer before quitting your +application, and subsequently restore them when you next start the +application, the following functions are provided. + +.sp +.nf + int gl_save_history(GetLine *gl, const char *filename, + const char *comment, int max_lines); + int gl_load_history(GetLine *gl, const char *filename, + const char *comment); +.fi +.sp + +The \f3filename\f1 argument specifies the name to give the history +file when saving, or the name of an existing history file, when +loading. This may contain home-directory and environment variable +expressions, such as "~/.myapp_history" or "$HOME/.myapp_history". +.sp +Along with each history line, extra information about it, such as when +it was entered by the user, and what its nesting level is, is recorded +as a comment preceding the line in the history file. Writing this as a +comment allows the history file to double as a command file, just in +case you wish to replay a whole session using it. Since comment +prefixes differ in different languages, the \f3comment\f1 argument is +provided for specifying the comment prefix. For example, if your +application were a unix shell, such as the bourne shell, you would +specify "#" here. Whatever you choose for the comment character, you +must specify the same prefix to \f3gl_load_history()\f1 that you used +when you called \f3gl_save_history()\f1 to write the history file. +.sp +The \f3max_lines\f1 must be either -1 to specify that all lines in the +history list be saved, or a positive number specifying a ceiling on +how many of the most recent lines should be saved. +.sp +Both fuctions return non-zero on error, after writing an error message +to stderr. Note that \f3gl_load_history()\f1 does not consider the +non-existence of a file to be an error. + +.SH MULTIPLE HISTORY LISTS + +If your application uses a single \f3GetLine\f1 object for entering +many different types of input lines, you may wish \f3gl_get_line()\f1 +to distinguish the different types of lines in the history list, and +only recall lines that match the current type of line. To support this +requirement, \f3gl_get_line()\f1 marks lines being recorded in the +history list with an integer identifier chosen by the application. +Initially this identifier is set to \f10\f3 by \f3new_GetLine()\f1, +but it can be changed subsequently by calling +\f3gl_group_history()\f1. + +.sp +.nf + int gl_group_history(GetLine *gl, unsigned id); +.fi +.sp + +The integer identifier \f3id\f1 can be any number chosen by the +application, but note that \f3gl_save_history()\f1 and +\f3gl_load_history()\f1 preserve the association between identifiers +and historical input lines between program invokations, so you should +choose fixed identifiers for the different types of input line used by +your application. +.sp +Whenever \f3gl_get_line()\f1 appends a new input line to the history +list, the current history identifier is recorded with it, and when it +is asked to recall a historical input line, it only recalls lines that +are marked with the current identifier. + +.SH DISPLAYING HISTORY + +The history list can be displayed by calling \f3gl_show_history()\f1. + +.sp +.nf + int gl_show_history(GetLine *gl, FILE *fp, + const char *fmt, + int all_groups, + int max_lines); +.fi +.sp + +This displays the current contents of the history list to the stdio +output stream \f3fp\f1. If the \f3max_lines\f1 argument is greater +than or equal to zero, then no more than this number of the most +recent lines will be displayed. If the \f3all_groups\f1 argument is +non-zero, lines from all history groups are displayed. Otherwise just +those of the currently selected history group are displayed. The +format string argument, \f3fmt\f1, determines how the line is +displayed. This can contain arbitrary characters which are written +verbatim, interleaved with any of the following format directives: + +.nf + %D - The date on which the line was originally + entered, formatted like 2001-11-20. + %T - The time of day when the line was entered, + formatted like 23:59:59. + %N - The sequential entry number of the line in + the history buffer. + %G - The number of the history group which the + line belongs to. + %% - A literal % character. + %H - The history line itself. +.fi + +Thus a format string like \f3"%D %T %H\n"\f1 would output something like: + +.nf + 2001-11-20 10:23:34 Hello world +.fi + +Note the inclusion of an explicit newline character in the format +string. + +.SH LOOKING UP HISTORY + +The \f3gl_lookup_history()\f1 function allows the calling application +to look up lines in the history list. + +.sp +.nf + typedef struct { + const char *line; /* The requested historical */ + /* line. */ + unsigned group; /* The history group to which */ + /* the line belongs. */ + time_t timestamp; /* The date and time at which */ + /* the line was originally */ + /* entered. */ + } GlHistoryLine; + + int gl_lookup_history(GetLine *gl, unsigned long id, + GlHistoryLine *hline); +.fi +.sp + +The \f3id\f1 argument indicates which line to look up, where the first +line that was entered in the history list after \f3new_GetLine()\f1 +was called, is denoted by 0, and subsequently entered lines are +denoted with successively higher numbers. Note that the range of lines +currently preserved in the history list can be queried by calling the +\f3gl_range_of_history()\f1 function, described later. If the +requested line is in the history list, the details of the line are +recorded in the variable pointed to by the \f3hline\f1 argument, and +\f31\f1 is returned. Otherwise \f30\f1 is returned, and the variable +pointed to by \f3hline\f1 is left unchanged. +.sp +Beware that the string returned in \f3hline->line\f1 is part of the +history buffer, so it must not be modified by the caller, and will be +recycled on the next call to any function that takes \f3gl\f1 as its +argument. Therefore you should make a private copy of this string if +you need to keep it around. + +.SH MISCELLANEOUS HISTORY CONFIGURATION + +If you wish to change the size of the history buffer that was +originally specified in the call to \f3new_GetLine()\f1, you can do so +with the \f3gl_resize_history()\f1 function. + +.sp +.nf + int gl_resize_history(GetLine *gl, size_t histlen); +.fi +.sp + +The \f3histlen\f1 argument specifies the new size in bytes, and if you +specify this as 0, the buffer will be deleted. +.sp +As mentioned in the discussion of \f3new_GetLine()\f1, the number of +lines that can be stored in the history buffer, depends on the lengths +of the individual lines. For example, a 1000 byte buffer could equally +store 10 lines of average length 100 bytes, or 2 lines of average +length 50 bytes. Although the buffer is never expanded when new lines +are added, a list of pointers into the buffer does get expanded when +needed to accomodate the number of lines currently stored in the +buffer. To place an upper limit on the number of lines in the buffer, +and thus a ceiling on the amount of memory used in this list, you can +call the \f3gl_limit_history()\f1 function. + +.sp +.nf + void gl_limit_history(GetLine *gl, int max_lines); +.fi +.sp + +The \f3max_lines\f1 should either be a positive number \f3>= 0\f1, +specifying an upper limit on the number of lines in the buffer, or be +\f3-1\f1 to cancel any previously specified limit. When a limit is in +effect, only the \f3max_lines\f1 most recently appended lines are kept +in the buffer. Older lines are discarded. +.sp +To discard lines from the history buffer, use the +\f3gl_clear_history()\f1 function. +.sp +.nf + void gl_clear_history(GetLine *gl, int all_groups); +.fi +.sp +The \f3all_groups\f1 argument tells the function whether to delete +just the lines associated with the current history group (see +\f3gl_group_history()\f1), or all historical lines in the buffer. +.sp +The \f3gl_toggle_history()\f1 function allows you to toggle history on +and off without losing the current contents of the history list. + +.sp +.nf + void gl_toggle_history(GetLine *gl, int enable); +.fi +.sp + +Setting the \f3enable\f1 argument to 0 turns off the history +mechanism, and setting it to 1 turns it back on. When history is +turned off, no new lines will be added to the history list, and +history lookup key-bindings will act as though there is nothing in the +history buffer. + +.SH QUERYING HISTORY INFORMATION + +The configured state of the history list can be queried with the +\f3gl_history_state()\f1 function. + +.sp +.nf + typedef struct { + int enabled; /* True if history is enabled */ + unsigned group; /* The current history group */ + int max_lines; /* The current upper limit on the */ + /* number of lines in the history */ + /* list, or -1 if unlimited. */ + } GlHistoryState; + + void gl_state_of_history(GetLine *gl, + GlHistoryState *state); +.fi +.sp +On return, the status information is recorded in the variable pointed +to by the \f3state\f1 argument. +.sp +The \f3gl_range_of_history()\f1 function returns the number and +range of lines in the history list. + +.sp +.nf +typedef struct { + unsigned long oldest; /* The sequential entry number */ + /* of the oldest line in the */ + /* history list. */ + unsigned long newest; /* The sequential entry number */ + /* of the newest line in the */ + /* history list. */ + int nlines; /* The number of lines in the */ + /* history list. */ +} GlHistoryRange; + +void gl_range_of_history(GetLine *gl, GlHistoryRange *range); +.fi +.sp +The return values are recorded in the variable pointed to by the +\f3range\f1 argument. If the \f3nlines\f1 member of this structure is +greater than zero, then the \f3oldest\f1 and \f3newest\f1 members +report the range of lines in the list, and \f3newest=oldest+nlines-1\f1. +Otherwise they are both zero. +.sp +The \f3gl_size_of_history()\f1 function returns the total size of the +history buffer and the amount of the buffer that is currently +occupied. +.sp +.nf + typedef struct { + size_t size; /* The size of the history buffer */ + /* (bytes). */ + size_t used; /* The number of bytes of the */ + /* history buffer that are */ + /* currently occupied. */ + } GlHistorySize; + + void gl_size_of_history(GetLine *gl, GlHistorySize *size); +.fi +.sp +On return, the size information is recorded in the variable pointed to +by the \f3size\f1 argument. + +.SH CHANGING TERMINALS + +The \f3new_GetLine()\f1 constructor function assumes that input is to +be read from \f3stdin\f1, and output written to \f3stdout\f1. The +following function allows you to switch to different input and output +streams. +.sp +.nf + int gl_change_terminal(GetLine *gl, FILE *input_fp, + FILE *output_fp, const char *term); +.fi +.sp +The \f3gl\f1 argument is the object that was returned by +\f3new_GetLine()\f1. The \f3input_fp\f1 argument specifies the stream +to read from, and \f3output_fp\f1 specifies the stream to be written +to. Only if both of these refer to a terminal, will interactive +terminal input be enabled. Otherwise \f3gl_get_line()\f1 will simply +call \f3fgets()\f1 to read command input. If both streams refer to a +terminal, then they must refer to the same terminal, and the type of +this terminal must be specified via the \f3term\f1 argument. The value +of the \f3term\f1 argument is looked up in the terminal information +database (terminfo or termcap), in order to determine which special +control sequences are needed to control various aspects of the +terminal. \f3new_GetLine()\f1 for example, passes the return value of +\f3getenv("TERM")\f1 in this argument. Note that if one or both of +\f3input_fp\f1 and \f3output_fp\f1 don't refer to a terminal, then it +is legal to pass \f3NULL\f1 instead of a terminal type. +.sp +Note that if you want to pass file descriptors to +\f3gl_change_terminal()\f1, you can do this by creating stdio stream +wrappers using the POSIX \f3fdopen()\f1 function. + +.SH EXTERNAL EVENT HANDLING + +While \f3gl_get_line()\f1 is waiting for keyboard input from the user, +you can ask it to also watch for activity on arbitrary file +descriptors, such as network sockets, pipes etc, and have it call +functions of your choosing when activity is seen. This works on any +system that has the \f3select()\f1 system call, which is most, if not +all flavors of unix. Registering a file descriptor to be watched by +\f3gl_get_line()\f1 involves calling the \f3gl_watch_fd()\f1 function. + +.sp +.nf + int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event, + GlFdEventFn *callback, void *data); +.fi +.sp + +If this returns non-zero, then it means that either your arguments are +invalid, or that this facility isn't supported on the host system. +.sp +The \f3fd\f1 argument is the file descriptor to be watched. The +\f3event\f1 argument specifies what type of activity is of interest, +chosen from the following enumerated values: + +.sp +.nf + GLFD_READ - Watch for the arrival of data to be read. + GLFD_WRITE - Watch for the ability to write to the file + descriptor without blocking. + GLFD_URGENT - Watch for the arrival of urgent + out-of-band data on the file descriptor. +.fi +.sp + +The \f3callback\f1 argument is the function to call when the selected +activity is seen. It should be defined with the following macro, which +is defined in libtecla.h. + +.sp +.nf + #define GL_FD_EVENT_FN(fn) GlFdStatus (fn)(GetLine *gl, \\ + void *data, int fd, \\ + GlFdEvent event) +.fi +.sp +The \f3data\f1 argument of the \f3gl_watch_fd()\f1 function is passed +to the callback function for its own use, and can point to anything +you like, including \f3NULL\f1. The file descriptor and the event +argument are also passed to the callback function, and this +potentially allows the same callback function to be registered to more +than one type of event and/or more than one file descriptor. The +return value of the callback function should be one of the following +values. + +.sp +.nf + GLFD_ABORT - Tell gl_get_line() to abort with an + error (errno won't be set, so set it + appropriately yourself if you need it). + GLFD_REFRESH - Redraw the input line then continue + waiting for input. Return this if + your callback wrote to the terminal. + GLFD_CONTINUE - Continue to wait for input, without + redrawing the line. +.fi +.sp +Note that before calling the callback, \f3gl_get_line()\f1 blocks most +signals, and leaves its own signal handlers installed, so if you need +to catch a particular signal you will need to both temporarily install +your own signal handler, and unblock the signal. Be sure to re-block +the signal (if it was originally blocked) and reinstate the original +signal handler, if any, before returning. +.sp +Your callback shouldn't try to read from the terminal, which is left +in raw mode as far as input is concerned. You can however write to the +terminal as usual, since features like conversion of newline to +carriage-return/linefeed are re-enabled while the callback is +running. If your callback function does write to the terminal, be sure +to output a newline first, and when your callback returns, tell +\f3gl_get_line()\f1 that the input line needs to be redrawn, by +returning the \f3GLFD_REFRESH\f1 status code. +.sp +To remove a callback function that you previously registered for a +given file descriptor and event, simply call \f3gl_watch_fd()\f1 with +the same file descriptor and \f3event\f1 arguments, but with a +\f3callback\f1 argument of \f30\f1. The \f3data\f1 argument is ignored +in this case. + +.SH SIGNAL HANDLING DEFAULTS + +By default, the \f3gl_get_line()\f1 function intercepts a +number of signals. This is particularly important for +signals which would by default terminate the process, since +the terminal needs to be restored to a usable state before +this happens. In this section, the signals that are trapped +by default, and how gl_get_line() responds to them, is +described. Changing these defaults is the topic of the +following section. +.sp +When the following subset of signals are caught, \f3gl_get_line()\f1 +first restores the terminal settings and signal handling to how they +were before \f3gl_get_line()\f1 was called, resends the signal, to +allow the calling application's signal handlers to handle it, then if +the process still exists, \f3gl_get_line()\f1 returns \f3NULL\f1 and +sets \f3errno\f1 as specified below. + +.sp +.nf + SIGINT - This signal is generated both by the keyboard + interrupt key (usually ^C), and the keyboard + break key. + + errno=EINTR + + SIGHUP - This signal is generated when the controlling + terminal exits. + + errno=ENOTTY + + SIGPIPE - This signal is generated when a program attempts + to write to a pipe who's remote end isn't being + read by any process. This can happen for example + if you have called \f3gl_change_terminal()\f1 to + redirect output to a pipe hidden under a pseudo + terminal. + + errno=EPIPE + + SIGQUIT - This signal is generated by the keyboard quit + key (usually ^\\). + + errno=EINTR + + SIGABRT - This signal is generated by the standard C, + abort() function. By default it both + terminates the process and generates a core + dump. + + errno=EINTR + + SIGTERM - This is the default signal that the UN*X + kill command sends to processes. + + errno=EINTR +.fi +.sp +Note that in the case of all of the above signals, POSIX mandates that +by default the process is terminated, with the addition of a core dump +in the case of the \f3SIGQUIT\f1 signal. In other words, if the +calling application doesn't override the default handler by supplying +its own signal handler, receipt of the corresponding signal will +terminate the application before \f3gl_get_line()\f1 returns. +.sp +If gl_get_line() aborts with errno set to EINTR, you can find out what +signal caused it to abort, by calling the following function. +.sp +.nf + int gl_last_signal(const GetLine *gl); +.fi +.sp +This returns the numeric code (eg. \f3SIGINT\f1) of the last signal +that was received during the most recent call to \f3gl_get_line()\f1, +or \f3-1\f1 if no signals were received. +.sp +On systems that support it, when a SIGWINCH (window change) signal is +received, \f3gl_get_line()\f1 queries the terminal to find out its new +size, redraws the current input line to accomodate the new size, then +returns to waiting for keyboard input from the user. Unlike other +signals, this signal isn't resent to the application. +.sp +Finally, the following signals cause \f3gl_get_line()\f1 to first +restore the terminal and signal environment to that which prevailed +before \f3gl_get_line()\f1 was called, then resend the signal to the +application. If the process still exists after the signal has been +delivered, then \f3gl_get_line()\f1 then re-establishes its own signal +handlers, switches the terminal back to raw mode, redisplays the input +line, and goes back to awaiting terminal input from the user. +.sp +.nf + SIGCONT - This signal is generated when a suspended + process is resumed. + + SIGPWR - This signal is generated when a power failure + occurs (presumably when the system is on a + UPS). + + SIGALRM - This signal is generated when a timer + expires. + + SIGUSR1 - An application specific signal. + + SIGUSR2 - Another application specific signal. + + SIGVTALRM - This signal is generated when a virtual + timer expires (see man setitimer(2)). + + SIGXCPU - This signal is generated when a process + exceeds its soft CPU time limit. + + SIGTSTP - This signal is generated by the terminal + suspend key, which is usually ^Z, or the + delayed terminal suspend key, which is + usually ^Y. + + SIGTTIN - This signal is generated if the program + attempts to read from the terminal while the + program is running in the background. + + SIGTTOU - This signal is generated if the program + attempts to write to the terminal while the + program is running in the background. +.fi +.sp + +Obviously not all of the above signals are supported on all systems, +so code to support them is conditionally compiled into the tecla +library. +.sp +Note that if \f3SIGKILL\f1, which by definition can't be caught, or +any of the hardware generated exception signals, such as +\f3SIGSEGV\f1, \f3SIGBUS\f1 and \f3SIGFPE\f1, are received and +unhandled while \f3gl_get_line()\f1 has the terminal in raw mode, the +program will be terminated without the terminal having been restored +to a usable state. In practice, job-control shells usually reset the +terminal settings when a process relinquishes the controlling +terminal, so this is only a problem with older shells. + +.SH CUSTOMIZED SIGNAL HANDLING + +The previous section listed the signals that +\f3gl_get_line()\f1 traps by default, and described how it +responds to them. This section describes how to both add and +remove signals from the list of trapped signals, and how to +specify how \f3gl_get_line()\f1 should respond to a given +signal. +.sp +If you don't need \f3gl_get_line()\f1 to do anything in +response to a signal that it normally traps, you can tell to +\f3gl_get_line()\f1 to ignore that signal by calling +\f3gl_ignore_signal()\f1. +.sp +.nf + int gl_ignore_signal(GetLine *gl, int signo); +.fi +.sp +The \f3signo\f1 argument is the number of the signal +(eg. \f3SIGINT\f1) that you want to have ignored. If the +specified signal isn't currently one of those being trapped, +this function does nothing. +.sp +The \f3gl_trap_signal()\f1 function allows you to either add +a new signal to the list that \f3gl_get_line()\f1 traps, or +modify how it responds to a signal that it already traps. +.sp +.nf + int gl_trap_signal(GetLine *gl, int signo, unsigned flags, + GlAfterSignal after, int errno_value); +.fi +.sp +The \f3signo\f1 argument is the number of the signal that +you wish to have trapped. The \f3flags\f1 argument is a set +of flags which determine the environment in which the +application's signal handler is invoked, the \f3after\f1 +argument tells \f3gl_get_line()\f1 what to do after the +application's signal handler returns, and \f3errno_value\f1 +tells \f3gl_get_line()\f1 what to set \f3errno\f1 to if told +to abort. +.sp +The \f3flags\f1 argument is a bitwise OR of zero or more of +the following enumerators: +.sp +.nf + GLS_RESTORE_SIG - Restore the caller's signal + environment while handling the + signal. + + GLS_RESTORE_TTY - Restore the caller's terminal settings + while handling the signal. + + GLS_RESTORE_LINE - Move the cursor to the start of the + line following the input line before + invoking the application's signal + handler. + + GLS_REDRAW_LINE - Redraw the input line when the + application's signal handler returns. + + GLS_UNBLOCK_SIG - Normally, if the calling program has + a signal blocked (man sigprocmask), + gl_get_line() does not trap that + signal. This flag tells gl_get_line() + to trap the signal and unblock it for + the duration of the call to + gl_get_line(). + + GLS_DONT_FORWARD - If this flag is included, the signal + will not be forwarded to the signal + handler of the calling program. +.fi +.sp +Two commonly useful flag combinations are also enumerated as +follows: +.sp +.nf + GLS_RESTORE_ENV = GLS_RESTORE_SIG | GLS_RESTORE_TTY | + GLS_REDRAW_LINE + + GLS_SUSPEND_INPUT = GLS_RESTORE_ENV | GLS_RESTORE_LINE +.fi +.sp + +If your signal handler, or the default system signal +handler for this signal, if you haven't overriden it, never +either writes to the terminal, nor suspends or terminates +the calling program, then you can safely set the \f3flags\f1 +argument to \f30\f1. +.sp +If your signal handler always writes to the terminal, reads +from it, or suspends or terminates the program, you should +specify the \f3flags\f1 argument as \f3GL_SUSPEND_INPUT\f1, +so that: +.sp +.nf +1. The cursor doesn't get left in the middle of the input + line. +2. So that the user can type in input and have it echoed. +3. So that you don't need to end each output line with + \f3\\r\\n\f1, instead of just \f3\\n\f1. +.fi +.sp +The \f3GL_RESTORE_ENV\f1 combination is the same as +\f3GL_SUSPEND_INPUT\f1, except that it doesn't move the +cursor, and if your signal handler doesn't read or write +anything to the terminal, the user won't see any visible +indication that a signal was caught. This can be useful if +you have a signal handler that only occasionally writes to +the terminal, where using \f3GL_SUSPEND_LINE\f1 would cause +the input line to be unnecessarily duplicated when nothing +had been written to the terminal. Such a signal handler, +when it does write to the terminal, should be sure to start +a new line at the start of its first write, by writing a +'\\n' character, and should be sure to leave the cursor on a +new line before returning. If the signal arrives while the +user is entering a line that only occupies a signal terminal +line, or if the cursor is on the last terminal line of a +longer input line, this will have the same effect as +\f3GL_SUSPEND_INPUT\f1. Otherwise it will start writing on a +line that already contains part of the displayed input line. +This doesn't do any harm, but it looks a bit ugly, which is +why the \f3GL_SUSPEND_INPUT\f1 combination is better if you +know that you are always going to be writting to the +terminal. +.sp +The \f3after\f1 argument, which determines what +\f3gl_get_line()\f1 does after the application's signal +handler returns (if it returns), can take any one of the +following values: +.sp +.nf + GLS_RETURN - Return the completed input line, just as + though the user had pressed the return + key. + + GLS_ABORT - Cause gl_get_line() to return \f3NULL\f1. + + GLS_CONTINUE - Resume command line editing. +.fi +.sp +The \f3errno_value\f1 argument is intended to be combined +with the \f3GLS_ABORT\f1 option, telling \f3gl_get_line()\f1 +what to set the standard \f3errno\f1 variable to before +returning \f3NULL\f1 to the calling program. It can also, +however, be used with the \f3GL_RETURN\f1 option, in case +you wish to have a way to distinguish between an input line +that was entered using the return key, and one that was +entered by the receipt of a signal. + +.SH THE TERMINAL SIZE + +On most systems the combination of the \f3TIOCGWINSZ\f1 ioctl and the +\f3SIGWINCH\f1 signal is used to maintain an accurate idea of the +terminal size. The terminal size is newly queried every time that +\f3gl_get_line()\f1 is called and whenever a \f3SIGWINCH\f1 signal is +received. +.sp +On the few systems where this mechanism isn't available, at +startup \f3new_GetLine()\f1 first looks for the \f3LINES\f1 +and \f3COLUMNS\f1 environment variables. If these aren't +found, or they contain unusable values, then if a terminal +information database like terminfo or termcap is available, +the default size of the terminal is looked up in this +database. If this too fails to provide the terminal size, a +default size of 80 columns by 24 lines is used. If this +default isn't appropriate for your system, +\f3gl_terminal_size()\f1 can be used to supply a different +fallback. +.sp +The \f3gl_terminal_size()\f1 function allows you to query +the current size of the terminal, and install an alternate +fallback size for cases where the size isn't available. +Beware that the terminal size won't be available if reading +from a pipe or a file, so the default values can be +important even on systems that do support ways of finding +out the terminal size. +.sp +.nf + typedef struct { + int nline; /* The terminal has nline lines */ + int ncolumn; /* The terminal has ncolumn columns */ + } GlTerminalSize; + + GlTerminalSize gl_terminal_size(GetLine *gl, + int def_ncolumn, + int def_nline); +.fi +.sp +This function first updates \f3gl_get_line()\f1's idea of +the terminal size, then records its findings in the return +value. +.sp +The \f3def_ncolumn\f1 and \f3def_nline\f1 specify the +default number of terminal columns and lines to use if the +terminal size can't be determined. + +.SH HIDING WHAT YOU TYPE + +When entering sensitive information, such as passwords, it is best not +to have the text that you are entering echoed on the terminal. +Furthermore, such text should not be recorded in the history list, +since somebody finding your terminal unattended could then recall it, +or somebody snooping through your directories could see it in your +history file. With this in mind, the \f3gl_echo_mode()\f1 +function allows you to toggle on and off the display and archival of +any text that is subsequently entered in calls to \f3gl_get_line()\f1. + +.sp +.nf + int gl_echo_mode(GetLine *gl, int enable); +.fi +.sp + +The \f3enable\f1 argument specifies whether entered text +should be visible or not. If it is \f30\f1, then +subsequently entered lines will not be visible on the +terminal, and will not be recorded in the history list. If +it is \f31\f1, then subsequent input lines will be displayed +as they are entered, and provided that history hasn't been +turned off via a call to \f3gl_toggle_history()\f1, then +they will also be archived in the history list. Finally, if +the \f3enable\f1 argument is \f3-1\f1, then the echoing mode +is left unchanged, which allows you to non-destructively +query the current setting via the return value. In all +cases, the return value of the function is \f30\f1 if +echoing was disabled before the function was called, and +\f31\f1 if it was enabled. +.sp +When echoing is turned off, note that although tab +completion will invisibly complete your prefix as far as +possible, ambiguous completions will not be displayed. + +.SH CALLBACK FUNCTION FACILITIES + +Unless otherwise stated, callback functions, such as tab +completion callbacks and event callbacks should not call any +functions in this module. The following functions, however, +are designed specifically to be used by callback functions. +.sp +Calling the \f3gl_replace_prompt()\f1 function from a +callback tells \f3gl_get_line() to display a different +prompt when the callback returns. It has no effect if called +when \f3gl_get_line()\f1 is not being called. +.sp +.nf + void gl_replace_prompt(GetLine *gl, const char *prompt); +.fi +.sp + +.SH INTERNATIONAL CHARACTER SETS + +Since libtecla version 1.4.0, \f3gl_get_line()\f1 has been 8-bit +clean. This means that all 8-bit characters that are printable in the +user's current locale are now displayed verbatim and included in the +returned input line. Assuming that the calling program correctly +contains a call like the following, +.sp +.nf + setlocale(LC_CTYPE, ""); +.fi +.sp +then the current locale is determined by the first of the environment +variables \f3LC_CTYPE\f1, \f3LC_ALL\f1, and \f3LANG\f1, that is found +to contain a valid locale name. If none of these variables are +defined, or the program neglects to call setlocale, then the default +\f3C\f1 locale is used, which is US 7-bit ASCII. On most unix-like +platforms, you can get a list of valid locales by typing the command: +.sp +.nf + locale -a +.fi +.sp +at the shell prompt. +.sp +.SS "Meta keys and locales" + +Beware that in most locales other than the default C locale, meta +characters become printable, and they are then no longer considered to +match \f3M-c\f1 style key bindings. This allows international +characters to be entered with the compose key without unexpectedly +triggering meta key bindings. You can still invoke meta bindings, +since there are actually two ways to do this. For example the binding +\f3M-c\f1 can also be invoked by pressing the escape key momentarily, +then pressing the \f3c\f1 key, and this will work regardless of +locale. Moreover, many modern terminal emulators, such as gnome's +gnome-terminal's and KDE's konsole terminals, already generate escape +pairs like this when you use the meta key, rather than a real meta +character, and other emulators usually have a way to request this +behavior, so you can continue to use the meta key on most systems. +.sp +For example, although xterm terminal emulators generate real 8-bit +meta characters by default when you use the meta key, they can be +configured to output the equivalent escape pair by setting their +\f3EightBitInput\f1 X resource to \f3False\f1. You can either do this +by placing a line like the following in your \f3~/.Xdefaults\f1 file, +.sp +.nf + XTerm*EightBitInput: False +.sp +.fi +or by starting an xterm with an \f3-xrm '*EightBitInput: False'\f1 +command-line argument. In recent versions of xterm you can toggle this +feature on and off with the \f3"Meta Sends Escape"\f1 option in the +menu that is displayed when you press the left mouse button and the +control key within an xterm window. In CDE, dtterms can be similarly +coerced to generate escape pairs in place of meta characters, by +setting the \f3Dtterm*KshMode\f1 resource to \f3True\f1. +.sp +.SS "Entering international characters" + +If you don't have a keyboard that generates all of the international +characters that you need, there is usually a compose key that will +allow you to enter special characters, or a way to create one. For +example, under X windows on unix-like systems, if your keyboard +doesn't have a compose key, you can designate a redundant key to serve +this purpose with the xmodmap command. For example, on many PC +keyboards there is a microsoft-windows key, which is otherwise useless +under Linux. On my PC the \f3xev\f1 program reports that pressing this +key generates keycode 115, so to turn this key into a compose key, I +do the following: +.sp +.nf + xmodmap -e 'keycode 115 = Multi_key' +.fi +.sp +I can then enter an i with a umlaut over it by typing this key, +followed by \f3"\f1, followed by i. + +.SH THREAD SAFETY + +In a multi-threaded program, you should use the libtecla_r.a version +of the library. This uses reentrant versions of system functions, +where available. Unfortunately neither terminfo nor termcap were +designed to be reentrant, so you can't safely use the functions of the +getline module in multiple threads (you can use the separate +file-expansion and word-completion modules in multiple threads, see +the corresponding man pages for details). However due to the use of +POSIX reentrant functions for looking up home directories etc, it is +safe to use this module from a single thread of a multi-threaded +program, provided that your other threads don't use any termcap or +terminfo functions. + +.SH FILES +.nf +libtecla.a - The tecla library +libtecla.h - The tecla header file. +~/.teclarc - The personal tecla customization file. +.fi + +.SH SEE ALSO +libtecla(3), ef_expand_file(3), cpl_complete_word(3), pca_lookup_file(3) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) diff --git a/libtecla-1.4.1/man3/gl_group_history.3 b/libtecla-1.4.1/man3/gl_group_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_group_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_ignore_signal.3 b/libtecla-1.4.1/man3/gl_ignore_signal.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_ignore_signal.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_last_signal.3 b/libtecla-1.4.1/man3/gl_last_signal.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_last_signal.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_limit_history.3 b/libtecla-1.4.1/man3/gl_limit_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_limit_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_load_history.3 b/libtecla-1.4.1/man3/gl_load_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_load_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_lookup_history.3 b/libtecla-1.4.1/man3/gl_lookup_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_lookup_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_prompt_style.3 b/libtecla-1.4.1/man3/gl_prompt_style.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_prompt_style.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_range_of_history.3 b/libtecla-1.4.1/man3/gl_range_of_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_range_of_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_resize_history.3 b/libtecla-1.4.1/man3/gl_resize_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_resize_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_save_history.3 b/libtecla-1.4.1/man3/gl_save_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_save_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_show_history.3 b/libtecla-1.4.1/man3/gl_show_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_show_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_size_of_history.3 b/libtecla-1.4.1/man3/gl_size_of_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_size_of_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_state_of_history.3 b/libtecla-1.4.1/man3/gl_state_of_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_state_of_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_terminal_size.3 b/libtecla-1.4.1/man3/gl_terminal_size.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_terminal_size.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_toggle_history.3 b/libtecla-1.4.1/man3/gl_toggle_history.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_toggle_history.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_trap_signal.3 b/libtecla-1.4.1/man3/gl_trap_signal.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_trap_signal.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/gl_watch_fd.3 b/libtecla-1.4.1/man3/gl_watch_fd.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/gl_watch_fd.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/libtecla.3 b/libtecla-1.4.1/man3/libtecla.3 new file mode 100644 index 0000000..611eb57 --- /dev/null +++ b/libtecla-1.4.1/man3/libtecla.3 @@ -0,0 +1,160 @@ +.\" Copyright (C) 2000, 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH libtecla 3 +.SH NAME +libtecla - An interactive command-line input library. +.SH SYNOPSIS +.nf +gcc ... -ltecla -lcurses +.fi + +.SH DESCRIPTION + +The \f3tecla\f1 library provides programs with interactive command +line editing facilities, similar to those of the unix \f3tcsh\f1 +shell. In addition to simple command-line editing, it supports recall +of previously entered command lines, TAB completion of file names or +other tokens, and in-line wild-card expansion of filenames. The +internal functions which perform file-name completion and wild-card +expansion are also available externally for optional use by the +calling program. +.sp +The various parts of the library are documented in the following man +pages: + +.nf + gl_get_line(3) - The interactive line-input module. + cpl_complete_word(3) - The word completion module. + ef_expand_file(3) - The filename expansion module. + pca_lookup_file(3) - A directory-list based filename + lookup and completion module. +.fi + +In addition there is one optional application distributed +with the library: + +.nf + enhance(3) - Add command-line editing to third + party applications. +.fi + +.SH THREAD SAFETY + +If the library is compiled with -D_POSIX_C_SOURCE=199506L, reentrant +versions of as many functions as possible are used. This includes +using getpwuid_r() and getpwnam_r() instead of getpwuid() and +getpwnam() when looking up the home directories of specific users in +the password file (for ~user/ expansion), and readdir_r() instead of +readdir() for reading directory entries when doing filename +completion. The reentrant version of the library is usually called +libtecla_r.a instead of libtecla.a, so if only the latter is +available, it probably isn't the correct version to link with +threaded programs. + +Reentrant functions for iterating through the password file aren't +available, so when the library is compiled to be reentrant, TAB +completion of incomplete usernames in \f3~username/\f1 expressions is +disabled. This doesn't disable expansion of complete \f3~username\f1 +expressions, which can be done reentrantly, or expansion of the parts +of filenames that follow them, so this doesn't remove much +functionality. + +The terminfo functions setupterm(), tigetstr(), tigetnum() and tputs() +also aren't reentrant, but very few programs will want to interact +with multiple terminals, so this shouldn't prevent this library from +being used in threaded programs. + +.SH LIBRARY VERSION NUMBER + +The version number of the library can be queried using the following +function. +.sp +.nf + void libtecla_version(int *major, int *minor, int *micro); +.fi +.sp + +On return, this function records the three components of the libtecla +version number in \f3*major\f1, \f3*minor\f1, \f3*micro\f1. The formal +meaning of the three components is as follows. + +.sp +.nf + major - Incrementing this number implies that a change has + been made to the library's public interface, which + makes it binary incompatible with programs that + were linked with previous shared versions of the + tecla library. + + minor - This number is incremented by one whenever + additional functionality, such as new functions or + modules, are added to the library. + + micro - This is incremented whenever modifications to the + library are made which make no changes to the + public interface, but which fix bugs and/or improve + the behind-the-scenes implementation. +.fi +.sp + +.SH TRIVIA + +In Spanish, a "tecla" is the key of a keyboard. Since this library +centers on keyboard input, and given that I wrote much of the library +while working in Chile, this seemed like a suitable name. + +.SH FILES +.nf +libtecla.a - The tecla library. +libtecla.h - The tecla header file. +~/.teclarc - The tecla personal customization file. +.fi + +.SH SEE ALSO +gl_get_line(3), ef_expand_file(3), cpl_complete_word(3), +pca_lookup_file(3), enhance(3) + +.SH AUTHOR +Martin Shepherd (mcs@astro.caltech.edu) + +.SH ACKNOWLEDGMENTS + +.nf +Markus Gyger - Lots of assistance, including help with + shared libraries, configuration information, + particularly for Solaris; modifications to + support C++ compilers, improvements for ksh + users, faster cursor motion, output + buffering, and changes to make gl_get_line() + 8-bit clean. +Mike MacFaden - Suggestions, feedback and testing that led + to many of the major new functions that were + added in version 1.4.0. +Tim Eliseo - Many vi-mode bindings and fixes. +.fi diff --git a/libtecla-1.4.1/man3/libtecla_version.3 b/libtecla-1.4.1/man3/libtecla_version.3 new file mode 100644 index 0000000..2c9c2c7 --- /dev/null +++ b/libtecla-1.4.1/man3/libtecla_version.3 @@ -0,0 +1 @@ +.so man3/libtecla.3 diff --git a/libtecla-1.4.1/man3/new_CplFileConf.3 b/libtecla-1.4.1/man3/new_CplFileConf.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/new_CplFileConf.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/new_ExpandFile.3 b/libtecla-1.4.1/man3/new_ExpandFile.3 new file mode 100644 index 0000000..f4299df --- /dev/null +++ b/libtecla-1.4.1/man3/new_ExpandFile.3 @@ -0,0 +1 @@ +.so man3/ef_expand_file.3 diff --git a/libtecla-1.4.1/man3/new_GetLine.3 b/libtecla-1.4.1/man3/new_GetLine.3 new file mode 100644 index 0000000..6bd3d1f --- /dev/null +++ b/libtecla-1.4.1/man3/new_GetLine.3 @@ -0,0 +1 @@ +.so man3/gl_get_line.3 diff --git a/libtecla-1.4.1/man3/new_PathCache.3 b/libtecla-1.4.1/man3/new_PathCache.3 new file mode 100644 index 0000000..e5a136e --- /dev/null +++ b/libtecla-1.4.1/man3/new_PathCache.3 @@ -0,0 +1 @@ +.so man3/pca_lookup_file.3 diff --git a/libtecla-1.4.1/man3/new_PcaPathConf.3 b/libtecla-1.4.1/man3/new_PcaPathConf.3 new file mode 100644 index 0000000..e5a136e --- /dev/null +++ b/libtecla-1.4.1/man3/new_PcaPathConf.3 @@ -0,0 +1 @@ +.so man3/pca_lookup_file.3 diff --git a/libtecla-1.4.1/man3/new_WordCompletion.3 b/libtecla-1.4.1/man3/new_WordCompletion.3 new file mode 100644 index 0000000..36c83a3 --- /dev/null +++ b/libtecla-1.4.1/man3/new_WordCompletion.3 @@ -0,0 +1 @@ +.so man3/cpl_complete_word.3 diff --git a/libtecla-1.4.1/man3/pca_last_error.3 b/libtecla-1.4.1/man3/pca_last_error.3 new file mode 100644 index 0000000..e5a136e --- /dev/null +++ b/libtecla-1.4.1/man3/pca_last_error.3 @@ -0,0 +1 @@ +.so man3/pca_lookup_file.3 diff --git a/libtecla-1.4.1/man3/pca_lookup_file.3 b/libtecla-1.4.1/man3/pca_lookup_file.3 new file mode 100644 index 0000000..131394a --- /dev/null +++ b/libtecla-1.4.1/man3/pca_lookup_file.3 @@ -0,0 +1,361 @@ +.\" Copyright (C) 2001 by Martin C. Shepherd +.\" +.\" All rights reserved. +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, and/or sell copies of the Software, and to permit persons +.\" to whom the Software is furnished to do so, provided that the above +.\" copyright notice(s) and this permission notice appear in all copies of +.\" the Software and that both the above copyright notice(s) and this +.\" permission notice appear in supporting documentation. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +.\" OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +.\" HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL +.\" INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" Except as contained in this notice, the name of a copyright holder +.\" shall not be used in advertising or otherwise to promote the sale, use +.\" or other dealings in this Software without prior written authorization +.\" of the copyright holder. +.TH pca_lookup_file 3 +.SH NAME +pca_lookup_file, del_PathCache, del_PcaPathConf, new_PathCache, new_PcaPathConf, pca_last_error, pca_path_completions, pca_scan_path, pca_set_check_fn, ppc_file_start, ppc_literal_escapes \- lookup a file in a list of directories +.SH SYNOPSIS +.nf +#include + +PathCache *new_PathCache(void); + +PathCache *del_PathCache(PathCache *pc); + +int pca_scan_path(PathCache *pc, const char *path); + +void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn, + void *data); + +char *pca_lookup_file(PathCache *pc, const char *name, + int name_len, int literal); + +const char *pca_last_error(PathCache *pc); + +CPL_MATCH_FN(pca_path_completions); + +.fi + +.SH DESCRIPTION + +The \f3PathCache\f1 object is part of the tecla library (see the +libtecla(3) man page). +.sp +\f3PathCache\f1 objects allow an application to search for files in +any colon separated list of directories, such as the unix execution +PATH environment variable. Files in absolute directories are cached in +a \f3PathCache\f1 object, whereas relative directories are scanned as +needed. Using a \f3PathCache\f1 object, you can look up the full +pathname of a simple filename, or you can obtain a list of the +possible completions of a given filename prefix. By default all files +in the list of directories are targets for lookup and completion, but +a versatile mechanism is provided for only selecting specific types of +files. The obvious application of this facility is to provide +Tab-completion and lookup of executable commands in the unix PATH, so +an optional callback which rejects all but executable files, is +provided. +.sp +.SH AN EXAMPLE + +Under UNIX, the following example program looks up and displays the +full pathnames of each of the command names on the command line. +.sp +.nf + #include + #include + #include + + int main(int argc, char *argv[]) + { + int i; + /* + * Create a cache for executable files. + */ + PathCache *pc = new_PathCache(); + if(!pc) + exit(1); + /* + * Scan the user's PATH for executables. + */ + if(pca_scan_path(pc, getenv("PATH"))) { + fprintf(stderr, "%s\\n", pca_last_error(pc)); + exit(1); + } + /* + * Arrange to only report executable files. + */ + pca_set_check_fn(pc, cpl_check_exe, NULL); + /* + * Lookup and display the full pathname of each of the + * commands listed on the command line. + */ + for(i=1; i +#include +#include +#include +#include + +#include +#include +#include + +#include "pathutil.h" + +/*....................................................................... + * Create a new PathName object. + * + * Output: + * return PathName * The new object, or NULL on error. + */ +PathName *_new_PathName(void) +{ + PathName *path; /* The object to be returned */ +/* + * Allocate the container. + */ + path = (PathName *)malloc(sizeof(PathName)); + if(!path) { + fprintf(stderr, "_new_PathName: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_PathName(). + */ + path->name = NULL; + path->dim = 0; +/* + * Figure out the maximum length of an expanded pathname. + */ + path->dim = _pu_pathname_dim(); + if(path->dim == 0) + return _del_PathName(path); +/* + * Allocate the pathname buffer. + */ + path->name = (char *)malloc(path->dim * sizeof(char)); + if(!path->name) { + fprintf(stderr, + "_new_PathName: Insufficient memory to allocate pathname buffer.\n"); + return _del_PathName(path); + }; + return path; +} + +/*....................................................................... + * Delete a PathName object. + * + * Input: + * path PathName * The object to be deleted. + * Output: + * return PathName * The deleted object (always NULL). + */ +PathName *_del_PathName(PathName *path) +{ + if(path) { + if(path->name) + free(path->name); + free(path); + }; + return NULL; +} + +/*....................................................................... + * Return the pathname to a zero-length string. + * + * Input: + * path PathName * The pathname container. + * Output: + * return char * The cleared pathname buffer, or NULL on error. + */ +char *_pn_clear_path(PathName *path) +{ +/* + * Check the arguments. + */ + if(!path) { + fprintf(stderr, "_pn_clear_path: NULL argument.\n"); + return NULL; + }; + path->name[0] = '\0'; + return path->name; +} + +/*....................................................................... + * Append a string to a pathname, increasing the size of the pathname + * buffer if needed. + * + * Input: + * path PathName * The pathname container. + * string const char * The string to be appended to the pathname. + * Note that regardless of the slen argument, + * this should be a '\0' terminated string. + * slen int The maximum number of characters to append + * from string[], or -1 to append the whole + * string. + * remove_escapes int If true, remove the backslashes that escape + * spaces, tabs, backslashes etc.. + * Output: + * return char * The pathname string path->name[], which may + * have been reallocated, or NULL if there was + * insufficient memory to extend the pathname. + */ +char *_pn_append_to_path(PathName *path, const char *string, int slen, + int remove_escapes) +{ + int pathlen; /* The length of the pathname */ + int i; +/* + * Check the arguments. + */ + if(!path || !string) { + fprintf(stderr, "_pn_append_to_path: NULL argument(s).\n"); + return NULL; + }; +/* + * Get the current length of the pathname. + */ + pathlen = strlen(path->name); +/* + * How many characters should be appended? + */ + if(slen < 0 || slen > strlen(string)) + slen = strlen(string); +/* + * Resize the pathname if needed. + */ + if(!_pn_resize_path(path, pathlen + slen)) + return NULL; +/* + * Append the string to the output pathname, removing any escape + * characters found therein. + */ + if(remove_escapes) { + int is_escape = 0; + for(i=0; iname[pathlen++] = string[i]; + }; +/* + * Terminate the string. + */ + path->name[pathlen] = '\0'; + } else { +/* + * Append the string directly to the pathname. + */ + memcpy(path->name + pathlen, string, slen); + path->name[pathlen + slen] = '\0'; + }; + return path->name; +} + +/*....................................................................... + * Prepend a string to a pathname, increasing the size of the pathname + * buffer if needed. + * + * Input: + * path PathName * The pathname container. + * string const char * The string to be prepended to the pathname. + * Note that regardless of the slen argument, + * this should be a '\0' terminated string. + * slen int The maximum number of characters to prepend + * from string[], or -1 to append the whole + * string. + * remove_escapes int If true, remove the backslashes that escape + * spaces, tabs, backslashes etc.. + * Output: + * return char * The pathname string path->name[], which may + * have been reallocated, or NULL if there was + * insufficient memory to extend the pathname. + */ +char *_pn_prepend_to_path(PathName *path, const char *string, int slen, + int remove_escapes) +{ + int pathlen; /* The length of the pathname */ + int shift; /* The number of characters to shift the suffix by */ + int i,j; +/* + * Check the arguments. + */ + if(!path || !string) { + fprintf(stderr, "_pn_prepend_to_path: NULL argument(s).\n"); + return NULL; + }; +/* + * Get the current length of the pathname. + */ + pathlen = strlen(path->name); +/* + * How many characters should be appended? + */ + if(slen < 0 || slen > strlen(string)) + slen = strlen(string); +/* + * Work out how far we need to shift the original path string to make + * way for the new prefix. When removing escape characters, we need + * final length of the new prefix, after unescaped backslashes have + * been removed. + */ + if(remove_escapes) { + int is_escape = 0; + for(shift=0,i=0; iname + shift, path->name, pathlen+1); +/* + * Copy the new prefix into the vacated space at the beginning of the + * output pathname, removing any escape characters if needed. + */ + if(remove_escapes) { + int is_escape = 0; + for(i=j=0; iname[j++] = string[i]; + }; + } else { + memcpy(path->name, string, slen); + }; + return path->name; +} + +/*....................................................................... + * If needed reallocate a given pathname buffer to allow a string of + * a given length to be stored in it. + * + * Input: + * path PathName * The pathname container object. + * length size_t The required length of the pathname buffer, + * not including the terminating '\0'. + * Output: + * return char * The pathname buffer, or NULL if there was + * insufficient memory (this isn't reported + * to stderr). + */ +char *_pn_resize_path(PathName *path, size_t length) +{ +/* + * Check the arguments. + */ + if(!path) { + fprintf(stderr, "_pn_resize_path: NULL argument(s).\n"); + return NULL; + }; +/* + * If the pathname buffer isn't large enough to accomodate a string + * of the specified length, attempt to reallocate it with the new + * size, plus space for a terminating '\0'. Also add a bit of + * head room to prevent too many reallocations if the initial length + * turned out to be very optimistic. + */ + if(length + 1 > path->dim) { + size_t dim = length + 1 + PN_PATHNAME_INC; + char *name = (char *) realloc(path->name, dim); + if(!name) + return NULL; + path->name = name; + path->dim = dim; + }; + return path->name; +} + +/*....................................................................... + * Estimate the largest amount of space needed to store a pathname. + * + * Output: + * return size_t The number of bytes needed, including space for the + * terminating '\0'. + */ +size_t _pu_pathname_dim(void) +{ + int maxlen; /* The return value excluding space for the '\0' */ +/* + * If the POSIX PATH_MAX macro is defined in limits.h, use it. + */ +#ifdef PATH_MAX + maxlen = PATH_MAX; +/* + * If we have pathconf, use it. + */ +#elif defined(_PC_PATH_MAX) + errno = 0; + maxlen = pathconf(FS_ROOT_DIR, _PC_PATH_MAX); + if(maxlen <= 0 || errno) + maxlen = MAX_PATHLEN_FALLBACK; +/* + * None of the above approaches worked, so substitute our fallback + * guess. + */ +#else + maxlen = MAX_PATHLEN_FALLBACK; +#endif +/* + * Return the amount of space needed to accomodate a pathname plus + * a terminating '\0'. + */ + return maxlen + 1; +} + +/*....................................................................... + * Return non-zero if the specified path name refers to a directory. + * + * Input: + * pathname const char * The path to test. + * Output: + * return int 0 - Not a directory. + * 1 - pathname[] refers to a directory. + */ +int _pu_path_is_dir(const char *pathname) +{ + struct stat statbuf; /* The file-statistics return buffer */ +/* + * Look up the file attributes. + */ + if(stat(pathname, &statbuf) < 0) + return 0; +/* + * Is the file a directory? + */ + return S_ISDIR(statbuf.st_mode) != 0; +} + +/*....................................................................... + * Return non-zero if the specified path name refers to a regular file. + * + * Input: + * pathname const char * The path to test. + * Output: + * return int 0 - Not a regular file. + * 1 - pathname[] refers to a regular file. + */ +int _pu_path_is_file(const char *pathname) +{ + struct stat statbuf; /* The file-statistics return buffer */ +/* + * Look up the file attributes. + */ + if(stat(pathname, &statbuf) < 0) + return 0; +/* + * Is the file a regular file? + */ + return S_ISREG(statbuf.st_mode) != 0; +} + +/*....................................................................... + * Return non-zero if the specified path name refers to an executable. + * + * Input: + * pathname const char * The path to test. + * Output: + * return int 0 - Not an executable file. + * 1 - pathname[] refers to an executable file. + */ +int _pu_path_is_exe(const char *pathname) +{ + struct stat statbuf; /* The file-statistics return buffer */ +/* + * Look up the file attributes. + */ + if(stat(pathname, &statbuf) < 0) + return 0; +/* + * Is the file a regular file which is executable by the current user. + */ + return S_ISREG(statbuf.st_mode) != 0 && + (statbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) && + access(pathname, X_OK) == 0; +} + +/*....................................................................... + * Search backwards for the potential start of a filename. This + * looks backwards from the specified index in a given string, + * stopping at the first unescaped space or the start of the line. + * + * Input: + * string const char * The string to search backwards in. + * back_from int The index of the first character in string[] + * that follows the pathname. + * Output: + * return char * The pointer to the first character of + * the potential pathname, or NULL on error. + */ +char *_pu_start_of_path(const char *string, int back_from) +{ + int i, j; +/* + * Check the arguments. + */ + if(!string || back_from < 0) { + fprintf(stderr, "_pu_start_path: Invalid argument(s).\n"); + return NULL; + }; +/* + * Search backwards from the specified index. + */ + for(i=back_from-1; i>=0; i--) { + int c = string[i]; +/* + * Stop on unescaped spaces. + */ + if(isspace((int)(unsigned char)c)) { +/* + * The space can't be escaped if we are at the start of the line. + */ + if(i==0) + break; +/* + * Find the extent of the escape characters which precedes the space. + */ + for(j=i-1; j>=0 && string[j]=='\\'; j--) + ; +/* + * If there isn't an odd number of escape characters before the space, + * then the space isn't escaped. + */ + if((i - 1 - j) % 2 == 0) + break; + }; + }; + return (char *)string + i + 1; +} + +/*....................................................................... + * Find the length of a potential filename starting from a given + * point. This looks forwards from the specified index in a given string, + * stopping at the first unescaped space or the end of the line. + * + * Input: + * string const char * The string to search backwards in. + * start_from int The index of the first character of the pathname + * in string[]. + * Output: + * return char * The pointer to the character that follows + * the potential pathname, or NULL on error. + */ +char *_pu_end_of_path(const char *string, int start_from) +{ + int c; /* The character being examined */ + int escaped = 0; /* True when the next character is escaped */ + int i; +/* + * Check the arguments. + */ + if(!string || start_from < 0) { + fprintf(stderr, "_pu_end_path: Invalid argument(s).\n"); + return NULL; + }; +/* + * Search forwards from the specified index. + */ + for(i=start_from; (c=string[i]) != '\0'; i++) { + if(escaped) { + escaped = 0; + } else if(isspace(c)) { + break; + } else if(c == '\\') { + escaped = 1; + }; + }; + return (char *)string + i; +} + +/*....................................................................... + * Return non-zero if the specified path name refers to an existing file. + * + * Input: + * pathname const char * The path to test. + * Output: + * return int 0 - The file doesn't exist. + * 1 - The file does exist. + */ +int _pu_file_exists(const char *pathname) +{ + struct stat statbuf; + return stat(pathname, &statbuf) == 0; +} diff --git a/libtecla-1.4.1/pathutil.h b/libtecla-1.4.1/pathutil.h new file mode 100644 index 0000000..2f4ece5 --- /dev/null +++ b/libtecla-1.4.1/pathutil.h @@ -0,0 +1,122 @@ +#ifndef pathutil_h +#define pathutil_h + +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * The following object encapsulates a buffer designed to be used to + * store pathnames. The pathname member of the object is initially + * allocated with the size that _pu_pathname_dim() returns, and then + * if this turns out to be pessimistic, the pathname can be reallocated + * via calls to pb_append_to_path() and/or pb_resize_path(). + */ +typedef struct { + char *name; /* The path buffer */ + size_t dim; /* The current allocated size of buffer[] */ +} PathName; + +PathName *_new_PathName(void); +PathName *_del_PathName(PathName *path); + +char *_pn_clear_path(PathName *path); +char *_pn_append_to_path(PathName *path, const char *string, int slen, + int remove_escapes); +char *_pn_prepend_to_path(PathName *path, const char *string, int slen, + int remove_escapes); +char *_pn_resize_path(PathName *path, size_t length); + +/* + * Search backwards for the potential start of a filename. This + * looks backwards from the specified index in a given string, + * stopping at the first unescaped space or the start of the line. + */ +char *_pu_start_of_path(const char *string, int back_from); + +/* + * Find the end of a potential filename, starting from a given index + * in the string. This looks forwards from the specified index in a + * given string, stopping at the first unescaped space or the end + * of the line. + */ +char *_pu_end_of_path(const char *string, int start_from); + + +/* + * Return an estimate of the the length of the longest pathname + * on the local system. + */ +size_t _pu_pathname_dim(void); + +/* + * Return non-zero if the specified path name refers to a directory. + */ +int _pu_path_is_dir(const char *pathname); + +/* + * Return non-zero if the specified path name refers to a regular file. + */ +int _pu_path_is_file(const char *pathname); + +/* + * Return non-zero if the specified path name refers to an executable. + */ +int _pu_path_is_exe(const char *pathname); + +/* + * Return non-zero if a file exists with the specified pathname. + */ +int _pu_file_exists(const char *pathname); + +/* + * If neither the POSIX PATH_MAX macro nor the pathconf() function + * can be used to find out the maximum pathlength on the target + * system, the following fallback maximum length is used. + */ +#define MAX_PATHLEN_FALLBACK 1024 + +/* + * If the pathname buffer turns out to be too small, it will be extended + * in chunks of the following amount (plus whatever is needed at the time). + */ +#define PN_PATHNAME_INC 100 + +/* + * Define the special character-sequences of the filesystem. + */ +#define FS_ROOT_DIR "/" /* The root directory */ +#define FS_ROOT_DIR_LEN (sizeof(FS_ROOT_DIR) - 1) +#define FS_PWD "." /* The current working directory */ +#define FS_PWD_LEN (sizeof(FS_PWD_LEN) - 1) +#define FS_DIR_SEP "/" /* The directory separator string */ +#define FS_DIR_SEP_LEN (sizeof(FS_DIR_SEP) - 1) + +#endif diff --git a/libtecla-1.4.1/pcache.c b/libtecla-1.4.1/pcache.c new file mode 100644 index 0000000..bbea916 --- /dev/null +++ b/libtecla-1.4.1/pcache.c @@ -0,0 +1,1688 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include +#include + +#include "libtecla.h" +#include "pathutil.h" +#include "homedir.h" +#include "freelist.h" +#include "direader.h" +#include "stringrp.h" + +/* + * The new_PcaPathConf() constructor sets the integer first member of + * the returned object to the following magic number. This is then + * checked for by pca_path_completions() as a sanity check. + */ +#define PPC_ID_CODE 4567 + +/* + * A pointer to a structure of the following type can be passed to + * the builtin path-completion callback function to modify its behavior. + */ +struct PcaPathConf { + int id; /* This is set to PPC_ID_CODE by new_PcaPathConf() */ + PathCache *pc; /* The path-list cache in which to look up the executables */ + int escaped; /* If non-zero, backslashes in the input line are */ + /* interpreted as escaping special characters and */ + /* spaces, and any special characters and spaces in */ + /* the listed completions will also be escaped with */ + /* added backslashes. This is the default behaviour. */ + /* If zero, backslashes are interpreted as being */ + /* literal parts of the file name, and none are added */ + /* to the completion suffixes. */ + int file_start; /* The index in the input line of the first character */ + /* of the file name. If you specify -1 here, */ + /* pca_path_completions() identifies the */ + /* the start of the file by looking backwards for */ + /* an unescaped space, or the beginning of the line. */ +}; + +/* + * Prepended to each chached filename is a character which contains + * one of the following status codes. When a given filename (minus + * this byte) is passed to the application's check_fn(), the result + * is recorded in this byte, such that the next time it is looked + * up, we don't have to call check_fn() again. These codes are cleared + * whenever the path is scanned and whenever the check_fn() callback + * is changed. + */ +typedef enum { + PCA_F_ENIGMA='?', /* The file remains to be checked */ + PCA_F_WANTED='+', /* The file has been selected by the caller's callback */ + PCA_F_IGNORE='-' /* The file has been rejected by the caller's callback */ +} PcaFileStatus; + +/* + * Encapsulate the memory management objects which supply memoy for + * the arrays of filenames. + */ +typedef struct { + StringGroup *sg; /* The memory used to record the names of files */ + size_t files_dim; /* The allocated size of files[] */ + char **files; /* Memory for 'files_dim' pointers to files */ + size_t nfiles; /* The number of filenames currently in files[] */ +} CacheMem; + +static CacheMem *new_CacheMem(void); +static CacheMem *del_CacheMem(CacheMem *cm); +static void rst_CacheMem(CacheMem *cm); + +/* + * Lists of nodes of the following type are used to record the + * names and contents of individual directories. + */ +typedef struct PathNode PathNode; +struct PathNode { + PathNode *next; /* The next directory in the path */ + int relative; /* True if the directory is a relative pathname */ + CacheMem *mem; /* The memory used to store dir[] and files[] */ + char *dir; /* The directory pathname (stored in pc->sg) */ + int nfile; /* The number of filenames stored in 'files' */ + char **files; /* Files of interest in the current directory, */ + /* or NULL if dir[] is a relative pathname */ + /* who's contents can't be cached. This array */ + /* and its contents are taken from pc->abs_mem */ + /* or pc->rel_mem */ +}; + +/* + * Append a new node to the list of directories in the path. + */ +static int add_PathNode(PathCache *pc, const char *dirname); + +/* + * Set the max length of the error-reporting string. There is no point + * in this being longer than the width of a typical terminal window. + * In composing error messages, I have assumed that this number is + * at least 80, so you don't decrease it below this number. + */ +#define ERRLEN 200 + +/* + * Set the maximum length allowed for usernames. + * names. + */ +#define USR_LEN 100 + +/* + * PathCache objects encapsulate the resources needed to record + * files of interest from comma-separated lists of directories. + */ +struct PathCache { + FreeList *node_mem; /* A free-list of PathNode objects */ + CacheMem *abs_mem; /* Memory for the filenames of absolute paths */ + CacheMem *rel_mem; /* Memory for the filenames of relative paths */ + PathNode *head; /* The head of the list of directories in the */ + /* path, or NULL if no path has been scanned yet. */ + PathNode *tail; /* The tail of the list of directories in the */ + /* path, or NULL if no path has been scanned yet. */ + PathName *path; /* The fully qualified name of a file */ + HomeDir *home; /* Home-directory lookup object */ + DirReader *dr; /* A portable directory reader */ + CplFileConf *cfc; /* Configuration parameters to pass to */ + /* cpl_file_completions() */ + CplCheckFn *check_fn; /* The callback used to determine if a given */ + /* filename should be recorded in the cache. */ + void *data; /* Annonymous data to be passed to pc->check_fn() */ + char usrnam[USR_LEN+1];/* The buffer used when reading the names of */ + /* users. */ + char errmsg[ERRLEN+1]; /* Error-report buffer */ +}; + +/* + * Empty the cache. + */ +static void pca_clear_cache(PathCache *pc); + +/* + * Read a username from string[] and record it in pc->usrnam[]. + */ +static int pca_read_username(PathCache *pc, const char *string, int slen, + int literal, const char **nextp); + +/* + * Extract the next component of a colon separated list of directory + * paths. + */ +static int pca_extract_dir(PathCache *pc, const char *path, + const char **nextp); + +/* + * Scan absolute directories for files of interest, recording their names + * in mem->sg and recording pointers to these names in mem->files[]. + */ +static int pca_scan_dir(PathCache *pc, const char *dirname, CacheMem *mem); + +/* + * A qsort() comparison function for comparing the cached filename + * strings pointed to by two (char **) array elements. Note that + * this ignores the initial cache-status byte of each filename. + */ +static int pca_cmp_matches(const void *v1, const void *v2); + +/* + * A qsort() comparison function for comparing a filename + * against an element of an array of pointers to filename cache + * entries. + */ +static int pca_cmp_file(const void *v1, const void *v2); + +/* + * Initialize a PcaPathConf configuration objects with the default + * options. + */ +static int pca_init_PcaPathConf(PcaPathConf *ppc, PathCache *pc); + +/* + * Make a copy of a completion suffix, suitable for passing to + * cpl_add_completion(). + */ +static int pca_prepare_suffix(PathCache *pc, const char *suffix, + int add_escapes); + +/* + * Return non-zero if the specified string appears to start with a pathname. + */ +static int cpa_cmd_contains_path(const char *prefix, int prefix_len); + +/* + * Return a given prefix with escapes optionally removed. + */ +static const char *pca_prepare_prefix(PathCache *pc, const char *prefix, + size_t prefix_len, int escaped); + +/* + * If there is a tilde expression at the beginning of the specified path, + * place the corresponding home directory into pc->path. Otherwise + * just clear pc->path. + */ +static int pca_expand_tilde(PathCache *pc, const char *path, int pathlen, + int literal, const char **endp); + +/* + * Clear the filename status codes that are recorded before each filename + * in the cache. + */ +static void pca_remove_marks(PathCache *pc); + +/* + * Specify how many PathNode's to allocate at a time. + */ +#define PATH_NODE_BLK 30 + +/* + * Specify the amount by which the files[] arrays are to be extended + * whenever they are found to be too small. + */ +#define FILES_BLK_FACT 256 + +/*....................................................................... + * Create a new object who's function is to maintain a cache of + * filenames found within a list of directories, and provide quick + * lookup and completion of selected files in this cache. + * + * Output: + * return PathCache * The new, initially empty cache, or NULL + * on error. + */ +PathCache *new_PathCache(void) +{ + PathCache *pc; /* The object to be returned */ +/* + * Allocate the container. + */ + pc = (PathCache *)malloc(sizeof(PathCache)); + if(!pc) { + fprintf(stderr, "new_PathCache: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_PathCache(). + */ + pc->node_mem = NULL; + pc->abs_mem = NULL; + pc->rel_mem = NULL; + pc->head = NULL; + pc->tail = NULL; + pc->path = NULL; + pc->home = NULL; + pc->dr = NULL; + pc->cfc = NULL; + pc->check_fn = 0; + pc->data = NULL; + pc->usrnam[0] = '\0'; + pc->errmsg[0] = '\0'; +/* + * Allocate the freelist of directory list nodes. + */ + pc->node_mem = _new_FreeList("new_PathCache", sizeof(PathNode), + PATH_NODE_BLK); + if(!pc->node_mem) + return del_PathCache(pc); +/* + * Allocate memory for recording names of files in absolute paths. + */ + pc->abs_mem = new_CacheMem(); + if(!pc->abs_mem) + return del_PathCache(pc); +/* + * Allocate memory for recording names of files in relative paths. + */ + pc->rel_mem = new_CacheMem(); + if(!pc->rel_mem) + return del_PathCache(pc); +/* + * Allocate a pathname buffer. + */ + pc->path = _new_PathName(); + if(!pc->path) + return del_PathCache(pc); +/* + * Allocate an object for looking up home-directories. + */ + pc->home = _new_HomeDir(); + if(!pc->home) + return del_PathCache(pc); +/* + * Allocate an object for reading directories. + */ + pc->dr = _new_DirReader(); + if(!pc->dr) + return del_PathCache(pc); +/* + * Allocate a cpl_file_completions() configuration object. + */ + pc->cfc = new_CplFileConf(); + if(!pc->cfc) + return del_PathCache(pc); +/* + * Configure cpl_file_completions() to use check_fn() to select + * files of interest. + */ + cfc_set_check_fn(pc->cfc, pc->check_fn, pc->data); +/* + * Return the cache, ready for use. + */ + return pc; +} + +/*....................................................................... + * Delete a given cache of files, returning the resources that it + * was using to the system. + * + * Input: + * pc PathCache * The cache to be deleted (can be NULL). + * Output: + * return PathCache * The deleted object (ie. allways NULL). + */ +PathCache *del_PathCache(PathCache *pc) +{ + if(pc) { +/* + * Delete the memory of the list of path nodes. + */ + pc->node_mem = _del_FreeList(NULL, pc->node_mem, 1); +/* + * Delete the memory used to record filenames. + */ + pc->abs_mem = del_CacheMem(pc->abs_mem); + pc->rel_mem = del_CacheMem(pc->rel_mem); +/* + * The list of PathNode's was already deleted when node_mem was + * deleted. + */ + pc->head = NULL; + pc->tail = NULL; +/* + * Delete the pathname buffer. + */ + pc->path = _del_PathName(pc->path); +/* + * Delete the home-directory lookup object. + */ + pc->home = _del_HomeDir(pc->home); +/* + * Delete the directory reader. + */ + pc->dr = _del_DirReader(pc->dr); +/* + * Delete the cpl_file_completions() config object. + */ + pc->cfc = del_CplFileConf(pc->cfc); +/* + * Delete the container. + */ + free(pc); + }; + return NULL; +} + +/*....................................................................... + * If you want subsequent calls to pca_lookup_file() and + * pca_path_completions() to only return the filenames of certain + * types of files, for example executables, or filenames ending in + * ".ps", call this function to register a file-selection callback + * function. This callback function takes the full pathname of a file, + * plus application-specific data, and returns 1 if the file is of + * interest, and zero otherwise. + * + * Input: + * pc PathCache * The filename cache. + * check_fn CplCheckFn * The function to call to see if the name of + * a given file should be included in the + * cache. This determines what type of files + * will reside in the cache. To revert to + * selecting all files, regardless of type, + * pass 0 here. + * data void * You can pass a pointer to anything you + * like here, including NULL. It will be + * passed to your check_fn() callback + * function, for its private use. + */ +void pca_set_check_fn(PathCache *pc, CplCheckFn *check_fn, void *data) +{ + if(pc) { +/* + * If the callback or its data pointer have changed, clear the cached + * statuses of files that were accepted or rejected by the previous + * calback. + */ + if(check_fn != pc->check_fn || data != pc->data) + pca_remove_marks(pc); +/* + * Record the new callback locally. + */ + pc->check_fn = check_fn; + pc->data = data; +/* + * Configure cpl_file_completions() to use the same callback to + * select files of interest. + */ + cfc_set_check_fn(pc->cfc, check_fn, data); + }; + return; +} + +/*....................................................................... + * Return a description of the last path-caching error that occurred. + * + * Input: + * pc PathCache * The filename cache that suffered the error. + * Output: + * return char * The description of the last error. + */ +const char *pca_last_error(PathCache *pc) +{ + return pc ? pc->errmsg : "NULL PathCache argument"; +} + +/*....................................................................... + * Discard all cached filenames. + * + * Input: + * pc PathCache * The cache to be cleared. + */ +static void pca_clear_cache(PathCache *pc) +{ + if(pc) { +/* + * Return all path-nodes to the freelist. + */ + _rst_FreeList(pc->node_mem); + pc->head = pc->tail = NULL; +/* + * Delete all filename strings. + */ + rst_CacheMem(pc->abs_mem); + rst_CacheMem(pc->rel_mem); + }; + return; +} + +/*....................................................................... + * Build the list of files of interest contained in a given + * colon-separated list of directories. + * + * Input: + * pc PathCache * The cache in which to store the names of + * the files that are found in the list of + * directories. + * path const char * A colon-separated list of directory + * paths. Under UNIX, when searching for + * executables, this should be the return + * value of getenv("PATH"). + * Output: + * return int 0 - OK. + * 1 - An error occurred. A description of + * the error can be acquired by calling + * pca_last_error(pc). + */ +int pca_scan_path(PathCache *pc, const char *path) +{ + const char *pptr; /* A pointer to the next unprocessed character in path[] */ + PathNode *node; /* A node in the list of directory paths */ + char **fptr; /* A pointer into pc->abs_mem->files[] */ +/* + * Check the arguments. + */ + if(!pc) + return 1; +/* + * Clear the outdated contents of the cache. + */ + pca_clear_cache(pc); +/* + * If no path list was provided, there is nothing to be added to the + * cache. + */ + if(!path) + return 0; +/* + * Extract directories from the path list, expanding tilde expressions + * on the fly into pc->pathname, then add them to the list of path + * nodes, along with a sorted list of the filenames of interest that + * the directories hold. + */ + pptr = path; + while(*pptr) { +/* + * Extract the next pathname component into pc->path->name. + */ + if(pca_extract_dir(pc, pptr, &pptr)) + return 1; +/* + * Add a new node to the list of paths, containing both the + * directory name and, if not a relative pathname, the list of + * files of interest in the directory. + */ + if(add_PathNode(pc, pc->path->name)) + return 1; + }; +/* + * The file arrays in each absolute directory node are sections of + * pc->abs_mem->files[]. Record pointers to the starts of each + * of these sections in each directory node. Note that this couldn't + * be done in add_PathNode(), because pc->abs_mem->files[] may + * get reallocated in subsequent calls to add_PathNode(), thus + * invalidating any pointers to it. + */ + fptr = pc->abs_mem->files; + for(node=pc->head; node; node=node->next) { + node->files = fptr; + fptr += node->nfile; + }; + return 0; +} + +/*....................................................................... + * Extract the next directory path from a colon-separated list of + * directories, expanding tilde home-directory expressions where needed. + * + * Input: + * pc PathCache * The cache of filenames. + * path const char * A pointer to the start of the next component + * in the path list. + * Input/Output: + * nextp const char ** A pointer to the next unprocessed character + * in path[] will be assigned to *nextp. + * Output: + * return int 0 - OK. The extracted path is in pc->path->name. + * 1 - Error. A description of the error will + * have been left in pc->errmsg. + */ +static int pca_extract_dir(PathCache *pc, const char *path, const char **nextp) +{ + const char *pptr; /* A pointer into path[] */ + const char *sptr; /* The path following tilde expansion */ + int escaped = 0; /* True if the last character was a backslash */ +/* + * If there is a tilde expression at the beginning of the specified path, + * place the corresponding home directory into pc->path. Otherwise + * just clear pc->path. + */ + if(pca_expand_tilde(pc, path, strlen(path), 0, &pptr)) + return 1; +/* + * Keep a record of the current location in the path. + */ + sptr = pptr; +/* + * Locate the end of the directory name in the pathname string, stopping + * when either the end of the string is reached, or an un-escaped colon + * separator is seen. + */ + while(*pptr && (escaped || *pptr != ':')) + escaped = !escaped && *pptr++ == '\\'; +/* + * Append the rest of the directory path to the pathname buffer. + */ + if(_pn_append_to_path(pc->path, sptr, pptr - sptr, 1) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to record directory name"); + return 1; + }; +/* + * To facilitate subsequently appending filenames to the directory + * path name, make sure that the recorded directory name ends in a + * directory separator. + */ + { + int dirlen = strlen(pc->path->name); + if(dirlen < FS_DIR_SEP_LEN || + strncmp(pc->path->name + dirlen - FS_DIR_SEP_LEN, FS_DIR_SEP, + FS_DIR_SEP_LEN) != 0) { + if(_pn_append_to_path(pc->path, FS_DIR_SEP, FS_DIR_SEP_LEN, 0) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to record directory name"); + return 1; + }; + }; + }; +/* + * Skip the separator unless we have reached the end of the path. + */ + if(*pptr==':') + pptr++; +/* + * Return the unprocessed tail of the path-list string. + */ + *nextp = pptr; + return 0; +} + +/*....................................................................... + * Read a username, stopping when a directory separator is seen, a colon + * separator is seen, the end of the string is reached, or the username + * buffer overflows. + * + * Input: + * pc PathCache * The cache of filenames. + * string char * The string who's prefix contains the name. + * slen int The max number of characters to read from string[]. + * literal int If true, treat backslashes as literal characters + * instead of escapes. + * Input/Output: + * nextp char ** A pointer to the next unprocessed character + * in string[] will be assigned to *nextp. + * Output: + * return int 0 - OK. The username can be found in pc->usrnam. + * 1 - Error. A description of the error message + * can be found in pc->errmsg. + */ +static int pca_read_username(PathCache *pc, const char *string, int slen, + int literal, const char **nextp) +{ + int usrlen; /* The number of characters in pc->usrnam[] */ + const char *sptr; /* A pointer into string[] */ + int escaped = 0; /* True if the last character was a backslash */ +/* + * Extract the username. + */ + for(sptr=string,usrlen=0; usrlen < USR_LEN && (sptr-string) < slen; sptr++) { +/* + * Stop if the end of the string is reached, or a directory separator + * or un-escaped colon separator is seen. + */ + if(!*sptr || strncmp(sptr, FS_DIR_SEP, FS_DIR_SEP_LEN)==0 || + (!escaped && *sptr == ':')) + break; +/* + * Escape the next character? + */ + if(!literal && !escaped && *sptr == '\\') { + escaped = 1; + } else { + escaped = 0; + pc->usrnam[usrlen++] = *sptr; + }; + }; +/* + * Did the username overflow the buffer? + */ + if(usrlen >= USR_LEN) { + strcpy(pc->errmsg, "Username too long"); + return 1; + }; +/* + * Terminate the string. + */ + pc->usrnam[usrlen] = '\0'; +/* + * Indicate where processing of the input string should continue. + */ + *nextp = sptr; + return 0; +} + + +/*....................................................................... + * Create a new CacheMem object. + * + * Output: + * return CacheMem * The new object, or NULL on error. + */ +static CacheMem *new_CacheMem(void) +{ + CacheMem *cm; /* The object to be returned */ +/* + * Allocate the container. + */ + cm = (CacheMem *)malloc(sizeof(CacheMem)); + if(!cm) { + fprintf(stderr, "new_CacheMem: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_CacheMem(). + */ + cm->sg = NULL; + cm->files_dim = 0; + cm->files = NULL; + cm->nfiles = 0; +/* + * Allocate a list of string segments for storing filenames. + */ + cm->sg = _new_StringGroup(_pu_pathname_dim()); + if(!cm->sg) + return del_CacheMem(cm); +/* + * Allocate an array of pointers to filenames. + * This will be extended later if needed. + */ + cm->files_dim = FILES_BLK_FACT; + cm->files = (char **) malloc(sizeof(*cm->files) * cm->files_dim); + if(!cm->files) { + fprintf(stderr, + "new_CacheMem: Insufficient memory to allocate array of files.\n"); + return del_CacheMem(cm); + }; + return cm; +} + +/*....................................................................... + * Delete a CacheMem object. + * + * Input: + * cm CacheMem * The object to be deleted. + * Output: + * return CacheMem * The deleted object (always NULL). + */ +static CacheMem *del_CacheMem(CacheMem *cm) +{ + if(cm) { +/* + * Delete the memory that was used to record filename strings. + */ + cm->sg = _del_StringGroup(cm->sg); +/* + * Delete the array of pointers to filenames. + */ + cm->files_dim = 0; + if(cm->files) { + free(cm->files); + cm->files = NULL; + }; +/* + * Delete the container. + */ + free(cm); + }; + return NULL; +} + +/*....................................................................... + * Re-initialize the memory used to allocate filename strings. + * + * Input: + * cm CacheMem * The memory cache to be cleared. + */ +static void rst_CacheMem(CacheMem *cm) +{ + _clr_StringGroup(cm->sg); + cm->nfiles = 0; + return; +} + +/*....................................................................... + * Append a new directory node to the list of directories read from the + * path. + * + * Input: + * pc PathCache * The filename cache. + * dirname const char * The name of the new directory. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int add_PathNode(PathCache *pc, const char *dirname) +{ + PathNode *node; /* The new directory list node */ + int relative; /* True if dirname[] is a relative pathname */ +/* + * Have we been passed a relative pathname or an absolute pathname? + */ + relative = strncmp(dirname, FS_ROOT_DIR, FS_ROOT_DIR_LEN) != 0; +/* + * If it's an absolute pathname, ignore it if the corresponding + * directory doesn't exist. + */ + if(!relative && !_pu_path_is_dir(dirname)) + return 0; +/* + * Allocate a new list node to record the specifics of the new directory. + */ + node = (PathNode *) _new_FreeListNode(pc->node_mem); + if(!node) { + sprintf(pc->errmsg, "Insufficient memory to cache new directory."); + return 1; + }; +/* + * Initialize the node. + */ + node->next = NULL; + node->relative = relative; + node->mem = relative ? pc->rel_mem : pc->abs_mem; + node->dir = NULL; + node->nfile = 0; + node->files = NULL; +/* + * Make a copy of the directory pathname. + */ + node->dir = _sg_store_string(pc->abs_mem->sg, dirname, 0); + if(!node->dir) { + strcpy(pc->errmsg, "Insufficient memory to store directory name."); + return 1; + }; +/* + * Scan absolute directories for files of interest, recording their names + * in node->mem->sg and appending pointers to these names to the + * node->mem->files[] array. + */ + if(!node->relative) { + int nfile = node->nfile = pca_scan_dir(pc, node->dir, node->mem); + if(nfile < 1) { /* No files matched or an error occurred */ + node = (PathNode *) _del_FreeListNode(pc->node_mem, node); + return nfile < 0; + }; + }; +/* + * Append the new node to the list. + */ + if(pc->head) { + pc->tail->next = node; + pc->tail = node; + } else { + pc->head = pc->tail = node; + }; + return 0; +} + +/*....................................................................... + * Scan a given directory for files of interest, record their names + * in mem->sg and append pointers to them to the mem->files[] array. + * + * Input: + * pc PathCache * The filename cache. + * dirname const char * The pathname of the directory to be scanned. + * mem CacheMem * The memory in which to store filenames of + * interest. + * Output: + * return int The number of files recorded, or -1 if a + * memory error occurs. Note that the + * inability to read the contents of the + * directory is not counted as an error. + */ +static int pca_scan_dir(PathCache *pc, const char *dirname, CacheMem *mem) +{ + int nfile = 0; /* The number of filenames recorded */ + const char *filename; /* The name of the file being looked at */ +/* + * Attempt to open the directory. If the directory can't be read then + * there are no accessible files of interest in the directory. + */ + if(_dr_open_dir(pc->dr, dirname, NULL)) + return 0; +/* + * Record the names of all files in the directory in the cache. + */ + while((filename = _dr_next_file(pc->dr))) { + char *copy; /* A copy of the filename */ +/* + * Make a temporary copy of the filename with an extra byte prepended. + */ + _pn_clear_path(pc->path); + if(_pn_append_to_path(pc->path, " ", 1, 0) == NULL || + _pn_append_to_path(pc->path, filename, -1, 1) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to record filename"); + return -1; + }; +/* + * Store the filename. + */ + copy = _sg_store_string(mem->sg, pc->path->name, 0); + if(!copy) { + strcpy(pc->errmsg, "Insufficient memory to cache file name."); + return -1; + }; +/* + * Mark the filename as unchecked. + */ + copy[0] = PCA_F_ENIGMA; +/* + * Make room to store a pointer to the copy in mem->files[]. + */ + if(mem->nfiles + 1 > mem->files_dim) { + int needed = mem->files_dim + FILES_BLK_FACT; + char **files = (char **) realloc(mem->files, sizeof(*mem->files)*needed); + if(!files) { + strcpy(pc->errmsg, "Insufficient memory to extend filename cache."); + return 1; + }; + mem->files = files; + mem->files_dim = needed; + }; +/* + * Record a pointer to the copy of the filename at the end of the files[] + * array. + */ + mem->files[mem->nfiles++] = copy; +/* + * Keep a record of the number of files matched so far. + */ + nfile++; + }; +/* + * Sort the list of files into lexical order. + */ + qsort(mem->files + mem->nfiles - nfile, nfile, sizeof(*mem->files), + pca_cmp_matches); +/* + * Return the number of files recorded in mem->files[]. + */ + return nfile; +} + +/*....................................................................... + * A qsort() comparison function for comparing the cached filename + * strings pointed to by two (char **) array elements. Note that + * this ignores the initial cache-status byte of each filename. + * + * Input: + * v1, v2 void * Pointers to the pointers of two strings to be compared. + * Output: + * return int -1 -> v1 < v2. + * 0 -> v1 == v2 + * 1 -> v1 > v2 + */ +static int pca_cmp_matches(const void *v1, const void *v2) +{ + const char **s1 = (const char **) v1; + const char **s2 = (const char **) v2; + return strcmp(*s1+1, *s2+1); +} + +/*....................................................................... + * Given the simple name of a file, search the cached list of files + * in the order in which they where found in the list of directories + * previously presented to pca_scan_path(), and return the pathname + * of the first file which has this name. If a pathname to a file is + * given instead of a simple filename, this is returned without being + * looked up in the cache, but with any initial ~username expression + * expanded, and optionally, unescaped backslashes removed. + * + * Input: + * pc PathCache * The cached list of files. + * name const char * The name of the file to lookup. + * name_len int The length of the filename string at the + * beginning of name[], or -1 to indicate that + * the filename occupies the whole of the + * string. + * literal int If this argument is zero, lone backslashes + * in name[] are ignored during comparison + * with filenames in the cache, under the + * assumption that they were in the input line + * soley to escape the special significance of + * characters like spaces. To have them treated + * as normal characters, give this argument a + * non-zero value, such as 1. + * Output: + * return char * The pathname of the first matching file, + * or NULL if not found. Note that the returned + * pointer points to memory owned by *pc, and + * will become invalid on the next call to any + * function in the PathCache module. + */ +char *pca_lookup_file(PathCache *pc, const char *name, int name_len, + int literal) +{ + PathNode *node; /* A node in the list of directories in the path */ + char **match; /* A pointer to a matching filename string in the cache */ +/* + * Check the arguments. + */ + if(!pc || !name || name_len==0) + return NULL; +/* + * If no length was specified, determine the length of the string to + * be looked up. + */ + if(name_len < 0) + name_len = strlen(name); +/* + * If the word starts with a ~username expression, the root directory, + * of it contains any directory separators, then treat it isn't a simple + * filename that can be looked up in the cache, but rather appears to + * be the pathname of a file. If so, return a copy of this pathname with + * escapes removed, if requested, and any initial ~username expression + * expanded. + */ + if(cpa_cmd_contains_path(name, name_len)) { + const char *nptr; + if(pca_expand_tilde(pc, name, name_len, literal, &nptr) || + _pn_append_to_path(pc->path, nptr, name_len - (nptr-name), + !literal) == NULL) + return NULL; + return pc->path->name; + }; +/* + * Look up the specified filename in each of the directories of the path, + * in the same order that they were listed in the path, and stop as soon + * as an instance of the file is found. + */ + for(node=pc->head; node; node=node->next) { +/* + * If the directory of the latest node is a relative pathname, + * scan it for files of interest. + */ + if(node->relative) { + rst_CacheMem(node->mem); + if(pca_scan_dir(pc, node->dir, node->mem) < 1) + continue; + node->files = node->mem->files; + node->nfile = node->mem->nfiles; + }; +/* + * Copy the filename into a temporary buffer, while interpretting + * escape characters if needed. + */ + _pn_clear_path(pc->path); + if(_pn_append_to_path(pc->path, name, name_len, !literal) == NULL) + return NULL; +/* + * Perform a binary search for the requested filename. + */ + match = (char **)bsearch(pc->path->name, node->files, node->nfile, + sizeof(*node->files), pca_cmp_file); + if(match) { +/* + * Prepend the pathname in which the directory was found, which we have + * guaranteed to end in a directory separator, to the located filename. + */ + if(_pn_prepend_to_path(pc->path, node->dir, -1, 0) == NULL) + return NULL; +/* + * Return the matching pathname unless it is rejected by the application. + */ + if(!pc->check_fn || (*match)[0] == PCA_F_WANTED || + ((*match)[0]==PCA_F_ENIGMA && pc->check_fn(pc->data, pc->path->name))){ + (*match)[0] = PCA_F_WANTED; + return pc->path->name; + } else { + *(match)[0] = PCA_F_IGNORE; + }; + }; + }; +/* + * File not found. + */ + return NULL; +} + +/*....................................................................... + * A qsort() comparison function for comparing a filename string to + * a cached filename string pointed to by a (char **) array element. + * This ignores the initial code byte at the start of the cached filename + * string. + * + * Input: + * v1, v2 void * Pointers to the pointers of two strings to be compared. + * Output: + * return int -1 -> v1 < v2. + * 0 -> v1 == v2 + * 1 -> v1 > v2 + */ +static int pca_cmp_file(const void *v1, const void *v2) +{ + const char *file_name = (const char *) v1; + const char **cache_name = (const char **) v2; + return strcmp(file_name, *cache_name + 1); +} + +/*....................................................................... + * The PcaPathConf structure may have options added to it in the future. + * To allow your application to be linked against a shared version of the + * tecla library, without these additions causing your application to + * crash, you should use new_PcaPathConf() to allocate such structures. + * This will set all of the configuration options to their default values, + * which you can then change before passing the structure to + * pca_path_completions(). + * + * Input: + * pc PathCache * The filename cache in which to look for + * file name completions. + * Output: + * return PcaPathConf * The new configuration structure, or NULL + * on error. A descripition of the error + * can be found by calling pca_last_error(pc). + */ +PcaPathConf *new_PcaPathConf(PathCache *pc) +{ + PcaPathConf *ppc; /* The object to be returned */ +/* + * Check the arguments. + */ + if(!pc) + return NULL; +/* + * Allocate the container. + */ + ppc = (PcaPathConf *)malloc(sizeof(PcaPathConf)); + if(!ppc) { + strcpy(pc->errmsg, "Insufficient memory."); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to del_PcaPathConf(). + */ + if(pca_init_PcaPathConf(ppc, pc)) + return del_PcaPathConf(ppc); + return ppc; +} + +/*....................................................................... + * Initialize a PcaPathConf configuration structure with defaults. + * + * Input: + * ppc PcaPathConf * The structre to be initialized. + * pc PathCache * The cache in which completions will be looked up. + * Output: + * return int 0 - OK. + * 1 - Error. A description of the error can be + * obtained by calling pca_last_error(pc). + */ +static int pca_init_PcaPathConf(PcaPathConf *ppc, PathCache *pc) +{ +/* + * Check the arguments. + */ + if(!pc) + return 1; +/* + * Set the default options. + */ + ppc->id = PPC_ID_CODE; + ppc->pc = pc; + ppc->escaped = 1; + ppc->file_start = -1; + return 0; +} + +/*....................................................................... + * Delete a PcaPathConf object. + * + * Input: + * ppc PcaPathConf * The object to be deleted. + * Output: + * return PcaPathConf * The deleted object (always NULL). + */ +PcaPathConf *del_PcaPathConf(PcaPathConf *ppc) +{ + if(ppc) { + ppc->pc = NULL; /* It is up to the caller to delete the cache */ +/* + * Delete the container. + */ + free(ppc); + }; + return NULL; +} + +/*....................................................................... + * pca_path_completions() is a completion callback function for use + * directly with cpl_complete_word() or gl_customize_completions(), or + * indirectly from your own completion callback function. It requires + * that a CpaPathArgs object be passed via its 'void *data' argument. + */ +CPL_MATCH_FN(pca_path_completions) +{ + PcaPathConf *ppc; /* The configuration arguments */ + PathCache *pc; /* The cache in which to look for completions */ + PathNode *node; /* A node in the list of directories in the path */ + const char *filename; /* The name of the file being looked at */ + const char *start_path; /* The pointer to the start of the pathname */ + /* in line[]. */ + int word_start; /* The index in line[] corresponding to start_path */ + const char *prefix; /* The file-name prefix being searched for */ + size_t prefix_len; /* The length of the prefix being completed */ + int bot; /* The lowest index of the array not searched yet */ + int top; /* The highest index of the array not searched yet */ +/* + * Check the arguments. + */ + if(!cpl) + return 1; + if(!line || word_end < 0 || !data) { + cpl_record_error(cpl, "pca_path_completions: Invalid arguments."); + return 1; + }; +/* + * Get the configuration arguments. + */ + ppc = (PcaPathConf *) data; +/* + * Check that the callback data is a PcaPathConf structure returned + * by new_PcaPathConf(). + */ + if(ppc->id != PPC_ID_CODE) { + cpl_record_error(cpl, + "Invalid callback data passed to pca_path_completions()"); + return 1; + }; +/* + * Get the filename cache. + */ + pc = ppc->pc; +/* + * Get the start of the file name. If not specified by the caller, + * identify it by searching backwards in the input line for an + * unescaped space or the start of the line. + */ + if(ppc->file_start < 0) { + start_path = _pu_start_of_path(line, word_end); + if(!start_path) { + cpl_record_error(cpl, "Unable to find the start of the file name."); + return 1; + }; + } else { + start_path = line + ppc->file_start; + }; +/* + * Get the index of the start of the word being completed. + */ + word_start = start_path - line; +/* + * Work out the length of the prefix that is bein completed. + */ + prefix_len = word_end - word_start; +/* + * If the word starts with a ~username expression or the root directory, + * of it contains any directory separators, then completion must be + * delegated to cpl_file_completions(). + */ + if(cpa_cmd_contains_path(start_path, prefix_len)) { + cfc_file_start(pc->cfc, word_start); + return cpl_file_completions(cpl, pc->cfc, line, word_end); + }; +/* + * Look up the specified file name in each of the directories of the path, + * in the same order that they were listed in the path, and stop as soon + * as an instance of the file is found. + */ + for(node=pc->head; node; node=node->next) { +/* + * If the directory of the latest node is a relative pathname, + * scan it for files of interest. + */ + if(node->relative) { + rst_CacheMem(node->mem); + if(pca_scan_dir(pc, node->dir, node->mem) < 1) + continue; + node->files = node->mem->files; + node->nfile = node->mem->nfiles; + }; +/* + * If needed, make a copy of the file-name being matched, with + * escapes removed. Note that we need to do this anew every loop + * iteration, because the above call to pca_scan_dir() uses + * pc->path. + */ + prefix = pca_prepare_prefix(pc, start_path, prefix_len, ppc->escaped); + if(!prefix) + return 1; +/* + * The directory entries are sorted, so we can perform a binary + * search for an instance of the prefix being searched for. + */ + bot = 0; + top = node->nfile - 1; + while(top >= bot) { + int mid = (top + bot)/2; + int test = strncmp(node->files[mid]+1, prefix, prefix_len); + if(test > 0) + top = mid - 1; + else if(test < 0) + bot = mid + 1; + else { + top = bot = mid; + break; + }; + }; +/* + * If we found a match, look to see if any of its neigbors also match. + */ + if(top == bot) { + while(--bot >= 0 && strncmp(node->files[bot]+1, prefix, prefix_len) == 0) + ; + while(++top < node->nfile && + strncmp(node->files[top]+1, prefix, prefix_len) == 0) + ; +/* + * We will have gone one too far in each direction. + */ + bot++; + top--; +/* + * Add the completions to the list after checking them against the + * callers requirements. + */ + for( ; bot<=top; bot++) { + char *match = node->files[bot]; +/* + * Form the full pathname of the file. + */ + _pn_clear_path(pc->path); + if(_pn_append_to_path(pc->path, node->dir, -1, 0) == NULL || + _pn_append_to_path(pc->path, match+1, -1, 0) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to complete file name"); + return 1; + }; +/* + * Should the file be included in the list of completions? + */ + if(!pc->check_fn || match[0] == PCA_F_WANTED || + (match[0]==PCA_F_ENIGMA && pc->check_fn(pc->data, pc->path->name))) { + match[0] = PCA_F_WANTED; +/* + * Copy the completion suffix into the work pathname pc->path->name, + * adding backslash escapes if needed. + */ + if(pca_prepare_suffix(pc, match + 1 + prefix_len, + ppc->escaped)) + return 1; +/* + * Record the completion. + */ + if(cpl_add_completion(cpl, line, word_start, word_end, pc->path->name, + "", " ")) + return 1; +/* + * The file was rejected by the application. + */ + } else { + match[0] = PCA_F_IGNORE; + }; + }; + }; + }; +/* + * We now need to search for subdirectories of the current directory which + * have matching prefixes. First, if needed, make a copy of the word being + * matched, with escapes removed. + */ + prefix = pca_prepare_prefix(pc, start_path, prefix_len, ppc->escaped); + if(!prefix) + return 1; +/* + * Now open the current directory. + */ + if(_dr_open_dir(pc->dr, FS_PWD, NULL)) + return 0; +/* + * Scan the current directory for sub-directories whos names start with + * the prefix that we are completing. + */ + while((filename = _dr_next_file(pc->dr))) { +/* + * Does the latest filename match the prefix, and is it a directory? + */ + if(strncmp(filename, prefix, prefix_len) == 0 && _pu_path_is_dir(filename)){ +/* + * Record the completion. + */ + if(pca_prepare_suffix(pc, filename + prefix_len, ppc->escaped) || + cpl_add_completion(cpl, line, word_start, word_end, pc->path->name, + FS_DIR_SEP, FS_DIR_SEP)) + return 1; +/* + * The prefix in pc->path->name will have been overwritten by + * pca_prepare_suffix(). Restore it here. + */ + prefix = pca_prepare_prefix(pc, start_path, prefix_len, ppc->escaped); + if(!prefix) + return 1; + }; + }; + _dr_close_dir(pc->dr); + return 0; +} + +/*....................................................................... + * Using the work buffer pc->path, make a suitably escaped copy of a + * given completion suffix, ready to be passed to cpl_add_completion(). + * + * Input: + * pc PathCache * The filename cache resource object. + * suffix char * The suffix to be copied. + * add_escapes int If true, escape special characters. + * Output: + * return int 0 - OK. + * 1 - Error. + */ +static int pca_prepare_suffix(PathCache *pc, const char *suffix, + int add_escapes) +{ + const char *sptr; /* A pointer into suffix[] */ + int nbsl; /* The number of backslashes to add to the suffix */ + int i; +/* + * How long is the suffix? + */ + int suffix_len = strlen(suffix); +/* + * Clear the work buffer. + */ + _pn_clear_path(pc->path); +/* + * Count the number of backslashes that will have to be added to + * escape spaces, tabs, backslashes and wildcard characters. + */ + nbsl = 0; + if(add_escapes) { + for(sptr = suffix; *sptr; sptr++) { + switch(*sptr) { + case ' ': case '\t': case '\\': case '*': case '?': case '[': + nbsl++; + break; + }; + }; + }; +/* + * Arrange for the output path buffer to have sufficient room for the + * both the suffix and any backslashes that have to be inserted. + */ + if(_pn_resize_path(pc->path, suffix_len + nbsl) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to complete file name"); + return 1; + }; +/* + * If the suffix doesn't need any escapes, copy it directly into the + * work buffer. + */ + if(nbsl==0) { + strcpy(pc->path->name, suffix); + } else { +/* + * Make a copy with special characters escaped? + */ + if(nbsl > 0) { + const char *src = suffix; + char *dst = pc->path->name; + for(i=0; i= FS_ROOT_DIR_LEN && + strncmp(prefix, FS_ROOT_DIR, FS_ROOT_DIR_LEN) == 0) + return 1; +/* + * Search the prefix for directory separators, returning as soon as + * any are found, since their presence indicates that the filename + * starts with a pathname specification (valid or otherwise). + */ + for(i=0; i= FS_DIR_SEP_LEN && + strncmp(prefix + i, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) + return 1; + }; +/* + * The file name doesn't appear to start with a pathname specification. + */ + return 0; +} + +/*....................................................................... + * If needed make a new copy of the prefix being matched, in pc->path->name, + * but with escapes removed. If no escapes are to be removed, simply return + * the original prefix string. + * + * Input: + * pc PathCache * The cache being searched. + * prefix const char * The prefix to be processed. + * prefix_len size_t The length of the prefix. + * escaped int If true, return a copy with escapes removed. + * Output: + * return const char * The prepared prefix, or NULL on error, in + * which case an error message will have been + * left in pc->errmsg. + */ +static const char *pca_prepare_prefix(PathCache *pc, const char *prefix, + size_t prefix_len, int escaped) +{ +/* + * Make a copy with escapes removed? + */ + if(escaped) { + _pn_clear_path(pc->path); + if(_pn_append_to_path(pc->path, prefix, prefix_len, 1) == NULL) { + strcpy(pc->errmsg, "Insufficient memory to complete filename"); + return NULL; + }; + return pc->path->name; + }; + return prefix; +} + +/*....................................................................... + * If backslashes in the filename should be treated as literal + * characters, call the following function with literal=1. Otherwise + * the default is to treat them as escape characters, used for escaping + * spaces etc.. + * + * Input: + * ppc PcaPathConf * The pca_path_completions() configuration object + * to be configured. + * literal int Pass non-zero here to enable literal interpretation + * of backslashes. Pass 0 to turn off literal + * interpretation. + */ +void ppc_literal_escapes(PcaPathConf *ppc, int literal) +{ + if(ppc) + ppc->escaped = !literal; +} + +/*....................................................................... + * Call this function if you know where the index at which the + * filename prefix starts in the input line. Otherwise by default, + * or if you specify start_index to be -1, the filename is taken + * to start after the first unescaped space preceding the cursor, + * or the start of the line, which ever comes first. + * + * Input: + * ppc PcaPathConf * The pca_path_completions() configuration object + * to be configured. + * start_index int The index of the start of the filename in + * the input line, or -1 to select the default. + */ +void ppc_file_start(PcaPathConf *ppc, int start_index) +{ + if(ppc) + ppc->file_start = start_index; +} + +/*....................................................................... + * Expand any ~user expression found at the start of a path, leaving + * either an empty string in pc->path if there is no ~user expression, + * or the corresponding home directory. + * + * Input: + * pc PathCache * The filename cache. + * path const char * The path to expand. + * pathlen int The max number of characters to look at in path[]. + * literal int If true, treat backslashes as literal characters + * instead of escapes. + * Input/Output: + * endp const char * A pointer to the next unprocessed character in + * path[] will be assigned to *endp. + * Output: + * return int 0 - OK + * 1 - Error (a description will have been placed + * in pc->errmsg[]). + */ +static int pca_expand_tilde(PathCache *pc, const char *path, int pathlen, + int literal, const char **endp) +{ + const char *pptr = path; /* A pointer into path[] */ + const char *homedir=NULL; /* A home directory */ +/* + * Clear the pathname buffer. + */ + _pn_clear_path(pc->path); +/* + * If the first character is a tilde, then perform home-directory + * interpolation. + */ + if(*pptr == '~') { +/* + * Skip the tilde character and attempt to read the username that follows + * it, into pc->usrnam[]. + */ + if(pca_read_username(pc, ++pptr, pathlen-1, literal, &pptr)) + return 1; +/* + * Attempt to lookup the home directory of the user. + */ + homedir = _hd_lookup_home_dir(pc->home, pc->usrnam); + if(!homedir) { + strncpy(pc->errmsg, _hd_last_home_dir_error(pc->home), ERRLEN); + pc->errmsg[ERRLEN] = '\0'; + return 1; + }; +/* + * Append the home directory to the pathname string. + */ + if(_pn_append_to_path(pc->path, homedir, -1, 0) == NULL) { + strcpy(pc->errmsg, "Insufficient memory for home directory expansion"); + return 1; + }; + }; +/* + * ~user and ~ are usually followed by a directory separator to + * separate them from the file contained in the home directory. + * If the home directory is the root directory, then we don't want + * to follow the home directory by a directory separator, so we should + * skip over it so that it doesn't get copied into the output pathname + */ + if(homedir && strcmp(homedir, FS_ROOT_DIR) == 0 && + (pptr-path) + FS_DIR_SEP_LEN < pathlen && + strncmp(pptr, FS_DIR_SEP, FS_DIR_SEP_LEN) == 0) { + pptr += FS_DIR_SEP_LEN; + }; +/* + * Return a pointer to the next unprocessed character. + */ + *endp = pptr; + return 0; +} + +/*....................................................................... + * Clear the filename status codes that are recorded before each filename + * in the cache. + * + * Input: + * pc PathCache * The filename cache. + */ +static void pca_remove_marks(PathCache *pc) +{ + PathNode *node; /* A node in the list of directories in the path */ + int i; +/* + * Traverse the absolute directories of the path, clearing the + * filename status marks that precede each filename. + */ + for(node=pc->head; node; node=node->next) { + if(!node->relative) { + for(i=0; infile; i++) + *node->files[i] = PCA_F_ENIGMA; + }; + }; + return; +} diff --git a/libtecla-1.4.1/stringrp.c b/libtecla-1.4.1/stringrp.c new file mode 100644 index 0000000..fe7d875 --- /dev/null +++ b/libtecla-1.4.1/stringrp.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ +#include +#include +#include + +#include "freelist.h" +#include "stringrp.h" + +/* + * StringSegment objects store lots of small strings in larger + * character arrays. Since the total length of all of the strings can't + * be known in advance, an extensible list of large character arrays, + * called string-segments are used. + */ +typedef struct StringSegment StringSegment; +struct StringSegment { + StringSegment *next; /* A pointer to the next segment in the list */ + char *block; /* An array of characters to be shared between strings */ + int unused; /* The amount of unused space at the end of block[] */ +}; + +/* + * StringGroup is typedef'd in stringrp.h. + */ +struct StringGroup { + FreeList *node_mem; /* The StringSegment free-list */ + int block_size; /* The dimension of each character array block */ + StringSegment *head; /* The list of character arrays */ +}; + +/* + * Specify how many StringSegment's to allocate at a time. + */ +#define STR_SEG_BLK 20 + +/*....................................................................... + * Create a new StringGroup object. + * + * Input: + * segment_size int The length of each of the large character + * arrays in which multiple strings will be + * stored. This sets the length of longest + * string that can be stored, and for efficiency + * should be at least 10 times as large as + * the average string that will be stored. + * Output: + * return StringGroup * The new object, or NULL on error. + */ +StringGroup *_new_StringGroup(int segment_size) +{ + StringGroup *sg; /* The object to be returned */ +/* + * Check the arguments. + */ + if(segment_size < 1) { + fprintf(stderr, "_new_StringGroup: Invalid segment_size argument.\n"); + return NULL; + }; +/* + * Allocate the container. + */ + sg = (StringGroup *) malloc(sizeof(StringGroup)); + if(!sg) { + fprintf(stderr, "_new_StringGroup: Insufficient memory.\n"); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize the + * container at least up to the point at which it can safely be passed + * to _del_StringGroup(). + */ + sg->node_mem = NULL; + sg->head = NULL; + sg->block_size = segment_size; +/* + * Allocate the free list that is used to allocate list nodes. + */ + sg->node_mem = _new_FreeList("_new_StringGroup", sizeof(StringSegment), + STR_SEG_BLK); + if(!sg->node_mem) + return _del_StringGroup(sg); + return sg; +} + +/*....................................................................... + * Delete a StringGroup object. + * + * Input: + * sg StringGroup * The object to be deleted. + * Output: + * return StringGroup * The deleted object (always NULL). + */ +StringGroup *_del_StringGroup(StringGroup *sg) +{ + if(sg) { + StringSegment *node; +/* + * Delete the character arrays. + */ + for(node=sg->head; node; node=node->next) { + if(node->block) + free(node->block); + node->block = NULL; + }; +/* + * Delete the list nodes that contained the string segments. + */ + sg->node_mem = _del_FreeList("_del_StringGroup", sg->node_mem, 1); + sg->head = NULL; /* Already deleted by deleting sg->node_mem */ +/* + * Delete the container. + */ + free(sg); + }; + return NULL; +} + +/*....................................................................... + * Make a copy of a string in the specified string group, and return + * a pointer to the copy. + * + * Input: + * sg StringGroup * The group to store the string in. + * string const char * The string to be recorded. + * remove_escapes int If true, omit backslashes which escape + * other characters when making the copy. + * Output: + * return char * The pointer to the copy of the string, + * or NULL if there was insufficient memory. + */ +char *_sg_store_string(StringGroup *sg, const char *string, int remove_escapes) +{ + char *copy; /* The recorded copy of string[] */ +/* + * Check the arguments. + */ + if(!sg || !string) + return NULL; +/* + * Get memory for the string. + */ + copy = _sg_alloc_string(sg, strlen(string)); + if(copy) { +/* + * If needed, remove backslash escapes while copying the input string + * into the cache string. + */ + if(remove_escapes) { + int escaped = 0; /* True if the next character should be */ + /* escaped. */ + const char *src = string; /* A pointer into the input string */ + char *dst = copy; /* A pointer into the cached copy of the */ + /* string. */ + while(*src) { + if(!escaped && *src == '\\') { + escaped = 1; + src++; + } else { + escaped = 0; + *dst++ = *src++; + }; + }; + *dst = '\0'; +/* + * If escapes have already been removed, copy the input string directly + * into the cache. + */ + } else { + strcpy(copy, string); + }; + }; +/* + * Return a pointer to the copy of the string (or NULL if the allocation + * failed). + */ + return copy; +} + +/*....................................................................... + * Allocate memory for a string of a given length. + * + * Input: + * sg StringGroup * The group to store the string in. + * length int The required length of the string. + * Output: + * return char * The pointer to the copy of the string, + * or NULL if there was insufficient memory. + */ +char *_sg_alloc_string(StringGroup *sg, int length) +{ + StringSegment *node; /* A node of the list of string segments */ + char *copy; /* The allocated string */ +/* + * If the string is longer than block_size, then we can't record it. + */ + if(length > sg->block_size || length < 0) + return NULL; +/* + * See if there is room to record the string in one of the existing + * string segments. + */ + for(node=sg->head; node && node->unused <= length; node=node->next) + ; +/* + * If there wasn't room, allocate a new string segment. + */ + if(!node) { + node = (StringSegment *) _new_FreeListNode(sg->node_mem); + if(!node) + return NULL; +/* + * Initialize the segment. + */ + node->next = NULL; + node->block = NULL; + node->unused = sg->block_size; +/* + * Attempt to allocate the string segment character array. + */ + node->block = (char *) malloc(sg->block_size); + if(!node->block) + return NULL; +/* + * Prepend the node to the list. + */ + node->next = sg->head; + sg->head = node; + }; +/* + * Get memory for the string. + */ + copy = node->block + sg->block_size - node->unused; + node->unused -= length + 1; +/* + * Return a pointer to the string memory. + */ + return copy; +} + +/*....................................................................... + * Delete all of the strings that are currently stored by a specified + * StringGroup object. + * + * Input: + * sg StringGroup * The group of strings to clear. + */ +void _clr_StringGroup(StringGroup *sg) +{ + StringSegment *node; /* A node in the list of string segments */ +/* + * Mark all of the string segments as unoccupied. + */ + for(node=sg->head; node; node=node->next) + node->unused = sg->block_size; + return; +} diff --git a/libtecla-1.4.1/stringrp.h b/libtecla-1.4.1/stringrp.h new file mode 100644 index 0000000..8b15ce9 --- /dev/null +++ b/libtecla-1.4.1/stringrp.h @@ -0,0 +1,84 @@ +#ifndef stringrp_h +#define stringrp_h +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * StringGroup objects provide memory for modules that need to + * allocate lots of small strings without needing to free any of them + * individually, but rather is happy to free them all at the same + * time. Taking advantage of these properties, StringGroup objects + * avoid the heap fragmentation that tends to occur when lots of small + * strings are allocated directly from the heap and later free'd. They + * do this by allocating a list of large character arrays in each of + * which multiple strings are stored. Thus instead of allocating lots + * of small strings, a few large character arrays are allocated. When + * the strings are free'd on mass, this list of character arrays is + * maintained, ready for subsequent use in recording another set of + * strings. + */ +typedef struct StringGroup StringGroup; + +/* + * The following constructor allocates a string-allocation object. + * The segment_size argument specifies how long each string segment + * array should be. This should be at least 10 times the length of + * the average string to be recorded in the string group, and + * sets the length of the longest string that can be stored. + */ +StringGroup *_new_StringGroup(int segment_size); + +/* + * Delete all of the strings that are currently stored by a specified + * StringGroup object. + */ +void _clr_StringGroup(StringGroup *sg); + +/* + * Make a copy of the specified string, returning a pointer to + * the copy, or NULL if there was insufficient memory. If the + * remove_escapes argument is non-zero, backslashes that escape + * other characters will be removed. + */ +char *_sg_store_string(StringGroup *sg, const char *string, int remove_escapes); + +/* + * Allocate memory for a string of a given length. + */ +char *_sg_alloc_string(StringGroup *sg, int length); + +/* + * Delete a StringGroup object (and all of the strings that it + * contains). + */ +StringGroup *_del_StringGroup(StringGroup *sg); + +#endif diff --git a/libtecla-1.4.1/strngmem.c b/libtecla-1.4.1/strngmem.c new file mode 100644 index 0000000..fedf4ff --- /dev/null +++ b/libtecla-1.4.1/strngmem.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +#include +#include + +#include "strngmem.h" +#include "freelist.h" + +struct StringMem { + unsigned long nmalloc; /* The number of strings allocated with malloc */ + FreeList *fl; /* The free-list */ +}; + +/*....................................................................... + * Create a string free-list container and the first block of its free-list. + * + * Input: + * caller const char * The name of the calling function, or NULL + * to not report errors to stderr. + * blocking_factor int The blocking_factor argument specifies how + * many strings of length SM_STRLEN + * bytes (see stringmem.h) are allocated in each + * free-list block. + * For example if blocking_factor=64 and + * SM_STRLEN=16, then each new + * free-list block will take 1K of memory. + * Output: + * return StringMem * The new free-list container, or NULL on + * error. + */ +StringMem *_new_StringMem(const char *caller, unsigned blocking_factor) +{ + StringMem *sm; /* The container to be returned. */ +/* + * Check arguments. + */ + if(blocking_factor < 1) { + if(caller) { + fprintf(stderr, "_new_StringMem (%s): Bad blocking factor (%d).\n", + caller, blocking_factor); + }; + return NULL; + }; +/* + * Allocate the container. + */ + sm = (StringMem *) malloc(sizeof(StringMem)); + if(!sm) { + if(caller) + fprintf(stderr, "_new_StringMem (%s): Insufficient memory.\n", caller); + return NULL; + }; +/* + * Before attempting any operation that might fail, initialize + * the container at least up to the point at which it can safely + * be passed to _del_StringMem(). + */ + sm->nmalloc = 0; + sm->fl = NULL; +/* + * Allocate the free-list. + */ + sm->fl = _new_FreeList(caller, SM_STRLEN, blocking_factor); + if(!sm->fl) + return _del_StringMem(caller, sm, 1); +/* + * Return the free-list container. + */ + return sm; +} + +/*....................................................................... + * Delete a string free-list. + * + * Input: + * caller const char * The name of the calling function, or NULL to + * not report errors to stderr. + * sm StringMem * The string free-list to be deleted, or NULL. + * force int If force==0 then _del_StringMem() will complain + * and refuse to delete the free-list if any + * of nodes have not been returned to the free-list. + * If force!=0 then _del_StringMem() will not check + * whether any nodes are still in use and will + * always delete the list. + * Output: + * return StringMem * Always NULL (even if the list couldn't be + * deleted). + */ +StringMem *_del_StringMem(const char *caller, StringMem *sm, int force) +{ + if(sm) { +/* + * Check whether any strings have not been returned to the free-list. + */ + if(!force && (sm->nmalloc > 0 || _busy_FreeListNodes(sm->fl) > 0)) { + if(caller) + fprintf(stderr, "_del_StringMem (%s): Free-list in use.\n", caller); + return NULL; + }; +/* + * Delete the free-list. + */ + sm->fl = _del_FreeList(caller, sm->fl, force); +/* + * Delete the container. + */ + free(sm); + }; + return NULL; +} + +/*....................................................................... + * Allocate an array of 'length' chars. + * + * Input: + * sm StringMem * The string free-list to allocate from. + * length size_t The length of the new string (including '\0'). + * Output: + * return char * The new string or NULL on error. + */ +char *_new_StringMemString(StringMem *sm, size_t length) +{ + char *string; /* The string to be returned */ + int was_malloc; /* True if malloc was used to allocate the string */ +/* + * Check arguments. + */ + if(!sm) + return NULL; + if(length < 1) + length = 1; +/* + * Allocate the new node from the free list if possible. + */ + if(length < SM_STRLEN) { + string = (char *)_new_FreeListNode(sm->fl); + if(!string) + return NULL; + was_malloc = 0; + } else { + string = (char *) malloc(length+1); /* Leave room for the flag byte */ + if(!string) + return NULL; +/* + * Count malloc allocations. + */ + was_malloc = 1; + sm->nmalloc++; + }; +/* + * Use the first byte of the string to record whether the string was + * allocated with malloc or from the free-list. Then return the rest + * of the string for use by the user. + */ + string[0] = (char) was_malloc; + return string + 1; +} + +/*....................................................................... + * Free a string that was previously returned by _new_StringMemString(). + * + * Input: + * sm StringMem * The free-list from which the string was originally + * allocated. + * s char * The string to be returned to the free-list, or NULL. + * Output: + * return char * Always NULL. + */ +char *_del_StringMemString(StringMem *sm, char *s) +{ + int was_malloc; /* True if the string originally came from malloc() */ +/* + * Is there anything to be deleted? + */ + if(s && sm) { +/* + * Retrieve the true string pointer. This is one less than the one + * returned by _new_StringMemString() because the first byte of the + * allocated memory is reserved by _new_StringMemString as a flag byte + * to say whether the memory was allocated from the free-list or directly + * from malloc(). + */ + s--; +/* + * Get the origination flag. + */ + was_malloc = s[0]; + if(was_malloc) { + free(s); + s = NULL; + sm->nmalloc--; + } else { + s = (char *) _del_FreeListNode(sm->fl, s); + }; + }; + return NULL; +} diff --git a/libtecla-1.4.1/strngmem.h b/libtecla-1.4.1/strngmem.h new file mode 100644 index 0000000..5737ae0 --- /dev/null +++ b/libtecla-1.4.1/strngmem.h @@ -0,0 +1,80 @@ +#ifndef stringmem_h +#define stringmem_h +/* + * Copyright (c) 2000, 2001 by Martin C. Shepherd. + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +typedef struct StringMem StringMem; + +/* + * Applications that dynamically allocate lots of small strings + * run the risk of significantly fragmenting the heap. This module + * aims to reduce this risk by allocating large arrays of small fixed + * length strings, arranging them as a free-list and allowing + * callers to allocate from the list. Strings that are too long + * to be allocated from the free-list are allocated from the heap. + * Since typical implementations of malloc() eat up a minimum of + * 16 bytes per call to malloc() [because of alignment and space + * management constraints] it makes sense to set the free-list + * string size to 16 bytes. Note that unlike malloc() which typically + * keeps 8 bytes per allocation for its own use, our allocator will + * return all but one of the 16 bytes for use. One hidden byte of overhead + * is reserved for flagging whether the string was allocated directly + * from malloc or from the free-list. + */ + +/* + * Set the length of each free-list string. The longest string that + * will be returned without calling malloc() will be one less than + * this number. + */ +#define SM_STRLEN 16 + +/* + * Create a string free-list container and the first block of its free-list. + */ +StringMem *_new_StringMem(const char *caller, unsigned blocking_factor); + +/* + * Delete a string free-list. + */ +StringMem *_del_StringMem(const char *caller, StringMem *sm, int force); + +/* + * Allocate an array of 'length' chars. + */ +char *_new_StringMemString(StringMem *sm, size_t size); + +/* + * Free a string that was previously returned by _new_StringMemString(). + */ +char *_del_StringMemString(StringMem *sm, char *s); + +#endif diff --git a/libtecla-1.4.1/update_html b/libtecla-1.4.1/update_html new file mode 100755 index 0000000..35625a7 --- /dev/null +++ b/libtecla-1.4.1/update_html @@ -0,0 +1,35 @@ +#!/bin/sh + +# Convert man pages to html files. + +cd man3 +for page in *.3;do + if [ "`wc -l $page | awk '{print $1}'`" -gt 1 ]; then + html="../html/`echo $page | sed -e 's/.3$/.html/'`" + man2html $page > $html + for ref in "libtecla(3)" "cpl_complete_word(3)" "ef_expand_file(3)" "gl_get_line(3)" "pca_lookup_file(3)" "enhance(3)"; do + link="`echo $ref | sed 's/(3)/.html/'`" + ed -s $html << EOF + 1,\$s|$ref|&|g + w + q +EOF + done + fi +done + +# Convert the change log into a web page. + +cd ../html +echo 'The tecla library change log' > changes.html +echo '
    ' >> changes.html
    +cat ../CHANGES >> changes.html
    +echo '
    ' >> changes.html + +# Do the same to the release-notes file. + +cd ../html +echo 'The tecla library release notes' > release.html +echo '
    ' >> release.html
    +cat ../RELEASE.NOTES >> release.html
    +echo '
    ' >> release.html diff --git a/libtecla-1.4.1/update_version b/libtecla-1.4.1/update_version new file mode 100755 index 0000000..c18f714 --- /dev/null +++ b/libtecla-1.4.1/update_version @@ -0,0 +1,82 @@ +#!/bin/sh +#----------------------------------------------------------------------- +# Change the version number of the library. This changes the number in +# every file that it is known to appear in. +# +# Usage: +# update_version major minor micro +#----------------------------------------------------------------------- + +usage="$0 major minor micro" + +if [ $# -ne 3 ]; then + echo $usage + exit 1 +fi + +# Get the three components of the version number. + +major="$1" +minor="$2" +micro="$3" + +# Everything will need to be reconfigured after this change, so +# discard any existing configuration. + +make distclean 2>/dev/null + +# Check that the version components are all positive integers. + +for c in $major $minor $micro; do + if echo "$c" | awk '{exit $1 ~ /^[0-9]+$/}'; then + echo 'Version number components must all be positive integers.' + exit 1 + fi +done + +# +# Update the version number in the configure.in script. +# +ed -s configure.in << EOF +/^MAJOR_VER=\"[0-9][0-9]*\"/ s/^.*$/MAJOR_VER=\"$major\"/ +/^MINOR_VER=\"[0-9][0-9]*\"/ s/^.*$/MINOR_VER=\"$minor\"/ +/^MICRO_VER=\"[0-9][0-9]*\"/ s/^.*$/MICRO_VER=\"$micro\"/ +w +q +EOF + +if which autoconf 1>/dev/null 2>&1; then + autoconf +else + echo 'Note that autoconf needs to be run.' +fi + +# +# Update the version number in the libtecla header file script. +# +ed -s libtecla.h << EOF +/^#define TECLA_MAJOR_VER [0-9][0-9]*/ s/^.*$/#define TECLA_MAJOR_VER $major/ +/^#define TECLA_MINOR_VER [0-9][0-9]*/ s/^.*$/#define TECLA_MINOR_VER $minor/ +/^#define TECLA_MICRO_VER [0-9][0-9]*/ s/^.*$/#define TECLA_MICRO_VER $micro/ +w +q +EOF + +# +# Update the version number in the README file. +# +ed -s README << EOF +/version [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* / s/version [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/version $major.$minor.$micro/ +w +q +EOF + +# +# Update the version number in the html index file. +# +ed -s html/index.html << EOF +/version [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\./ s/version [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*/version $major.$minor.$micro/g +/libtecla-[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\./ s/libtecla-[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\./libtecla-$major.$minor.$micro./g +w +q +EOF diff --git a/libtecla-1.4.1/version.c b/libtecla-1.4.1/version.c new file mode 100644 index 0000000..9e1275e --- /dev/null +++ b/libtecla-1.4.1/version.c @@ -0,0 +1,30 @@ +#include "libtecla.h" + +/*....................................................................... + * Return the version number of the tecla library. + * + * Input: + * major int * The major version number of the library + * will be assigned to *major. This number is + * only incremented when a change to the library is + * made that breaks binary (shared library) and/or + * compilation backwards compatibility. + * minor int * The minor version number of the library + * will be assigned to *minor. This number is + * incremented whenever new functions are added to + * the public API. + * micro int * The micro version number of the library will be + * assigned to *micro. This number is incremented + * whenever internal changes are made that don't + * change the public API, such as bug fixes and + * performance enhancements. + */ +void libtecla_version(int *major, int *minor, int *micro) +{ + if(major) + *major = TECLA_MAJOR_VER; + if(minor) + *minor = TECLA_MINOR_VER; + if(micro) + *micro = TECLA_MICRO_VER; +} diff --git a/ncurses-5.2/ANNOUNCE b/ncurses-5.2/ANNOUNCE new file mode 100644 index 0000000..7b5f4ef --- /dev/null +++ b/ncurses-5.2/ANNOUNCE @@ -0,0 +1,486 @@ + + Announcing ncurses 5.2 + + The ncurses (new curses) library is a free software emulation of + curses in System V Release 4.0, and more. It uses terminfo format, + supports pads and color and multiple highlights and forms characters + and function-key mapping, and has all the other SYSV-curses + enhancements over BSD curses. + + In mid-June 1995, the maintainer of 4.4BSD curses declared that he + considered 4.4BSD curses obsolete, and is encouraging the keepers of + Unix releases such as BSD/OS, freeBSD and netBSD to switch over to + ncurses. + + The ncurses code was developed under GNU/Linux. It should port easily + to any ANSI/POSIX-conforming UNIX. It has even been ported to OS/2 + Warp! + + The distribution includes the library and support utilities, including + a terminfo compiler tic(1), a decompiler infocmp(1), clear(1), + tput(1), tset(1), and a termcap conversion tool captoinfo(1). Full + manual pages are provided for the library and tools. + + The ncurses distribution is available via anonymous FTP at the GNU + distribution site [1]ftp://ftp.gnu.org/pub/gnu/ncurses. + It is also available at [2]ftp://dickey.his.com/ncurses. + + Release Notes + + This release is designed to be upward compatible from ncurses 5.0 and + 5.1; very few applications will require recompilation, depending on + the platform. These are the highlights from the change-log since + ncurses 5.1 release. + + Interface changes: + * change type of ospeed variable back to short to match its use in + legacy applications. It was altered after ncurses 4.2 to speed_t + to repair a type mismatch which was introduced after 1.9.4 in + 1995. The principal users of termcap continued to use short, which + is not the same size. + NOTE: A few applications will have to be recompiled (about 1% of + the programs in a typical Linux distribution, 10% of the programs + that use ncurses). These are easy to identify with nm or strings. + * remove a private function _nc_can_clear_with(), which was built + with the configure --enable-expanded option but not used. + * add several private functions (prefixed with "_nc_") for tracing + chtype values in the debug library, and for better access and + buffer limit checking. + + New features and improvements: + * rewrote tgoto() to make it better support existing termcap + applications which use hardcoded strings rather than obtain all of + their information from the termcap file. If the string does not + appear to be a terminfo string (i.e., does not refer to a "%p" + parameter, or terminfo-style padding), and termcap support is + configured, tgoto() will interpret it as termcap. Otherwise, as + before, it will use tparm(). + * to ensure that the tgoto() changes work properly, added checks to + tic which report capabilities that do not reference the expected + number of parameters. + * new configure script options: + + option --disable-root-environ adds runtime checks which tell + ncurses to disregard $TERMINFO and similar environment + variables if the current user is root, or running + setuid/setgid. + + option --disable-assumed-color allows you to use the pre-5.1 + convention of default colors used for color-pair 0 to be + configured (see assume_default_colors()). + + implement configure script options that transform installed + program names, e.g., --program-prefix, including the manpage + names and cross references. + + option --with-database allows you to specify a different + terminfo source-file to install. On OS/2 EMX, the default is + misc/emx.src, otherwise misc/terminfo.src + + option --with-default-terminfo-dir allows you to specify the + default terminfo database directory. + + option --with-libtool allows you to build with libtool. + NOTE: libtool uses a different notation for numbering shared + library versions from the existing ncurses configuration. + + option --with-manpage-tbl causes the manpages to be + preprocessed by tbl(1) prior to installation, + + option --without-curses-h causes the installation process to + install curses.h as ncurses.h and make appropriate changes to + headers and manpages. + * modified configure script options: + + change symbol used by the --install-prefix configure option + from INSTALL_PREFIX to DESTDIR (the latter has become common + usage although the name is misleading). + + modify ld -rpath options (e.g., Linux, and Solaris) to use an + absolute pathname for the build tree's lib directory, + avoiding confusion with directories relative to the current + one with the installed programs. + + modified misc/run_tic.in to use tic -o, to eliminate + dependency on $TERMINFO variable for installs. + * terminfo database: + + updated xterm terminfo entries to match XFree86 xterm patch + #146. + + added amiga-vnc, Matrix Orbital, and QNX qansi to + misc/terminfo.src. + + added os2 entry to misc/emx.src. + + add S0 and E0 extensions to screen's terminfo entry since + otherwise the FreeBSD port makes it pass termcap equivalents + to tgoto, which would be misinterpreted by older versions of + ncurses. + * improvements to program usability: + + modify programs to use curses_version() string to report the + version of ncurses with which they are compiled rather than + the NCURSES_VERSION string. The function returns the patch + level in addition to the major and minor version numbers. + + modify tput program so it can be renamed or invoked via a + link as 'reset' or 'init', producing the same effect as + tput reset or tput init. + + add error checking to infocmp's -v and -m options to ensure + that the option value is indeed a number. + * improved performance: + + replace a lookup table in lib_vidattr.c used to decode + no_color_video with a logic expression which is faster. + + Major bug fixes: + * correct manlinks.sed script introduced in ncurses 5.1 to avoid + using ERE "\+", which is not understood by standard versions of + sed. This happens to work with GNU sed, but is not portable, and + was the initial motivation for this release. + * remove "hpux10.*" case from CF_SHARED_OPTS configure script macro. + This differed from the "hpux*" case by using reversed symbolic + links, which made the 5.1 version not match the configuration of + 5.0 shared libraries. + * guard against corrupt terminfo data: + + modify tparm() to disallow arithmetic on strings, analyze the + varargs list to read strings as strings and numbers as + numbers. + + modify tparm()'s internal function spop() to treat a null + pointer as an empty string. + + modify parse_format() in lib_tparm.c to ignore precision if + it is longer than 10000. + + rewrote limit checks in lib_mvcur.c using new functions + _nc_safe_strcat(), etc. Made other related changes to check + lengths used for strcat() and strcpy(). + * corrections to screen optimization: + + added special case in lib_vidattr.c to reset underline and + standout for devices that have no sgr0 defined. + + change handling of non_dest_scroll_region in tty_update.c to + clear text after it is shifted in rather than before shifting + out. Also correct row computation. + + modify rs2 capability in xterm-r6 and similar entries where + cursor save/restore bracketed the sequence for resetting + video attributes. The cursor restore would undo that. + * UTF-8 support: + + when checking LC_ALL, LC_CTYPE, and LANG environment + variables for UTF-8 locale, ignore those which are set to an + empty value, as per SUSV2. + + encode 0xFFFD in UTF-8 with 3 bytes, not 2. + + modify _nc_utf8_outch() to avoid sign-extension when checking + for out-of-range value. + * other library fixes: + + added checks for an empty $HOME environment variable, to + avoid retrieving terminfo descriptions from ./.terminfo . + + change functions _nc_parse_entry() and postprocess_termcap() + to avoid using strtok(), because it is non-reentrant. + + initialize fds[] array to 0's in _nc_timed_wait(); apparently + poll() only sets the revents members of that array when there + is activity corresponding to the related file. + + add a check for null pointer in Make_Enum_Type(). + + fix a heap problem with the c++ binding. + + correct missing includes for in several places, + including the C++ binding. This is not noted by gcc unless we + use the -fno-builtin option. + * several fixes for tic: + + add a check for empty buffers returned by fgets() in + comp_scan.c next_char() function, in case tic is run on a + non-text file (fixes a core dump). + + modify tic to verify that its inputs are really files, in + case someone tries to read a directory (or /dev/zero). + + correct an uninitialized parameter to open_tempfile() in + tic.c which made "tic -I" give an ambiguous error message + about tmpnam. + + correct logic in adjust_cancels(), which did not check both + alternatives when reclassifying an extended name between + boolean, number and string, causing an infinite loop in tic. + * using new checks in tic for parameter counts in capability + strings, found/fixed several errors both in the terminfo database + and in the include/Caps file. + + modified several terminfo capability strings, including the + definitions for setaf, setab, in include/Caps to indicate + that the entries are parameterized. This information is used + to tell which strings are translated when converting to + termcap. This fixes a problem where the generated termcap + would contain a spurious "%p1" for the terminfo "%p1%d". + + correct parameter counts in include/Caps for dclk as well as + some printer-specific capabilities: csnm, defc, scs, scsd, + smgtp, smglp. + * various fixes for install scripts used to support configure + --srcdir and --with-install-prefix. + * correct several mismatches between manpage filename and ".TH" + directives, renaming dft_fgbg.3x to default_colors.3x and + menu_attribs.3x to menu_attributes.3x. + + Portability: + * configure script: + + newer config.guess, config.sub, including changes to support + OS/2 EMX. The configure script for OS/2 EMX still relies on a + patch since there is no (working) support for that platform + in the main autoconf distribution. + + make configure script checks on variables $GCC and $GXX + consistently compare against 'yes' rather than test if they + are nonnull, since either may be set to the corresponding + name of the C or C++ compiler. + + change configure script to use AC_CANONICAL_SYSTEM rather + than AC_CANONICAL_HOST, which means that configure --target + will set a default program-prefix. + + modify the check for big-core to force a couple of memory + accesses, which may work as needed for older/less-capable + machines (if not, there's still the explicit configure + option). + + modify configure test for tcgetattr() to allow for old + implementations, e.g., on BeOS, which only defined it as a + macro. + + add configure check for filesystems (such as OS/2 EMX) which + do not distinguish between upper/lowercase filenames, use + this to fix tags rules in makefiles. + + add MKncurses_def.sh to generate fallback definitions for + ncurses_cfg.h, to quiet gcc -Wundef warnings, modified + ifdef's in code to consistently use "#if" rather than + "#ifdef". + + change most remaining unquoted parameters of test in + configure script to use quotes, for instance fixing a problem + in the --disable-database option. + + modify scripts so that "make install.data" works on OS/2 EMX. + + modify scripts and makefiles so the Ada95 directory builds on + OS/2 EMX. + * library: + + replaced case-statement in _nc_tracebits() for CSIZE with a + table to simplify working around implementations that define + random combinations of the related macros to zero. + + improved OS/2 mouse support by retrying as a 2-button mouse + if code fails to set up a 3-button mouse. + + added private entrypoint _nc_basename(), used to consolidate + related code in progs, as well as accommodating OS/2 EMX + pathnames. + + alter definition of NCURSES_CONST to make it non-empty. + + redefine 'TEXT' in menu.h for AMIGA, since it is reported to + have an (unspecified) symbol conflict. + * programs: + + modified progs/tset.c and tack/sysdep.c to build with sgttyb + interface if neither termio or termios is available. Tested + this with FreeBSD 2.1.5 (which does have termios - but the + sgttyb does work). + + Features of Ncurses + + The ncurses package is fully compatible with SVr4 (System V Release 4) + curses: + * All 257 of the SVr4 calls have been implemented (and are + documented). + * Full support for SVr4 curses features including keyboard mapping, + color, forms-drawing with ACS characters, and automatic + recognition of keypad and function keys. + * An emulation of the SVr4 panels library, supporting a stack of + windows with backing store, is included. + * An emulation of the SVr4 menus library, supporting a uniform but + flexible interface for menu programming, is included. + * An emulation of the SVr4 form library, supporting data collection + through on-screen forms, is included. + * Binary terminfo entries generated by the ncurses tic(1) + implementation are bit-for-bit-compatible with the entry format + SVr4 curses uses. + * The utilities have options to allow you to filter terminfo entries + for use with less capable curses/terminfo versions such as the + HP/UX and AIX ports. + + The ncurses package also has many useful extensions over SVr4: + * The API is 8-bit clean and base-level conformant with the X/OPEN + curses specification, XSI curses (that is, it implements all BASE + level features, but not all EXTENDED features). Most + EXTENDED-level features not directly concerned with wide-character + support are implemented, including many function calls not + supported under SVr4 curses (but portability of all calls is + documented so you can use the SVr4 subset only). + * Unlike SVr3 curses, ncurses can write to the rightmost-bottommost + corner of the screen if your terminal has an insert-character + capability. + * Ada95 and C++ bindings. + * Support for mouse event reporting with X Window xterm and OS/2 + console windows. + * Extended mouse support via Alessandro Rubini's gpm package. + * The function wresize() allows you to resize windows, preserving + their data. + * The function use_default_colors() allows you to use the terminal's + default colors for the default color pair, achieving the effect of + transparent colors. + * The functions keyok() and define_key() allow you to better control + the use of function keys, e.g., disabling the ncurses KEY_MOUSE, + or by defining more than one control sequence to map to a given + key code. + * Support for 16-color terminals, such as aixterm and XFree86 xterm. + * Better cursor-movement optimization. The package now features a + cursor-local-movement computation more efficient than either BSD's + or System V's. + * Super hardware scrolling support. The screen-update code + incorporates a novel, simple, and cheap algorithm that enables it + to make optimal use of hardware scrolling, line-insertion, and + line-deletion for screen-line movements. This algorithm is more + powerful than the 4.4BSD curses quickch() routine. + * Real support for terminals with the magic-cookie glitch. The + screen-update code will refrain from drawing a highlight if the + magic- cookie unattributed spaces required just before the + beginning and after the end would step on a non-space character. + It will automatically shift highlight boundaries when doing so + would make it possible to draw the highlight without changing the + visual appearance of the screen. + * It is possible to generate the library with a list of pre-loaded + fallback entries linked to it so that it can serve those terminal + types even when no terminfo tree or termcap file is accessible + (this may be useful for support of screen-oriented programs that + must run in single-user mode). + * The tic(1)/captoinfo utility provided with ncurses has the ability + to translate many termcaps from the XENIX, IBM and AT&T extension + sets. + * A BSD-like tset(1) utility is provided. + * The ncurses library and utilities will automatically read terminfo + entries from $HOME/.terminfo if it exists, and compile to that + directory if it exists and the user has no write access to the + system directory. This feature makes it easier for users to have + personal terminfo entries without giving up access to the system + terminfo directory. + * You may specify a path of directories to search for compiled + descriptions with the environment variable TERMINFO_DIRS (this + generalizes the feature provided by TERMINFO under stock System + V.) + * In terminfo source files, use capabilities may refer not just to + other entries in the same source file (as in System V) but also to + compiled entries in either the system terminfo directory or the + user's $HOME/.terminfo directory. + * A script (capconvert) is provided to help BSD users transition + from termcap to terminfo. It gathers the information in a TERMCAP + environment variable and/or a ~/.termcap local entries file and + converts it to an equivalent local terminfo tree under + $HOME/.terminfo. + * Automatic fallback to the /etc/termcap file can be compiled in + when it is not possible to build a terminfo tree. This feature is + neither fast nor cheap, you don't want to use it unless you have + to, but it's there. + * The table-of-entries utility toe makes it easy for users to see + exactly what terminal types are available on the system. + * The library meets the XSI requirement that every macro entry point + have a corresponding function which may be linked (and will be + prototype-checked) if the macro definition is disabled with + #undef. + * An HTML "Introduction to Programming with NCURSES" document + provides a narrative introduction to the curses programming + interface. + + State of the Package + + Numerous bugs present in earlier versions have been fixed; the library + is far more reliable than it used to be. Bounds checking in many + `dangerous' entry points has been improved. The code is now type-safe + according to gcc -Wall. The library has been checked for malloc leaks + and arena corruption by the Purify memory-allocation tester. + + The ncurses code has been tested with a wide variety of applications + including (versions starting with those noted): + + cdk + Curses Development Kit + [3]http://www.vexus.ca/CDK.html + [4]http://dickey.his.com/cdk. + + ded + directory-editor + [5]http://dickey.his.com/ded. + + dialog + the underlying application used in Slackware's setup, and the + basis for similar applications on GNU/Linux. + [6]http://dickey.his.com/dialog. + + lynx + the character-screen WWW browser + [7]http://lynx.isc.org/release. + + Midnight Commander 4.1 + file manager + [8]www.gnome.org/mc/. + + mutt + mail utility + [9]http://www.mutt.org. + + ncftp + file-transfer utility + [10]http://www.ncftp.com. + + nvi + New vi versions 1.50 are able to use ncurses versions 1.9.7 and + later. + [11]http://www.bostic.com/vi/. + + tin + newsreader, supporting color, MIME + [12]http://www.tin.org. + + taper + tape archive utility + [13]http://members.iinet.net.au/~yusuf/taper/. + + vh-1.6 + Volks-Hypertext browser for the Jargon File + [14]http://www.bg.debian.org/Packages/unstable/text/vh.html. + + as well as some that use ncurses for the terminfo support alone: + + minicom + terminal emulator + [15]http://www.pp.clinet.fi/~walker/minicom.html. + + vile + vi-like-emacs + [16]http://dickey.his.com/vile. + + The ncurses distribution includes a selection of test programs + (including a few games). + +Who's Who and What's What + + The original developers of ncurses are [17]Zeyd Ben-Halim and [18]Eric + S. Raymond. Ongoing work is being done by [19]Thomas Dickey and + [20]Jürgen Pfeifer. [21]Thomas Dickey acts as the maintainer for the + Free Software Foundation, which holds the copyright on ncurses. + Contact the current maintainers at [22]bug-ncurses@gnu.org. + + To join the ncurses mailing list, please write email to + bug-ncurses-request@gnu.org containing the line: + subscribe @ + + This list is open to anyone interested in helping with the development + and testing of this package. + + Beta versions of ncurses and patches to the current release are made + available at [23]ftp://dickey.his.com/ncurses. + +Future Plans + + * Extended-level XPG4 conformance, with internationalization + support. + * Ports to more systems, including DOS and Windows. + + We need people to help with these projects. If you are interested in + working on them, please join the ncurses list. + +Other Related Resources + + The distribution includes and uses a version of the terminfo-format + terminal description file maintained by Eric Raymond. + [24]http://earthspace.net/~esr/terminfo. + + You can find lots of information on terminal-related topics not + covered in the terminfo file at [25]Richard Shuford's archive. + +References + + 1. ftp://ftp.gnu.org/pub/gnu/ncurses + 2. ftp://dickey.his.com/ncurses + 3. http://www.vexus.ca/CDK.html + 4. http://dickey.his.com/cdk/cdk.html + 5. http://dickey.his.com/ded/ded.html + 6. http://dickey.his.com/dialog/dialog.html + 7. http://lynx.isc.org/release/ + 8. file://localhost/usr/build/ncurses/ncurses-5.2-20001021/doc/html/www.gnome.org/mc/ + 9. http://www.mutt.org/ + 10. http://www.ncftp.com/ + 11. http://www.bostic.com/vi/ + 12. http://www.tin.org/ + 13. http://members.iinet.net.au/~yusuf/taper/ + 14. http://www.bg.debian.org/Packages/unstable/text/vh.html + 15. http://www.pp.clinet.fi/~walker/minicom.html + 16. http://dickey.his.com/vile/vile.html + 17. mailto:zmbenhal@netcom.com + 18. http://www.ccil.org/~esr/home.html + 19. mailto:dickey@herndon4.his.com + 20. mailto:juergen.pfeifer@gmx.net + 21. mailto:dickey@herndon4.his.com + 22. mailto:bug-ncurses@gnu.org + 23. ftp://dickey.his.com/ncurses + 24. http://earthspace.net/~esr/terminfo + 25. http://www.cs.utk.edu/~shuford/terminal_index.html diff --git a/ncurses-5.2/Ada95/Makefile.in b/ncurses-5.2/Ada95/Makefile.in new file mode 100644 index 0000000..8dcf186 --- /dev/null +++ b/ncurses-5.2/Ada95/Makefile.in @@ -0,0 +1,67 @@ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Juergen Pfeifer 1996 +# +# Version Control +# $Revision$ +# +SHELL = /bin/sh +THIS = Makefile + +SUBDIRS = @ADA_SUBDIRS@ + +CF_MFLAGS = @cf_cv_makeflags@ +@SET_MAKE@ + +all \ +libs \ +sources \ +install \ +install.libs \ +uninstall \ +uninstall.libs :: + for d in $(SUBDIRS); do \ + (cd $$d ; $(MAKE) $(CF_MFLAGS) $@) ;\ + done + +clean \ +mostlyclean :: + for d in $(SUBDIRS); do \ + (cd $$d ; $(MAKE) $(CF_MFLAGS) $@) ;\ + done + +distclean \ +realclean :: + for d in $(SUBDIRS); do \ + (cd $$d ; $(MAKE) $(CF_MFLAGS) $@) ;\ + done + rm -f Makefile + +install.data : + @ diff --git a/ncurses-5.2/Ada95/README b/ncurses-5.2/Ada95/README new file mode 100644 index 0000000..8a53061 --- /dev/null +++ b/ncurses-5.2/Ada95/README @@ -0,0 +1,33 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell copies -- +-- of the Software, and to permit persons to whom the Software is furnished -- +-- to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -- +-- NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -- +-- USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------- + +-- Author: Juergen Pfeifer 1996 + +The documentation is provided in HTML format in the ./html +subdirectory. The main document is named index.html + diff --git a/ncurses-5.2/Ada95/TODO b/ncurses-5.2/Ada95/TODO new file mode 100644 index 0000000..ece4d96 --- /dev/null +++ b/ncurses-5.2/Ada95/TODO @@ -0,0 +1,27 @@ +-- $Id$ + +-- Intensive testing + Perhaps the delivery of the Beta will help a bit. + +-- Documentation + Like most WEB pages: under continuous construction + +-- Style cleanup + +-- Alternate functions for procedures with out params + Comfort purpose + +-- Sample program + Under continuous construction (and it's not a WEB page!!!) + +-- Make the binding objects a shared library + They are rather large, so it would make sense, otherwise Ada95 + would look too large, although the generated code is as compact + as C or C++. I'll wait a bit until the GNAT people provide some + better support to construct shared libraries. + +-- Think about more inlining + +-- Check for memory leaks. + Oh I would like it so much if the GNAT guys would put an optional + GC into their system. diff --git a/ncurses-5.2/Ada95/gen/Makefile.in b/ncurses-5.2/Ada95/gen/Makefile.in new file mode 100644 index 0000000..31d3fb3 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/Makefile.in @@ -0,0 +1,429 @@ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Juergen Pfeifer 1996 +# +# Version Control +# $Revision$ +# +.SUFFIXES: + +SHELL = /bin/sh +THIS = Makefile + +x = @PROG_EXT@ + +top_srcdir = @top_srcdir@ +DESTDIR = @DESTDIR@ +srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +ADA_INCLUDE = $(DESTDIR)@ADA_INCLUDE@ +ADA_OBJECTS = $(DESTDIR)@ADA_OBJECTS@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +AWK = @AWK@ +LN_S = @LN_S@ + +HOST_CC = @BUILD_CC@ +CFLAGS = @CFLAGS@ + +CPPFLAGS = @ACPPFLAGS@ \ + -DHAVE_CONFIG_H -I$(srcdir) + +CCFLAGS = $(CPPFLAGS) $(CFLAGS) +CFLAGS_NORMAL = $(CCFLAGS) +CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE +CFLAGS_PROFILE = $(CCFLAGS) -pg +CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@ + +CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@) + +LINK = $(HOST_CC) +LD_FLAGS = @LD_MODEL@ $(LOCAL_LIBS) @LDFLAGS@ @LIBS@ @LOCAL_LDFLAGS2@ $(LDFLAGS) + +RANLIB = @RANLIB@ + +LIB_CURSES = -L../../lib -lncurses@LIB_SUFFIX@ + +M4 = m4 +M4FLAGS = + +GENERATE = ./gen$x '@DFT_ARG_SUFFIX@' +DEL_ADAMODE = sed -e '/^\-\-\ \ \-\*\-\ ada\ \-\*\-.*/d' + +GNATHTML = `type -p gnathtml || type -p gnathtml.pl` +GNATHP = www.gnat.com +MAIL = juergen.pfeifer@gmx.net +HOMEP = home.t-online.de/home/Juergen.Pfeifer + +################################################################################ +ALIB = @cf_ada_package@ +ABASE = $(ALIB)-curses + +ADA_SRCDIR = ../src + +GEN_FILES0 = Base_Defs + +GEN_FILES1 = Key_Definitions \ + Old_Keys \ + Character_Attribute_Set_Rep \ + AC_Rep \ + Color_Defs \ + ACS_Map \ + Linker_Options \ + Base_Defs \ + Window_Offsets \ + Version_Info + +GEN_FILES2 = Menu_Opt_Rep \ + Menu_Base_Defs \ + Menu_Linker_Options \ + Item_Rep + +GEN_FILES3 = Form_Opt_Rep \ + Form_Base_Defs \ + Form_Linker_Options \ + Field_Rep + +GEN_FILES4 = Mouse_Base_Defs \ + Mouse_Event_Rep \ + Mouse_Events \ + Panel_Linker_Options + +GEN_FILES5 = Chtype_Def \ + Eti_Defs + +GEN_TARGETS = $(ADA_SRCDIR)/$(ABASE).ads \ + $(ADA_SRCDIR)/$(ABASE)-aux.ads \ + $(ADA_SRCDIR)/$(ABASE)-menus.ads \ + $(ADA_SRCDIR)/$(ABASE)-forms.ads \ + $(ADA_SRCDIR)/$(ABASE)-mouse.ads \ + $(ADA_SRCDIR)/$(ABASE)-panels.ads \ + $(ADA_SRCDIR)/$(ABASE)-menus-menu_user_data.ads \ + $(ADA_SRCDIR)/$(ABASE)-menus-item_user_data.ads \ + $(ADA_SRCDIR)/$(ABASE)-forms-form_user_data.ads \ + $(ADA_SRCDIR)/$(ABASE)-forms-field_types.ads \ + $(ADA_SRCDIR)/$(ABASE)-forms-field_user_data.ads \ + $(ADA_SRCDIR)/$(ABASE)-panels-user_data.ads + +GEN_SRC = $(srcdir)/$(ABASE).ads.m4 \ + $(srcdir)/$(ABASE)-aux.ads.m4 \ + $(srcdir)/$(ABASE)-menus.ads.m4 \ + $(srcdir)/$(ABASE)-forms.ads.m4 \ + $(srcdir)/$(ABASE)-mouse.ads.m4 \ + $(srcdir)/$(ABASE)-panels.ads.m4 \ + $(srcdir)/$(ABASE)-menus-menu_user_data.ads.m4 \ + $(srcdir)/$(ABASE)-menus-item_user_data.ads.m4 \ + $(srcdir)/$(ABASE)-forms-form_user_data.ads.m4 \ + $(srcdir)/$(ABASE)-forms-field_types.ads.m4 \ + $(srcdir)/$(ABASE)-forms-field_user_data.ads.m4 \ + $(srcdir)/$(ABASE)-panels-user_data.ads.m4 + + +all \ +libs : $(GEN_TARGETS) + @ + +sources: + +$(ADA_INCLUDE) \ +$(ADA_OBJECTS) : + $(top_srcdir)/mkinstalldirs $@ + +install \ +install.libs :: $(ADA_INCLUDE) + @echo installing package $(ALIB) in $(ADA_INCLUDE) + @$(top_srcdir)/tar-copy.sh '$(ALIB)[-.]*.ad?' $(ADA_SRCDIR) $(ADA_INCLUDE) + @test $(srcdir) != ./ && $(top_srcdir)/tar-copy.sh '$(ALIB)[-.]*.ad?' $(srcdir)/../src $(ADA_INCLUDE) + +install \ +install.libs :: $(ADA_OBJECTS) + @echo installing package $(ALIB) in $(ADA_OBJECTS) + @chmod a-wx $(ADA_SRCDIR)/*.ali + @$(top_srcdir)/tar-copy.sh '$(ALIB)[-.]*.ali' $(ADA_SRCDIR) $(ADA_OBJECTS) + @chmod u+x $(ADA_SRCDIR)/*.ali + +uninstall \ +uninstall.libs :: + @echo removing package $(ALIB) from $(ADA_INCLUDE) + -@cd $(ADA_INCLUDE) && rm -f $(ALIB)[-.]* + +uninstall \ +uninstall.libs :: + @echo removing package $(ALIB) from $(ADA_OBJECTS) + -@cd $(ADA_OBJECTS) && rm -f $(ALIB)[-.]* + +gen$x: gen.o + @ECHO_LINK@ $(LINK) $(CFLAGS_NORMAL) gen.o $(LD_FLAGS) -o $@ $(LIB_CURSES) + +gen.o: $(srcdir)/gen.c + $(HOST_CC) $(CFLAGS_NORMAL) -c -o $@ $(srcdir)/gen.c + +Character_Attribute_Set_Rep: gen$x + $(GENERATE) B A >$@ + +Base_Defs: gen$x + $(GENERATE) B B >$@ + +Color_Defs: gen$x + $(GENERATE) B C >$@ + +Key_Definitions: gen$x + $(GENERATE) B K >$@ + +Old_Keys: gen$x + $(GENERATE) B O >$@ + +ACS_Map: gen$x + $(GENERATE) B M >$@ + +AC_Rep: gen$x + $(GENERATE) B R >$@ + +Linker_Options: gen$x + $(GENERATE) B L >$@ + +Version_Info: gen$x + $(GENERATE) B V >$@ + +Window_Offsets: gen$x + $(GENERATE) B D >$@ + +Menu_Opt_Rep: gen$x + $(GENERATE) M R >$@ + +Menu_Base_Defs: gen$x + $(GENERATE) M B >$@ + +Menu_Linker_Options: gen$x + $(GENERATE) M L >$@ + +Item_Rep: gen$x + $(GENERATE) M I >$@ + +Form_Opt_Rep: gen$x + $(GENERATE) F R >$@ + +Form_Base_Defs: gen$x + $(GENERATE) F B >$@ + +Form_Linker_Options: gen$x + $(GENERATE) F L >$@ + +Field_Rep: gen$x + $(GENERATE) F I >$@ + +Mouse_Base_Defs: gen$x + $(GENERATE) P B >$@ + +Mouse_Event_Rep: gen$x + $(GENERATE) P M >$@ + +Mouse_Events: gen$x + $(GENERATE) B E >$@ + +Panel_Linker_Options: gen$x + $(GENERATE) P L >$@ + +Chtype_Def: gen$x + $(GENERATE) E C >$@ + +Eti_Defs: gen$x + $(GENERATE) E E >$@ + +$(ADA_SRCDIR)/$(ABASE).ads: $(srcdir)/$(ABASE).ads.m4 \ + $(GEN_FILES1) $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE).ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-aux.ads: $(srcdir)/$(ABASE)-aux.ads.m4 \ + $(GEN_FILES5) $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-aux.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-menus.ads: $(srcdir)/$(ABASE)-menus.ads.m4 \ + $(GEN_FILES2) $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-menus.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-forms.ads: $(srcdir)/$(ABASE)-forms.ads.m4 \ + $(GEN_FILES3) $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-forms.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-mouse.ads: $(srcdir)/$(ABASE)-mouse.ads.m4 \ + $(GEN_FILES4) $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-mouse.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-panels.ads: $(srcdir)/$(ABASE)-panels.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-panels.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-menus-menu_user_data.ads: \ + $(srcdir)/$(ABASE)-menus-menu_user_data.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-menus-menu_user_data.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-menus-item_user_data.ads: \ + $(srcdir)/$(ABASE)-menus-item_user_data.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-menus-item_user_data.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-forms-form_user_data.ads: \ + $(srcdir)/$(ABASE)-forms-form_user_data.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-forms-form_user_data.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-forms-field_types.ads: \ + $(srcdir)/$(ABASE)-forms-field_types.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-forms-field_types.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-forms-field_user_data.ads: \ + $(srcdir)/$(ABASE)-forms-field_user_data.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-forms-field_user_data.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +$(ADA_SRCDIR)/$(ABASE)-panels-user_data.ads: \ + $(srcdir)/$(ABASE)-panels-user_data.ads.m4 \ + $(srcdir)/normal.m4 + $(M4) $(M4FLAGS) -DM4MACRO=$(srcdir)/normal.m4 \ + $(srcdir)/$(ABASE)-panels-user_data.ads.m4 |\ + $(DEL_ADAMODE) >$@ + +install.progs :: + +tags: + ctags *.[ch] + +TAGS: + etags *.[ch] + +mostlyclean :: + -rm -f a.out core gen$x *.o + -rm -f $(GEN_FILES1) + -rm -f $(GEN_FILES2) + -rm -f $(GEN_FILES3) + -rm -f $(GEN_FILES4) + -rm -f $(GEN_FILES5) + +clean :: mostlyclean + -rm -f $(GEN_TARGETS) instab.tmp *.ad[bs] *.html *.ali *.tmp + +distclean :: clean + rm -f Makefile + +realclean :: distclean + +HTML_DIR = ../../doc/html/ada + +instab.tmp : table.m4 $(GEN_SRC) + @rm -f $@ + @for f in $(GEN_SRC) ; do \ + $(M4) $(M4FLAGS) -DM4MACRO=table.m4 $$f | $(DEL_ADAMODE) >> $@ ;\ + done; + +$(HTML_DIR)/table.html : instab.tmp + @-touch $@ + @-chmod +w $@ + @echo ' $@ + @echo 'PUBLIC "-//IETF//DTD HTML 3.0//EN">' >> $@ + @echo '' >> $@ + @echo '' >> $@ + @echo 'Correspondence between ncurses C and Ada functions' >>$@ + @echo '' >> $@ + @echo '' >> $@ + @echo '

    Correspondence between ncurses C and Ada functions

    ' >>$@ + @echo '

    Sorted by C function name

    ' >>$@ + @echo '' >>$@ + @echo '' >>$@ + @echo '' >>$@ + @sort < instab.tmp >> $@ + @echo '
    C nameAda nameman page
    ' >>$@ + @rm -f instab.tmp + +adahtml: + @rm -rf $(HTML_DIR)/ + @mkdir -p $(HTML_DIR) + cp -p ../src/*.ad[sb] . && chmod +w *.ad[sb] + ln -sf ../src/*.ali . + for f in $(GEN_SRC); do \ + g=`basename $$f .ads.m4` ;\ + $(M4) $(M4FLAGS) -DM4MACRO=html.m4 $$f | $(DEL_ADAMODE) > $$g.ads ;\ + done + @-rm -f $(HTML_DIR)/$(ALIB)*.htm* + $(GNATHTML) -d -f $(ALIB)*.ads + for f in html/$(ALIB)*.htm*; do \ + a=`basename $$f` ; \ + sed -e 's/You may also.*body.*//' <$$f |\ + sed -e 's%GNAT%GNAT%g' |\ + sed -e 's%<A HREF%%g' |\ + sed -e 's/3X/3x/g' |\ + sed -e 's/$$\([A-Za-z0-9_]*:.*\)\$$/@\1@/' |\ + sed -e 's%Juergen Pfeifer%J\ürgen Pfeifer%g' |\ + sed -e 's%$(MAIL)%\<$(MAIL)\>%g' |\ + sed -e 's%</A>%%g' > $$a.tmp ;\ + mv $$a.tmp $$f ;\ + done + @rm -f *.ad[sb] *.ali *.tmp + @for f in funcs.htm main.htm ; do \ + sed -e "\%\[ \]%d" < html/$$f > $$f ;\ + mv $$f html/$$f ;\ + done + @rm -f "html/funcs/ .htm" + @cp -pdrf html/* $(HTML_DIR)/ + @rm -rf html + +html : adahtml $(HTML_DIR)/table.html + @ + +############################################################################### +# The remainder of this file is automatically generated during configuration +############################################################################### diff --git a/ncurses-5.2/Ada95/gen/gen.c b/ncurses-5.2/Ada95/gen/gen.c new file mode 100644 index 0000000..a566ccd --- /dev/null +++ b/ncurses-5.2/Ada95/gen/gen.c @@ -0,0 +1,1381 @@ +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1996 * + ****************************************************************************/ + +/* + Version Control + $Revision$ + --------------------------------------------------------------------------*/ +/* + This program generates various record structures and constants from the + ncurses header file for the Ada95 packages. Essentially it produces + Ada95 source on stdout, which is then merged using m4 into a template + to produce the real source. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define RES_NAME "Reserved" + +static const char *model = ""; +static int little_endian = 0; + +typedef struct { + const char *name; + unsigned long attr; +} name_attribute_pair; + +static int find_pos (char *s, unsigned len, int *low, int *high) +{ + unsigned int i,j; + int l = 0; + + *high = -1; + *low = 8*len; + + for(i=0; i < len; i++,s++) + { + if (*s) + { + for(j=0;j<8*sizeof(char);j++) + { + if ((( little_endian && ((*s)&0x01)) || + (!little_endian && ((*s)&0x80))) ) + { + if (l > *high) + *high = l; + if (l < *low) + *low = l; + } + l++; + if (little_endian) + *s >>= 1; + else + *s <<= 1; + } + } + else + l += 8; + } + return (*high >= 0 && (*low <= *high)) ? *low : -1; +} + +/* + * This helper routine generates a representation clause for a + * record type defined in the binding. + * We are only dealing with record types which are of 32 or 16 + * bit size, i.e. they fit into an (u)int or a (u)short. + */ +static void +gen_reps +(const name_attribute_pair *nap, /* array of name_attribute_pair records */ + const char *name, /* name of the represented record type */ + int len, /* size of the record in bytes */ + int bias) +{ + int i,n,l,cnt = 0,low,high; + int width = strlen(RES_NAME) + 3; + unsigned long a; + unsigned long mask = 0; + + assert (nap!=NULL); + + for (i=0; nap[i].name != (char *)0; i++) + { + cnt++; + l = strlen(nap[i].name); + if (l>width) + width = l; + } + assert (width > 0); + + printf(" type %s is\n",name); + printf(" record\n"); + for (i=0; nap[i].name != (char *)0; i++) + { + printf(" %-*s : Boolean;\n",width,nap[i].name); + } + printf(" end record;\n"); + printf(" pragma Pack (%s);\n",name); + printf(" pragma Convention (C, %s);\n\n",name); + + printf(" for %s use\n",name); + printf(" record\n"); + + for (i=0; nap[i].name != (char *)0; i++) + { + a = nap[i].attr; + mask |= a; + l = find_pos( (char *)&a,sizeof(a),&low,&high ); + if (l>=0) + printf(" %-*s at 0 range %2d .. %2d;\n",width,nap[i].name, + low-bias,high-bias); + } + i = 1; n = cnt; + printf(" end record;\n"); + printf(" for %s'Size use %d;\n", name, 8*len); + printf(" -- Please note: this rep. clause is generated and may be\n"); + printf(" -- different on your system."); +} + + +static void chtype_rep (const char *name, attr_t mask) +{ + attr_t x = -1; + attr_t t = x & mask; + int low, high; + int l = find_pos ((char *)&t, sizeof(t), &low, &high); + if (l>=0) + printf(" %-5s at 0 range %2d .. %2d;\n",name,low,high); +} + +static void gen_chtype_rep(const char *name) +{ + printf(" for %s use\n record\n",name); + chtype_rep("Ch",A_CHARTEXT); + chtype_rep("Color",A_COLOR); + chtype_rep("Attr",(A_ATTRIBUTES&~A_COLOR)); + printf(" end record;\n for %s'Size use %ld;\n", name, (long)(8*sizeof(chtype))); + printf(" -- Please note: this rep. clause is generated and may be\n"); + printf(" -- different on your system.\n"); +} + + +static void mrep_rep (const char *name, void *rec) +{ + int low, high; + int l = find_pos((char *)rec, sizeof(MEVENT), &low, &high); + if (l>=0) + printf(" %-7s at 0 range %3d .. %3d;\n",name,low,high); +} + + +static void gen_mrep_rep(const char *name) +{ + MEVENT x; + + printf(" for %s use\n record\n",name); + + memset(&x,0,sizeof(x)); + x.id = -1; + mrep_rep("Id",&x); + + memset(&x,0,sizeof(x)); + x.x = -1; + mrep_rep("X",&x); + + memset(&x,0,sizeof(x)); + x.y = -1; + mrep_rep("Y",&x); + + memset(&x,0,sizeof(x)); + x.z = -1; + mrep_rep("Z",&x); + + memset(&x,0,sizeof(x)); + x.bstate = -1; + mrep_rep("Bstate",&x); + + printf(" end record;\n"); + printf(" -- Please note: this rep. clause is generated and may be\n"); + printf(" -- different on your system.\n"); +} + +static void gen_attr_set( const char *name ) +{ + /* All of the A_xxx symbols are defined in ncurses, but not all are nonzero + * if "configure --enable-widec" is specified. + */ + static const name_attribute_pair nap[] = { +#if A_STANDOUT + {"Stand_Out", A_STANDOUT}, +#endif +#if A_UNDERLINE + {"Under_Line", A_UNDERLINE}, +#endif +#if A_REVERSE + {"Reverse_Video", A_REVERSE}, +#endif +#if A_BLINK + {"Blink", A_BLINK}, +#endif +#if A_DIM + {"Dim_Character", A_DIM}, +#endif +#if A_BOLD + {"Bold_Character", A_BOLD}, +#endif +#if A_ALTCHARSET + {"Alternate_Character_Set", A_ALTCHARSET}, +#endif +#if A_INVIS + {"Invisible_Character", A_INVIS}, +#endif +#if A_PROTECT + {"Protected_Character", A_PROTECT}, +#endif +#if A_HORIZONTAL + {"Horizontal", A_HORIZONTAL}, +#endif +#if A_LEFT + {"Left", A_LEFT}, +#endif +#if A_LOW + {"Low", A_LOW}, +#endif +#if A_RIGHT + {"Right", A_RIGHT}, +#endif +#if A_TOP + {"Top", A_TOP}, +#endif +#if A_VERTICAL + {"Vertical", A_VERTICAL}, +#endif + {(char *)0, 0} + }; + chtype attr = A_ATTRIBUTES & ~A_COLOR; + int start=-1, len=0, i, set; + for(i=0;i<(int)(8*sizeof(chtype));i++) { + set = attr&1; + if (set) { + if (start<0) + start = i; + if (start>=0) { + len++; + } + } + attr = attr >> 1; + } + gen_reps (nap, name, (len+7)/8, little_endian?start:0); +} + +static void gen_menu_opt_rep(const char *name) +{ + static const name_attribute_pair nap[] = { +#ifdef O_ONEVALUE + {"One_Valued", O_ONEVALUE}, +#endif +#ifdef O_SHOWDESC + {"Show_Descriptions", O_SHOWDESC}, +#endif +#ifdef O_ROWMAJOR + {"Row_Major_Order", O_ROWMAJOR}, +#endif +#ifdef O_IGNORECASE + {"Ignore_Case", O_IGNORECASE}, +#endif +#ifdef O_SHOWMATCH + {"Show_Matches", O_SHOWMATCH}, +#endif +#ifdef O_NONCYCLIC + {"Non_Cyclic", O_NONCYCLIC}, +#endif + {(char *)0, 0} + }; + gen_reps (nap, name, sizeof(int),0); +} + +static void gen_item_opt_rep(const char *name) +{ + static const name_attribute_pair nap[] = { +#ifdef O_SELECTABLE + {"Selectable", O_SELECTABLE}, +#endif + {(char *)0 , 0} + }; + gen_reps (nap, name, sizeof(int),0); +} + +static void gen_form_opt_rep(const char *name) +{ + static const name_attribute_pair nap[] = { +#ifdef O_NL_OVERLOAD + {"NL_Overload", O_NL_OVERLOAD}, +#endif +#ifdef O_BS_OVERLOAD + {"BS_Overload", O_BS_OVERLOAD}, +#endif + {(char *)0 , 0} + }; + gen_reps (nap, name, sizeof(int),0); +} + +/* + * Generate the representation clause for the Field_Option_Set record + */ +static void gen_field_opt_rep(const char *name) +{ + static const name_attribute_pair nap[] = { +#ifdef O_VISIBLE + {"Visible",O_VISIBLE}, +#endif +#ifdef O_ACTIVE + {"Active",O_ACTIVE}, +#endif +#ifdef O_PUBLIC + {"Public",O_PUBLIC}, +#endif +#ifdef O_EDIT + {"Edit",O_EDIT}, +#endif +#ifdef O_WRAP + {"Wrap",O_WRAP}, +#endif +#ifdef O_BLANK + {"Blank",O_BLANK}, +#endif +#ifdef O_AUTOSKIP + {"Auto_Skip",O_AUTOSKIP}, +#endif +#ifdef O_NULLOK + {"Null_Ok",O_NULLOK}, +#endif +#ifdef O_PASSOK + {"Pass_Ok",O_PASSOK}, +#endif +#ifdef O_STATIC + {"Static",O_STATIC}, +#endif + {(char *)0, 0} + }; + gen_reps (nap, name, sizeof(int),0); +} + +/* + * Generate a single key code constant definition. + */ +static void keydef(const char *name, const char *old_name, int value, int mode) +{ + if (mode==0) /* Generate the new name */ + printf(" %-30s : constant Special_Key_Code := 8#%3o#;\n",name,value); + else + { /* generate the old name, but only if it doesn't conflict with the old + * name (Ada95 isn't case sensitive!) + */ + const char *s = old_name; const char *t = name; + while ( *s && *t && (toupper(*s++) == toupper(*t++))); + if (*s || *t) + printf(" %-16s : Special_Key_Code renames %s;\n",old_name,name); + } +} + +/* + * Generate constants for the key codes. When called with mode==0, a + * complete list with nice constant names in proper casing style will + * be generated. Otherwise a list of old (i.e. C-style) names will be + * generated, given that the name wasn't already defined in the "nice" + * list. + */ +static void gen_keydefs (int mode) +{ + char buf[16]; + char obuf[16]; + int i; + +#ifdef KEY_CODE_YES + keydef("Key_Code_Yes","KEY_CODE_YES",KEY_CODE_YES,mode); +#endif +#ifdef KEY_MIN + keydef("Key_Min","KEY_MIN",KEY_MIN,mode); +#endif +#ifdef KEY_BREAK + keydef("Key_Break","KEY_BREAK",KEY_BREAK,mode); +#endif +#ifdef KEY_DOWN + keydef("Key_Cursor_Down","KEY_DOWN",KEY_DOWN,mode); +#endif +#ifdef KEY_UP + keydef("Key_Cursor_Up","KEY_UP",KEY_UP,mode); +#endif +#ifdef KEY_LEFT + keydef("Key_Cursor_Left","KEY_LEFT",KEY_LEFT,mode); +#endif +#ifdef KEY_RIGHT + keydef("Key_Cursor_Right","KEY_RIGHT",KEY_RIGHT,mode); +#endif +#ifdef KEY_HOME + keydef("Key_Home","KEY_HOME",KEY_HOME,mode); +#endif +#ifdef KEY_BACKSPACE + keydef("Key_Backspace","KEY_BACKSPACE",KEY_BACKSPACE,mode); +#endif +#ifdef KEY_F0 + keydef("Key_F0","KEY_F0",KEY_F0,mode); +#endif +#ifdef KEY_F + for(i=1;i<=24;i++) + { + sprintf(buf ,"Key_F%d",i); + sprintf(obuf,"KEY_F%d",i); + keydef(buf,obuf,KEY_F(i),mode); + } +#endif +#ifdef KEY_DL + keydef("Key_Delete_Line","KEY_DL",KEY_DL,mode); +#endif +#ifdef KEY_IL + keydef("Key_Insert_Line","KEY_IL",KEY_IL,mode); +#endif +#ifdef KEY_DC + keydef("Key_Delete_Char","KEY_DC",KEY_DC,mode); +#endif +#ifdef KEY_IC + keydef("Key_Insert_Char","KEY_IC",KEY_IC,mode); +#endif +#ifdef KEY_EIC + keydef("Key_Exit_Insert_Mode","KEY_EIC",KEY_EIC,mode); +#endif +#ifdef KEY_CLEAR + keydef("Key_Clear_Screen","KEY_CLEAR",KEY_CLEAR,mode); +#endif +#ifdef KEY_EOS + keydef("Key_Clear_End_Of_Screen","KEY_EOS",KEY_EOS,mode); +#endif +#ifdef KEY_EOL + keydef("Key_Clear_End_Of_Line","KEY_EOL",KEY_EOL,mode); +#endif +#ifdef KEY_SF + keydef("Key_Scroll_1_Forward","KEY_SF",KEY_SF,mode); +#endif +#ifdef KEY_SR + keydef("Key_Scroll_1_Backward","KEY_SR",KEY_SR,mode); +#endif +#ifdef KEY_NPAGE + keydef("Key_Next_Page","KEY_NPAGE",KEY_NPAGE,mode); +#endif +#ifdef KEY_PPAGE + keydef("Key_Previous_Page","KEY_PPAGE",KEY_PPAGE,mode); +#endif +#ifdef KEY_STAB + keydef("Key_Set_Tab","KEY_STAB",KEY_STAB,mode); +#endif +#ifdef KEY_CTAB + keydef("Key_Clear_Tab","KEY_CTAB",KEY_CTAB,mode); +#endif +#ifdef KEY_CATAB + keydef("Key_Clear_All_Tabs","KEY_CATAB",KEY_CATAB,mode); +#endif +#ifdef KEY_ENTER + keydef("Key_Enter_Or_Send","KEY_ENTER",KEY_ENTER,mode); +#endif +#ifdef KEY_SRESET + keydef("Key_Soft_Reset","KEY_SRESET",KEY_SRESET,mode); +#endif +#ifdef KEY_RESET + keydef("Key_Reset","KEY_RESET",KEY_RESET,mode); +#endif +#ifdef KEY_PRINT + keydef("Key_Print","KEY_PRINT",KEY_PRINT,mode); +#endif +#ifdef KEY_LL + keydef("Key_Bottom","KEY_LL",KEY_LL,mode); +#endif +#ifdef KEY_A1 + keydef("Key_Upper_Left_Of_Keypad","KEY_A1",KEY_A1,mode); +#endif +#ifdef KEY_A3 + keydef("Key_Upper_Right_Of_Keypad","KEY_A3",KEY_A3,mode); +#endif +#ifdef KEY_B2 + keydef("Key_Center_Of_Keypad","KEY_B2",KEY_B2,mode); +#endif +#ifdef KEY_C1 + keydef("Key_Lower_Left_Of_Keypad","KEY_C1",KEY_C1,mode); +#endif +#ifdef KEY_C3 + keydef("Key_Lower_Right_Of_Keypad","KEY_C3",KEY_C3,mode); +#endif +#ifdef KEY_BTAB + keydef("Key_Back_Tab","KEY_BTAB",KEY_BTAB,mode); +#endif +#ifdef KEY_BEG + keydef("Key_Beginning","KEY_BEG",KEY_BEG,mode); +#endif +#ifdef KEY_CANCEL + keydef("Key_Cancel","KEY_CANCEL",KEY_CANCEL,mode); +#endif +#ifdef KEY_CLOSE + keydef("Key_Close","KEY_CLOSE",KEY_CLOSE,mode); +#endif +#ifdef KEY_COMMAND + keydef("Key_Command","KEY_COMMAND",KEY_COMMAND,mode); +#endif +#ifdef KEY_COPY + keydef("Key_Copy","KEY_COPY",KEY_COPY,mode); +#endif +#ifdef KEY_CREATE + keydef("Key_Create","KEY_CREATE",KEY_CREATE,mode); +#endif +#ifdef KEY_END + keydef("Key_End","KEY_END",KEY_END,mode); +#endif +#ifdef KEY_EXIT + keydef("Key_Exit","KEY_EXIT",KEY_EXIT,mode); +#endif +#ifdef KEY_FIND + keydef("Key_Find","KEY_FIND",KEY_FIND,mode); +#endif +#ifdef KEY_HELP + keydef("Key_Help","KEY_HELP",KEY_HELP,mode); +#endif +#ifdef KEY_MARK + keydef("Key_Mark","KEY_MARK",KEY_MARK,mode); +#endif +#ifdef KEY_MESSAGE + keydef("Key_Message","KEY_MESSAGE",KEY_MESSAGE,mode); +#endif +#ifdef KEY_MOVE + keydef("Key_Move","KEY_MOVE",KEY_MOVE,mode); +#endif +#ifdef KEY_NEXT + keydef("Key_Next","KEY_NEXT",KEY_NEXT,mode); +#endif +#ifdef KEY_OPEN + keydef("Key_Open","KEY_OPEN",KEY_OPEN,mode); +#endif +#ifdef KEY_OPTIONS + keydef("Key_Options","KEY_OPTIONS",KEY_OPTIONS,mode); +#endif +#ifdef KEY_PREVIOUS + keydef("Key_Previous","KEY_PREVIOUS",KEY_PREVIOUS,mode); +#endif +#ifdef KEY_REDO + keydef("Key_Redo","KEY_REDO",KEY_REDO,mode); +#endif +#ifdef KEY_REFERENCE + keydef("Key_Reference","KEY_REFERENCE",KEY_REFERENCE,mode); +#endif +#ifdef KEY_REFRESH + keydef("Key_Refresh","KEY_REFRESH",KEY_REFRESH,mode); +#endif +#ifdef KEY_REPLACE + keydef("Key_Replace","KEY_REPLACE",KEY_REPLACE,mode); +#endif +#ifdef KEY_RESTART + keydef("Key_Restart","KEY_RESTART",KEY_RESTART,mode); +#endif +#ifdef KEY_RESUME + keydef("Key_Resume","KEY_RESUME",KEY_RESUME,mode); +#endif +#ifdef KEY_SAVE + keydef("Key_Save","KEY_SAVE",KEY_SAVE,mode); +#endif +#ifdef KEY_SBEG + keydef("Key_Shift_Begin","KEY_SBEG",KEY_SBEG,mode); +#endif +#ifdef KEY_SCANCEL + keydef("Key_Shift_Cancel","KEY_SCANCEL",KEY_SCANCEL,mode); +#endif +#ifdef KEY_SCOMMAND + keydef("Key_Shift_Command","KEY_SCOMMAND",KEY_SCOMMAND,mode); +#endif +#ifdef KEY_SCOPY + keydef("Key_Shift_Copy","KEY_SCOPY",KEY_SCOPY,mode); +#endif +#ifdef KEY_SCREATE + keydef("Key_Shift_Create","KEY_SCREATE",KEY_SCREATE,mode); +#endif +#ifdef KEY_SDC + keydef("Key_Shift_Delete_Char","KEY_SDC",KEY_SDC,mode); +#endif +#ifdef KEY_SDL + keydef("Key_Shift_Delete_Line","KEY_SDL",KEY_SDL,mode); +#endif +#ifdef KEY_SELECT + keydef("Key_Select","KEY_SELECT",KEY_SELECT,mode); +#endif +#ifdef KEY_SEND + keydef("Key_Shift_End","KEY_SEND",KEY_SEND,mode); +#endif +#ifdef KEY_SEOL + keydef("Key_Shift_Clear_End_Of_Line","KEY_SEOL",KEY_SEOL,mode); +#endif +#ifdef KEY_SEXIT + keydef("Key_Shift_Exit","KEY_SEXIT",KEY_SEXIT,mode); +#endif +#ifdef KEY_SFIND + keydef("Key_Shift_Find","KEY_SFIND",KEY_SFIND,mode); +#endif +#ifdef KEY_SHELP + keydef("Key_Shift_Help","KEY_SHELP",KEY_SHELP,mode); +#endif +#ifdef KEY_SHOME + keydef("Key_Shift_Home","KEY_SHOME",KEY_SHOME,mode); +#endif +#ifdef KEY_SIC + keydef("Key_Shift_Insert_Char","KEY_SIC",KEY_SIC,mode); +#endif +#ifdef KEY_SLEFT + keydef("Key_Shift_Cursor_Left","KEY_SLEFT",KEY_SLEFT,mode); +#endif +#ifdef KEY_SMESSAGE + keydef("Key_Shift_Message","KEY_SMESSAGE",KEY_SMESSAGE,mode); +#endif +#ifdef KEY_SMOVE + keydef("Key_Shift_Move","KEY_SMOVE",KEY_SMOVE,mode); +#endif +#ifdef KEY_SNEXT + keydef("Key_Shift_Next_Page","KEY_SNEXT",KEY_SNEXT,mode); +#endif +#ifdef KEY_SOPTIONS + keydef("Key_Shift_Options","KEY_SOPTIONS",KEY_SOPTIONS,mode); +#endif +#ifdef KEY_SPREVIOUS + keydef("Key_Shift_Previous_Page","KEY_SPREVIOUS",KEY_SPREVIOUS,mode); +#endif +#ifdef KEY_SPRINT + keydef("Key_Shift_Print","KEY_SPRINT",KEY_SPRINT,mode); +#endif +#ifdef KEY_SREDO + keydef("Key_Shift_Redo","KEY_SREDO",KEY_SREDO,mode); +#endif +#ifdef KEY_SREPLACE + keydef("Key_Shift_Replace","KEY_SREPLACE",KEY_SREPLACE,mode); +#endif +#ifdef KEY_SRIGHT + keydef("Key_Shift_Cursor_Right","KEY_SRIGHT",KEY_SRIGHT,mode); +#endif +#ifdef KEY_SRSUME + keydef("Key_Shift_Resume","KEY_SRSUME",KEY_SRSUME,mode); +#endif +#ifdef KEY_SSAVE + keydef("Key_Shift_Save","KEY_SSAVE",KEY_SSAVE,mode); +#endif +#ifdef KEY_SSUSPEND + keydef("Key_Shift_Suspend","KEY_SSUSPEND",KEY_SSUSPEND,mode); +#endif +#ifdef KEY_SUNDO + keydef("Key_Shift_Undo","KEY_SUNDO",KEY_SUNDO,mode); +#endif +#ifdef KEY_SUSPEND + keydef("Key_Suspend","KEY_SUSPEND",KEY_SUSPEND,mode); +#endif +#ifdef KEY_UNDO + keydef("Key_Undo","KEY_UNDO",KEY_UNDO,mode); +#endif +#ifdef KEY_MOUSE + keydef("Key_Mouse","KEY_MOUSE",KEY_MOUSE,mode); +#endif +#ifdef KEY_RESIZE + keydef("Key_Resize","KEY_RESIZE",KEY_RESIZE,mode); +#endif +} + +/* + * Generate a constant with the given name. The second parameter + * is a reference to the ACS character in the acs_map[] array and + * will be translated into an index. + */ +static void acs_def (const char *name, chtype *a) +{ + int c = a - &acs_map[0]; + printf(" %-24s : constant Character := ",name); + if (isprint(c) && (c!='`')) + printf("'%c';\n",c); + else + printf("Character'Val (%d);\n",c); +} + +/* + * Generate the constants for the ACS characters + */ +static void gen_acs (void) +{ +#ifdef ACS_ULCORNER + acs_def("ACS_Upper_Left_Corner",&ACS_ULCORNER); +#endif +#ifdef ACS_LLCORNER + acs_def("ACS_Lower_Left_Corner",&ACS_LLCORNER); +#endif +#ifdef ACS_URCORNER + acs_def("ACS_Upper_Right_Corner",&ACS_URCORNER); +#endif +#ifdef ACS_LRCORNER + acs_def("ACS_Lower_Right_Corner",&ACS_LRCORNER); +#endif +#ifdef ACS_LTEE + acs_def("ACS_Left_Tee",&ACS_LTEE); +#endif +#ifdef ACS_RTEE + acs_def("ACS_Right_Tee",&ACS_RTEE); +#endif +#ifdef ACS_BTEE + acs_def("ACS_Bottom_Tee",&ACS_BTEE); +#endif +#ifdef ACS_TTEE + acs_def("ACS_Top_Tee",&ACS_TTEE); +#endif +#ifdef ACS_HLINE + acs_def("ACS_Horizontal_Line",&ACS_HLINE); +#endif +#ifdef ACS_VLINE + acs_def("ACS_Vertical_Line",&ACS_VLINE); +#endif +#ifdef ACS_PLUS + acs_def("ACS_Plus_Symbol",&ACS_PLUS); +#endif +#ifdef ACS_S1 + acs_def("ACS_Scan_Line_1",&ACS_S1); +#endif +#ifdef ACS_S9 + acs_def("ACS_Scan_Line_9",&ACS_S9); +#endif +#ifdef ACS_DIAMOND + acs_def("ACS_Diamond",&ACS_DIAMOND); +#endif +#ifdef ACS_CKBOARD + acs_def("ACS_Checker_Board",&ACS_CKBOARD); +#endif +#ifdef ACS_DEGREE + acs_def("ACS_Degree",&ACS_DEGREE); +#endif +#ifdef ACS_PLMINUS + acs_def("ACS_Plus_Minus",&ACS_PLMINUS); +#endif +#ifdef ACS_BULLET + acs_def("ACS_Bullet",&ACS_BULLET); +#endif +#ifdef ACS_LARROW + acs_def("ACS_Left_Arrow",&ACS_LARROW); +#endif +#ifdef ACS_RARROW + acs_def("ACS_Right_Arrow",&ACS_RARROW); +#endif +#ifdef ACS_DARROW + acs_def("ACS_Down_Arrow",&ACS_DARROW); +#endif +#ifdef ACS_UARROW + acs_def("ACS_Up_Arrow",&ACS_UARROW); +#endif +#ifdef ACS_BOARD + acs_def("ACS_Board_Of_Squares",&ACS_BOARD); +#endif +#ifdef ACS_LANTERN + acs_def("ACS_Lantern",&ACS_LANTERN); +#endif +#ifdef ACS_BLOCK + acs_def("ACS_Solid_Block",&ACS_BLOCK); +#endif +#ifdef ACS_S3 + acs_def("ACS_Scan_Line_3",&ACS_S3); +#endif +#ifdef ACS_S7 + acs_def("ACS_Scan_Line_7",&ACS_S7); +#endif +#ifdef ACS_LEQUAL + acs_def("ACS_Less_Or_Equal",&ACS_LEQUAL); +#endif +#ifdef ACS_GEQUAL + acs_def("ACS_Greater_Or_Equal",&ACS_GEQUAL); +#endif +#ifdef ACS_PI + acs_def("ACS_PI",&ACS_PI); +#endif +#ifdef ACS_NEQUAL + acs_def("ACS_Not_Equal",&ACS_NEQUAL); +#endif +#ifdef ACS_STERLING + acs_def("ACS_Sterling",&ACS_STERLING); +#endif +} + + +#define GEN_EVENT(name,value) \ + printf(" %-25s : constant Event_Mask := 8#%011lo#;\n", \ + #name, value) + +#define GEN_MEVENT(name) \ + printf(" %-25s : constant Event_Mask := 8#%011lo#;\n", \ + #name, name) + +static +void gen_mouse_events(void) +{ + mmask_t all1 = 0; + mmask_t all2 = 0; + mmask_t all3 = 0; + mmask_t all4 = 0; + +#ifdef BUTTON1_RELEASED + GEN_MEVENT(BUTTON1_RELEASED); + all1 |= BUTTON1_RELEASED; +#endif +#ifdef BUTTON1_PRESSED + GEN_MEVENT(BUTTON1_PRESSED); + all1 |= BUTTON1_PRESSED; +#endif +#ifdef BUTTON1_CLICKED + GEN_MEVENT(BUTTON1_CLICKED); + all1 |= BUTTON1_CLICKED; +#endif +#ifdef BUTTON1_DOUBLE_CLICKED + GEN_MEVENT(BUTTON1_DOUBLE_CLICKED); + all1 |= BUTTON1_DOUBLE_CLICKED; +#endif +#ifdef BUTTON1_TRIPLE_CLICKED + GEN_MEVENT(BUTTON1_TRIPLE_CLICKED); + all1 |= BUTTON1_TRIPLE_CLICKED; +#endif +#ifdef BUTTON1_RESERVED_EVENT + GEN_MEVENT(BUTTON1_RESERVED_EVENT); + all1 |= BUTTON1_RESERVED_EVENT; +#endif +#ifdef BUTTON2_RELEASED + GEN_MEVENT(BUTTON2_RELEASED); + all2 |= BUTTON2_RELEASED; +#endif +#ifdef BUTTON2_PRESSED + GEN_MEVENT(BUTTON2_PRESSED); + all2 |= BUTTON2_PRESSED; +#endif +#ifdef BUTTON2_CLICKED + GEN_MEVENT(BUTTON2_CLICKED); + all2 |= BUTTON2_CLICKED; +#endif +#ifdef BUTTON2_DOUBLE_CLICKED + GEN_MEVENT(BUTTON2_DOUBLE_CLICKED); + all2 |= BUTTON2_DOUBLE_CLICKED; +#endif +#ifdef BUTTON2_TRIPLE_CLICKED + GEN_MEVENT(BUTTON2_TRIPLE_CLICKED); + all2 |= BUTTON2_TRIPLE_CLICKED; +#endif +#ifdef BUTTON2_RESERVED_EVENT + GEN_MEVENT(BUTTON2_RESERVED_EVENT); + all2 |= BUTTON2_RESERVED_EVENT; +#endif +#ifdef BUTTON3_RELEASED + GEN_MEVENT(BUTTON3_RELEASED); + all3 |= BUTTON3_RELEASED; +#endif +#ifdef BUTTON3_PRESSED + GEN_MEVENT(BUTTON3_PRESSED); + all3 |= BUTTON3_PRESSED; +#endif +#ifdef BUTTON3_CLICKED + GEN_MEVENT(BUTTON3_CLICKED); + all3 |= BUTTON3_CLICKED; +#endif +#ifdef BUTTON3_DOUBLE_CLICKED + GEN_MEVENT(BUTTON3_DOUBLE_CLICKED); + all3 |= BUTTON3_DOUBLE_CLICKED; +#endif +#ifdef BUTTON3_TRIPLE_CLICKED + GEN_MEVENT(BUTTON3_TRIPLE_CLICKED); + all3 |= BUTTON3_TRIPLE_CLICKED; +#endif +#ifdef BUTTON3_RESERVED_EVENT + GEN_MEVENT(BUTTON3_RESERVED_EVENT); + all3 |= BUTTON3_RESERVED_EVENT; +#endif +#ifdef BUTTON4_RELEASED + GEN_MEVENT(BUTTON4_RELEASED); + all4 |= BUTTON4_RELEASED; +#endif +#ifdef BUTTON4_PRESSED + GEN_MEVENT(BUTTON4_PRESSED); + all4 |= BUTTON4_PRESSED; +#endif +#ifdef BUTTON4_CLICKED + GEN_MEVENT(BUTTON4_CLICKED); + all4 |= BUTTON4_CLICKED; +#endif +#ifdef BUTTON4_DOUBLE_CLICKED + GEN_MEVENT(BUTTON4_DOUBLE_CLICKED); + all4 |= BUTTON4_DOUBLE_CLICKED; +#endif +#ifdef BUTTON4_TRIPLE_CLICKED + GEN_MEVENT(BUTTON4_TRIPLE_CLICKED); + all4 |= BUTTON4_TRIPLE_CLICKED; +#endif +#ifdef BUTTON4_RESERVED_EVENT + GEN_MEVENT(BUTTON4_RESERVED_EVENT); + all4 |= BUTTON4_RESERVED_EVENT; +#endif +#ifdef BUTTON_CTRL + GEN_MEVENT(BUTTON_CTRL); +#endif +#ifdef BUTTON_SHIFT + GEN_MEVENT(BUTTON_SHIFT); +#endif +#ifdef BUTTON_ALT + GEN_MEVENT(BUTTON_ALT); +#endif +#ifdef ALL_MOUSE_EVENTS + GEN_MEVENT(ALL_MOUSE_EVENTS); +#endif + +GEN_EVENT(BUTTON1_EVENTS,all1); +GEN_EVENT(BUTTON2_EVENTS,all2); +GEN_EVENT(BUTTON3_EVENTS,all3); +GEN_EVENT(BUTTON4_EVENTS,all4); +} + +/* + * Output some comment lines indicating that the file is generated. + * The name parameter is the name of the facility to be used in + * the comment. + */ +static void prologue(const char *name) +{ + printf("-- %s binding.\n",name); + printf("-- This module is generated. Please don't change it manually!\n"); + printf("-- Run the generator instead.\n-- |"); + + printf("define(`M4_BIT_ORDER',`%s_Order_First')", + little_endian ? "Low":"High"); +} + +/* + * Write the prologue for the curses facility and make sure that + * KEY_MIN and KEY_MAX are defined for the rest of this source. + */ +static void basedefs (void) +{ + prologue("curses"); +#ifndef KEY_MAX +# define KEY_MAX 0777 +#endif + printf("define(`M4_KEY_MAX',`8#%o#')",KEY_MAX); +#ifndef KEY_MIN +# define KEY_MIN 0401 +#endif + if (KEY_MIN == 256) { + fprintf(stderr,"Unexpected value for KEY_MIN: %d\n",KEY_MIN); + exit(1); + } + printf("define(`M4_SPECIAL_FIRST',`8#%o#')",KEY_MIN - 1); +} + +/* + * Write out the comment lines for the menu facility + */ +static void menu_basedefs (void) +{ + prologue("menu"); +} + +/* + * Write out the comment lines for the form facility + */ +static void form_basedefs (void) +{ + prologue("form"); +} + +/* + * Write out the comment lines for the mouse facility + */ +static void mouse_basedefs(void) +{ + prologue("mouse"); +} + +/* + * Write the definition of a single color + */ +static void color_def (const char *name, int value) +{ + printf(" %-8s : constant Color_Number := %d;\n",name,value); +} + +/* + * Generate all color definitions + */ +static void gen_color (void) +{ +#ifdef COLOR_BLACK + color_def ("Black",COLOR_BLACK); +#endif +#ifdef COLOR_RED + color_def ("Red",COLOR_RED); +#endif +#ifdef COLOR_GREEN + color_def ("Green",COLOR_GREEN); +#endif +#ifdef COLOR_YELLOW + color_def ("Yellow",COLOR_YELLOW); +#endif +#ifdef COLOR_BLUE + color_def ("Blue",COLOR_BLUE); +#endif +#ifdef COLOR_MAGENTA + color_def ("Magenta",COLOR_MAGENTA); +#endif +#ifdef COLOR_CYAN + color_def ("Cyan",COLOR_CYAN); +#endif +#ifdef COLOR_WHITE + color_def ("White",COLOR_WHITE); +#endif +} + +/* + * Generate the linker options for the base facility + */ +static void gen_linkopts (void) +{ + printf(" pragma Linker_Options (\"-lncurses%s\");\n", model); +} + +/* + * Generate the linker options for the menu facility + */ +static void gen_menu_linkopts (void) +{ + printf(" pragma Linker_Options (\"-lmenu%s\");\n", model); +} + +/* + * Generate the linker options for the form facility + */ +static void gen_form_linkopts (void) +{ + printf(" pragma Linker_Options (\"-lform%s\");\n", model); +} + +/* + * Generate the linker options for the panel facility + */ +static void gen_panel_linkopts (void) +{ + printf(" pragma Linker_Options (\"-lpanel%s\");\n", model); +} + +static void gen_version_info (void) +{ + static const char* v1 = + " NC_Major_Version : constant := %d; -- Major version of the library\n"; + static const char* v2 = + " NC_Minor_Version : constant := %d; -- Minor version of the library\n"; + static const char* v3 = + " NC_Version : constant String := %c%d.%d%c; -- Version of library\n"; + + printf(v1, NCURSES_VERSION_MAJOR); + printf(v2, NCURSES_VERSION_MINOR); + printf(v3, '"',NCURSES_VERSION_MAJOR,NCURSES_VERSION_MINOR,'"'); +} + +static int +eti_gen(char*buf, int code, const char* name, int* etimin, int* etimax) +{ + sprintf(buf," E_%-16s : constant Eti_Error := %d;\n",name,code); + if (code < *etimin) + *etimin = code; + if (code > *etimax) + *etimax = code; + return strlen(buf); +} + +#define GEN_OFFSET(member,itype) \ + if (sizeof(((WINDOW*)0)->member)==sizeof(itype)) { \ + o = offsetof(WINDOW, member); \ + if ((o%sizeof(itype) == 0)) { \ + printf(" Offset%-*s : constant Natural := %2ld; -- %s\n", \ + 8, #member, o/sizeof(itype),#itype); \ + } \ + } + +static void +gen_offsets(void) +{ + long o; + const char* s_bool = ""; + + GEN_OFFSET(_maxy,short); + GEN_OFFSET(_maxx,short); + GEN_OFFSET(_begy,short); + GEN_OFFSET(_begx,short); + GEN_OFFSET(_cury,short); + GEN_OFFSET(_curx,short); + GEN_OFFSET(_yoffset,short); + GEN_OFFSET(_pary,int); + GEN_OFFSET(_parx,int); + if (sizeof(bool) == sizeof(char)) { + GEN_OFFSET(_scroll,char); + s_bool = "char"; + } else if (sizeof(bool) == sizeof(short)) { + GEN_OFFSET(_scroll,short); + s_bool = "short"; + } else if (sizeof(bool) == sizeof(int)) { + GEN_OFFSET(_scroll,int); + s_bool = "int"; + } + printf(" Sizeof%-*s : constant Natural := %2ld; -- %s\n", + 8, "_bool", (long) sizeof(bool),"bool"); + /* In ncurses _maxy and _maxx needs an offset for the "public" + * value + */ + printf(" Offset%-*s : constant Natural := %2d; -- %s\n", + 8, "_XY",1,"int"); + printf("\n"); + printf(" type Curses_Bool is mod 2 ** Interfaces.C.%s'Size;\n",s_bool); +} + +/* + * main() expects two arguments on the commandline, both single characters. + * The first character denotes the facility for which we generate output. + * Possible values are + * B - Base + * M - Menus + * F - Forms + * P - Pointer Device (Mouse) + * E - ETI base definitions + * + * The second character then denotes the specific output that should be + * generated for the selected facility. + */ +int main(int argc, char *argv[]) +{ + int x = 0x12345678; + char *s = (char *)&x; + + if (*s == 0x78) + little_endian = 1; + + if (argc!=4) + exit(1); + model = *++argv; + + switch(argv[1][0]) + { + /* ---------------------------------------------------------------*/ + case 'B': /* The Base facility */ + switch(argv[2][0]) + { + case 'A': /* chtype translation into Ada95 record type */ + gen_attr_set("Character_Attribute_Set"); + break; + case 'K': /* translation of keycodes */ + gen_keydefs(0); + break; + case 'B': /* write some initial comment lines */ + basedefs(); + break; + case 'C': /* generate color constants */ + gen_color(); + break; + case 'D': /* generate displacements of fields in WINDOW struct. */ + gen_offsets(); + break; + case 'E': /* generate Mouse Event codes */ + gen_mouse_events(); + break; + case 'M': /* generate constants for the ACS characters */ + gen_acs(); + break; + case 'L': /* generate the Linker_Options pragma */ + gen_linkopts(); + break; + case 'O': /* generate definitions of the old key code names */ + gen_keydefs(1); + break; + case 'R': /* generate representation clause for Attributed character */ + gen_chtype_rep("Attributed_Character"); + break; + case 'V': /* generate version info */ + gen_version_info(); + break; + default: + break; + } + break; + /* ---------------------------------------------------------------*/ + case 'M': /* The Menu facility */ + switch(argv[2][0]) + { + case 'R': /* generate representation clause for Menu_Option_Set */ + gen_menu_opt_rep("Menu_Option_Set"); + break; + case 'B': /* write some initial comment lines */ + menu_basedefs(); + break; + case 'L': /* generate the Linker_Options pragma */ + gen_menu_linkopts(); + break; + case 'I': /* generate representation clause for Item_Option_Set */ + gen_item_opt_rep("Item_Option_Set"); + break; + default: + break; + } + break; + /* ---------------------------------------------------------------*/ + case 'F': /* The Form facility */ + switch(argv[2][0]) + { + case 'R': /* generate representation clause for Form_Option_Set */ + gen_form_opt_rep("Form_Option_Set"); + break; + case 'B': /* write some initial comment lines */ + form_basedefs(); + break; + case 'L': /* generate the Linker_Options pragma */ + gen_form_linkopts(); + break; + case 'I': /* generate representation clause for Field_Option_Set */ + gen_field_opt_rep("Field_Option_Set"); + break; + default: + break; + } + break; + /* ---------------------------------------------------------------*/ + case 'P': /* The Pointer(=Mouse) facility */ + switch(argv[2][0]) { + case 'B': /* write some initial comment lines */ + mouse_basedefs(); + break; + case 'M': /* generate representation clause for Mouse_Event */ + gen_mrep_rep("Mouse_Event"); + break; + case 'L': /* generate the Linker_Options pragma */ + gen_panel_linkopts(); + break; + default: + break; + } + break; + /* ---------------------------------------------------------------*/ + case 'E' : /* chtype size detection */ + switch(argv[2][0]) { + case 'C': + { + const char* fmt = " type C_Chtype is new %s;\n"; + const char* afmt = " type C_AttrType is new %s;\n"; + + if (sizeof(chtype)==sizeof(int)) { + if (sizeof(int)==sizeof(long)) + printf(fmt,"C_ULong"); + else + printf(fmt,"C_UInt"); + } + else if (sizeof(chtype)==sizeof(long)) { + printf(fmt,"C_ULong"); + } + else + printf("Error\n"); + + if (sizeof(attr_t)==sizeof(int)) { + if (sizeof(int)==sizeof(long)) + printf(afmt,"C_ULong"); + else + printf(afmt,"C_UInt"); + } + else if (sizeof(attr_t)==sizeof(long)) { + printf(afmt,"C_ULong"); + } + else + printf("Error\n"); + + printf("define(`CF_CURSES_OK',`%d')",OK); + printf("define(`CF_CURSES_ERR',`%d')",ERR); + printf("define(`CF_CURSES_TRUE',`%d')",TRUE); + printf("define(`CF_CURSES_FALSE',`%d')",FALSE); + } + break; + case 'E': + { + char* buf = (char*)malloc(2048); + char* p = buf; + int etimin = E_OK; + int etimax = E_OK; + if (p) { + p += eti_gen(p, E_OK, "Ok", &etimin, &etimax); + p += eti_gen(p, E_SYSTEM_ERROR,"System_Error", &etimin, &etimax); + p += eti_gen(p, E_BAD_ARGUMENT, "Bad_Argument", &etimin, &etimax); + p += eti_gen(p, E_POSTED, "Posted", &etimin, &etimax); + p += eti_gen(p, E_CONNECTED, "Connected", &etimin, &etimax); + p += eti_gen(p, E_BAD_STATE, "Bad_State", &etimin, &etimax); + p += eti_gen(p, E_NO_ROOM, "No_Room", &etimin, &etimax); + p += eti_gen(p, E_NOT_POSTED, "Not_Posted", &etimin, &etimax); + p += eti_gen(p, E_UNKNOWN_COMMAND, + "Unknown_Command", &etimin, &etimax); + p += eti_gen(p, E_NO_MATCH, "No_Match", &etimin, &etimax); + p += eti_gen(p, E_NOT_SELECTABLE, + "Not_Selectable", &etimin, &etimax); + p += eti_gen(p, E_NOT_CONNECTED, + "Not_Connected", &etimin, &etimax); + p += eti_gen(p, E_REQUEST_DENIED, + "Request_Denied", &etimin, &etimax); + p += eti_gen(p, E_INVALID_FIELD, + "Invalid_Field", &etimin, &etimax); + p += eti_gen(p, E_CURRENT, + "Current", &etimin, &etimax); + } + printf(" subtype Eti_Error is C_Int range %d .. %d;\n\n", + etimin,etimax); + printf(buf); + } + break; + default: + break; + } + break; + /* ---------------------------------------------------------------*/ + case 'V' : /* plain version dump */ + { + switch(argv[2][0]) { + case '1': /* major version */ +#ifdef NCURSES_VERSION_MAJOR + printf("%d",NCURSES_VERSION_MAJOR); +#endif + break; + case '2': /* minor version */ +#ifdef NCURSES_VERSION_MINOR + printf("%d",NCURSES_VERSION_MINOR); +#endif + break; + case '3': /* patch level */ +#ifdef NCURSES_VERSION_PATCH + printf("%d",NCURSES_VERSION_PATCH); +#endif + break; + default: + break; + } + } + break; + /* ---------------------------------------------------------------*/ + default: + break; + } + return 0; +} + diff --git a/ncurses-5.2/Ada95/gen/html.m4 b/ncurses-5.2/Ada95/gen/html.m4 new file mode 100644 index 0000000..0b4254d --- /dev/null +++ b/ncurses-5.2/Ada95/gen/html.m4 @@ -0,0 +1,11 @@ +define(`ANCHORIDX',`0')dnl +define(`MANPAGE',`define(`MANPG',$1)dnl +|===================================================================== + -- | Man page MANPG + -- |=====================================================================')dnl +define(`ANCHOR',`define(`ANCHORIDX',incr(ANCHORIDX))dnl +`#'1A NAME="AFU`_'ANCHORIDX"`#'2dnl +define(`CFUNAME',`$1')define(`AFUNAME',`$2')dnl +|') +define(`AKA',``AKA': CFUNAME')dnl +define(`ALIAS',``AKA': $1')dnl diff --git a/ncurses-5.2/Ada95/gen/normal.m4 b/ncurses-5.2/Ada95/gen/normal.m4 new file mode 100644 index 0000000..f884c46 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/normal.m4 @@ -0,0 +1,8 @@ +define(`MANPAGE',`define(`MANPG',$1)dnl +|===================================================================== + -- | Man page MANPG + -- |=====================================================================')dnl +define(`ANCHOR',`define(`CFUNAME',`$1')define(`AFUNAME',`$2')'dnl +|)dnl +define(`AKA',``AKA': CFUNAME')dnl +define(`ALIAS',``AKA': $1')dnl diff --git a/ncurses-5.2/Ada95/gen/table.m4 b/ncurses-5.2/Ada95/gen/table.m4 new file mode 100644 index 0000000..48ed6ce --- /dev/null +++ b/ncurses-5.2/Ada95/gen/table.m4 @@ -0,0 +1,6 @@ +define(`ANCHORIDX',`0')dnl +define(`MANPAGE',`define(`MANPG',$1)')dnl +divert(-1)dnl +define(`ANCHOR',`divert(0)define(`ANCHORIDX',incr(ANCHORIDX))dnl +$1$2MANPG +divert(-1)') diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-aux.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-aux.ads.m4 new file mode 100644 index 0000000..5d479ce --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-aux.ads.m4 @@ -0,0 +1,104 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-aux__ads.htm')dnl +include(M4MACRO)------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Aux -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +include(`Base_Defs') +with System; +with Interfaces.C; +with Interfaces.C.Strings; use Interfaces.C.Strings; +with Unchecked_Conversion; + +package Terminal_Interface.Curses.Aux is + pragma Preelaborate (Terminal_Interface.Curses.Aux); + + use type Interfaces.C.int; + + subtype C_Int is Interfaces.C.int; + subtype C_Short is Interfaces.C.short; + subtype C_Long_Int is Interfaces.C.long; + subtype C_Size_T is Interfaces.C.size_t; + subtype C_UInt is Interfaces.C.unsigned; + subtype C_ULong is Interfaces.C.unsigned_long; + subtype C_Char_Ptr is Interfaces.C.Strings.chars_ptr; + type C_Void_Ptr is new System.Address; +include(`Chtype_Def') + -- This is how those constants are defined in ncurses. I see them also + -- exactly like this in all ETI implementations I ever tested. So it + -- could be that this is quite general, but please check with your curses. + -- This is critical, because curses sometime mixes boolean returns with + -- returning an error status. + Curses_Ok : constant C_Int := CF_CURSES_OK; + Curses_Err : constant C_Int := CF_CURSES_ERR; + + Curses_True : constant C_Int := CF_CURSES_TRUE; + Curses_False : constant C_Int := CF_CURSES_FALSE; + + -- Eti_Error: type for error codes returned by the menu and form subsystem +include(`Eti_Defs') + procedure Eti_Exception (Code : Eti_Error); + -- Dispatch the error code and raise the appropriate exception + -- + -- + -- Some helpers + function Chtype_To_AttrChar is new + Unchecked_Conversion (Source => C_Chtype, + Target => Attributed_Character); + function AttrChar_To_Chtype is new + Unchecked_Conversion (Source => Attributed_Character, + Target => C_Chtype); + + function AttrChar_To_AttrType is new + Unchecked_Conversion (Source => Attributed_Character, + Target => C_AttrType); + + function AttrType_To_AttrChar is new + Unchecked_Conversion (Source => C_AttrType, + Target => Attributed_Character); + + procedure Fill_String (Cp : in chars_ptr; + Str : out String); + -- Fill the Str parameter with the string denoted by the chars_ptr + -- C-Style string. + + function Fill_String (Cp : chars_ptr) return String; + -- Same but as function. + +end Terminal_Interface.Curses.Aux; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 new file mode 100644 index 0000000..3ee0ecf --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 @@ -0,0 +1,238 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-forms-field_user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; + +package Terminal_Interface.Curses.Forms.Field_Types is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types); + use type Interfaces.C.int; + subtype C_Int is Interfaces.C.int; + + -- MANPAGE(`form_fieldtype.3x') + + type Field_Type is abstract tagged null record; + -- Abstract base type for all field types. A concrete field type + -- is an extension that adds some data elements describing formats or + -- boundary values for the type and validation routines. + -- For the builtin low-level fieldtypes, the validation routines are + -- already defined by the low-level C library. + -- The builtin types like Alpha or AlphaNumeric etc. are defined in + -- child packages of this package. You may use one of them as example + -- how to create you own child packages for low-level field types that + -- you may have already written in C. + + type Field_Type_Access is access all Field_Type'Class; + + -- ANCHOR(`set_field_type()',`Set_Type') + procedure Set_Field_Type (Fld : in Field; + Fld_Type : in Field_Type) is abstract; + -- AKA + -- But: we hide the vararg mechanism of the C interface. You always + -- have to pass a single Field_Type parameter. + + -- --------------------------------------------------------------------- + + -- MANPAGE(`form_field_validation.3x') + + -- ANCHOR(`field_type()',`Get_Type') + function Get_Type (Fld : in Field) return Field_Type_Access; + -- AKA + -- ALIAS(`field_arg()') + -- In Ada95 we can combine these. If you try to retrieve the field type + -- that is not defined as extension of the abstract tagged type above, + -- you will raise a Form_Exception. + -- This is not inlined + + -- +---------------------------------------------------------------------- + -- | Private Part. + -- | Most of this is used by the implementations of the child packages. + -- | +private + type Makearg_Function is access + function (Args : System.Address) return System.Address; + pragma Convention (C, Makearg_Function); + + type Copyarg_Function is access + function (Usr : System.Address) return System.Address; + pragma Convention (C, Copyarg_Function); + + type Freearg_Function is access + procedure (Usr : System.Address); + pragma Convention (C, Freearg_Function); + + type Field_Check_Function is access + function (Fld : Field; Usr : System.Address) return C_Int; + pragma Convention (C, Field_Check_Function); + + type Char_Check_Function is access + function (Ch : C_Int; Usr : System.Address) return C_Int; + pragma Convention (C, Char_Check_Function); + + type Choice_Function is access + function (Fld : Field; Usr : System.Address) return C_Int; + pragma Convention (C, Choice_Function); + + -- +---------------------------------------------------------------------- + -- | This must be in sync with the FIELDTYPE structure in form.h + -- | + type Low_Level_Field_Type is + record + Status : Interfaces.C.short; + Ref_Count : Interfaces.C.long; + Left, Right : System.Address; + Makearg : Makearg_Function; + Copyarg : Copyarg_Function; + Freearg : Freearg_Function; + Fcheck : Field_Check_Function; + Ccheck : Char_Check_Function; + Next, Prev : Choice_Function; + end record; + pragma Convention (C, Low_Level_Field_Type); + type C_Field_Type is access all Low_Level_Field_Type; + + Null_Field_Type : constant C_Field_Type := null; + + -- +---------------------------------------------------------------------- + -- | This four low-level fieldtypes are the ones associated with + -- | fieldtypes handled by this binding. Any other low-level fieldtype + -- | will result in a Form_Exception is function Get_Type. + -- | + M_Generic_Type : C_Field_Type := null; + M_Generic_Choice : C_Field_Type := null; + M_Builtin_Router : C_Field_Type := null; + M_Choice_Router : C_Field_Type := null; + + -- Two wrapper functions to access those low-level fieldtypes defined + -- in this package. + function C_Builtin_Router return C_Field_Type; + function C_Choice_Router return C_Field_Type; + + procedure Wrap_Builtin (Fld : Field; + Typ : Field_Type'Class; + Cft : C_Field_Type := C_Builtin_Router); + -- This procedure has to be called by the Set_Field_Type implementation + -- for builtin low-level fieldtypes to replace it by an Ada95 + -- conformant Field_Type object. + -- The parameter Cft must be C_Builtin_Router for regular low-level + -- fieldtypes (like TYP_ALPHA or TYP_ALNUM) and C_Choice_Router for + -- low-level fieldtypes witch choice functions (like TYP_ENUM). + -- Any other value will raise a Form_Exception. + + function Make_Arg (Args : System.Address) return System.Address; + pragma Convention (C, Make_Arg); + -- This is the Makearg_Function for the internal low-level types + -- introduced by this binding. + + function Copy_Arg (Usr : System.Address) return System.Address; + pragma Convention (C, Copy_Arg); + -- This is the Copyarg_Function for the internal low-level types + -- introduced by this binding. + + procedure Free_Arg (Usr : System.Address); + pragma Convention (C, Free_Arg); + -- This is the Freearg_Function for the internal low-level types + -- introduced by this binding. + + function Field_Check_Router (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Field_Check_Router); + -- This is the Field_Check_Function for the internal low-level types + -- introduced to wrap the low-level types by a Field_Type derived + -- type. It routes the call to the corresponding low-level validation + -- function. + + function Char_Check_Router (Ch : C_Int; + Usr : System.Address) return C_Int; + pragma Convention (C, Char_Check_Router); + -- This is the Char_Check_Function for the internal low-level types + -- introduced to wrap the low-level types by a Field_Type derived + -- type. It routes the call to the corresponding low-level validation + -- function. + + function Next_Router (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Next_Router); + -- This is the Choice_Function for the internal low-level types + -- introduced to wrap the low-level types by a Field_Type derived + -- type. It routes the call to the corresponding low-level next_choice + -- function. + + function Prev_Router (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Prev_Router); + -- This is the Choice_Function for the internal low-level types + -- introduced to wrap the low-level types by a Field_Type derived + -- type. It routes the call to the corresponding low-level prev_choice + -- function. + + -- This is the Argument structure maintained by all low-level field types + -- introduced by this binding. + type Argument is record + Typ : Field_Type_Access; -- the Field_Type creating this record + Usr : System.Address; -- original arg for builtin low-level types + Cft : C_Field_Type; -- the original low-level type + end record; + type Argument_Access is access all Argument; + + -- +---------------------------------------------------------------------- + -- | + -- | Some Imports of libform routines to deal with low-level fieldtypes. + -- | + function New_Fieldtype (Fcheck : Field_Check_Function; + Ccheck : Char_Check_Function) + return C_Field_Type; + pragma Import (C, New_Fieldtype, "new_fieldtype"); + + function Set_Fieldtype_Arg (Cft : C_Field_Type; + Mak : Makearg_Function := Make_Arg'Access; + Cop : Copyarg_Function := Copy_Arg'Access; + Fre : Freearg_Function := Free_Arg'Access) + return C_Int; + pragma Import (C, Set_Fieldtype_Arg, "set_fieldtype_arg"); + + function Set_Fieldtype_Choice (Cft : C_Field_Type; + Next, Prev : Choice_Function) + return C_Int; + pragma Import (C, Set_Fieldtype_Choice, "set_fieldtype_choice"); + +end Terminal_Interface.Curses.Forms.Field_Types; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 new file mode 100644 index 0000000..eb8714e --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 @@ -0,0 +1,70 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-forms-field_user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_User_Data -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ + +generic + type User is limited private; + type User_Access is access User; +package Terminal_Interface.Curses.Forms.Field_User_Data is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_User_Data); + + -- MANPAGE(`form_field_userptr.3x') + + -- ANCHOR(`set_field_userptr',`Set_User_Data') + procedure Set_User_Data (Fld : in Field; + Data : in User_Access); + -- AKA + pragma Inline (Set_User_Data); + + -- ANCHOR(`field_userptr',`Get_User_Data') + procedure Get_User_Data (Fld : in Field; + Data : out User_Access); + -- AKA + + -- ANCHOR(`field_userptr',`Get_User_Data') + function Get_User_Data (Fld : in Field) return User_Access; + -- AKA + -- Sama as function + pragma Inline (Get_User_Data); + +end Terminal_Interface.Curses.Forms.Field_User_Data; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 new file mode 100644 index 0000000..87f777c --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 @@ -0,0 +1,70 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-forms-form_user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Form_User_Data -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ + +generic + type User is limited private; + type User_Access is access User; +package Terminal_Interface.Curses.Forms.Form_User_Data is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Form_User_Data); + + -- MANPAGE(`form_userptr.3x') + + -- ANCHOR(`set_form_userptr',`Set_User_Data') + procedure Set_User_Data (Frm : in Form; + Data : in User_Access); + -- AKA + pragma Inline (Set_User_Data); + + -- ANCHOR(`form_userptr',`Get_User_Data') + procedure Get_User_Data (Frm : in Form; + Data : out User_Access); + -- AKA + + -- ANCHOR(`form_userptr',`Get_User_Data') + function Get_User_Data (Frm : in Form) return User_Access; + -- AKA + -- Same as function + pragma Inline (Get_User_Data); + +end Terminal_Interface.Curses.Forms.Form_User_Data; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms.ads.m4 new file mode 100644 index 0000000..24c4dc1 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-forms.ads.m4 @@ -0,0 +1,696 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-forms__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Form -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +include(`Form_Base_Defs') +with System; +with Ada.Characters.Latin_1; + +package Terminal_Interface.Curses.Forms is + pragma Preelaborate (Terminal_Interface.Curses.Forms); +include(`Form_Linker_Options')dnl +include(`Linker_Options') + Space : Character renames Ada.Characters.Latin_1.Space; + + type Field is private; + type Form is private; + + Null_Field : constant Field; + Null_Form : constant Form; + + type Field_Justification is (None, + Left, + Center, + Right); + + pragma Warnings (Off); +include(`Field_Rep')Dnl + + pragma Warnings (On); + + function Default_Field_Options return Field_Option_Set; + -- The initial defaults for the field options. + pragma Inline (Default_Field_Options); + + pragma Warnings (Off); +include(`Form_Opt_Rep')Dnl + + pragma Warnings (On); + + function Default_Form_Options return Form_Option_Set; + -- The initial defaults for the form options. + pragma Inline (Default_Form_Options); + + type Buffer_Number is new Natural; + + type Field_Array is array (Positive range <>) of aliased Field; + pragma Convention (C, Field_Array); + + type Field_Array_Access is access Field_Array; + + procedure Free (FA : in out Field_Array_Access; + Free_Fields : in Boolean := False); + -- Release the memory for an allocated field array + -- If Free_Fields is True, call Delete() for all the fields in + -- the array. + + subtype Form_Request_Code is Key_Code range (Key_Max + 1) .. (Key_Max + 57); + + -- The prefix F_ stands for "Form Request" + F_Next_Page : constant Form_Request_Code := Key_Max + 1; + F_Previous_Page : constant Form_Request_Code := Key_Max + 2; + F_First_Page : constant Form_Request_Code := Key_Max + 3; + F_Last_Page : constant Form_Request_Code := Key_Max + 4; + + F_Next_Field : constant Form_Request_Code := Key_Max + 5; + F_Previous_Field : constant Form_Request_Code := Key_Max + 6; + F_First_Field : constant Form_Request_Code := Key_Max + 7; + F_Last_Field : constant Form_Request_Code := Key_Max + 8; + F_Sorted_Next_Field : constant Form_Request_Code := Key_Max + 9; + F_Sorted_Previous_Field : constant Form_Request_Code := Key_Max + 10; + F_Sorted_First_Field : constant Form_Request_Code := Key_Max + 11; + F_Sorted_Last_Field : constant Form_Request_Code := Key_Max + 12; + F_Left_Field : constant Form_Request_Code := Key_Max + 13; + F_Right_Field : constant Form_Request_Code := Key_Max + 14; + F_Up_Field : constant Form_Request_Code := Key_Max + 15; + F_Down_Field : constant Form_Request_Code := Key_Max + 16; + + F_Next_Char : constant Form_Request_Code := Key_Max + 17; + F_Previous_Char : constant Form_Request_Code := Key_Max + 18; + F_Next_Line : constant Form_Request_Code := Key_Max + 19; + F_Previous_Line : constant Form_Request_Code := Key_Max + 20; + F_Next_Word : constant Form_Request_Code := Key_Max + 21; + F_Previous_Word : constant Form_Request_Code := Key_Max + 22; + F_Begin_Field : constant Form_Request_Code := Key_Max + 23; + F_End_Field : constant Form_Request_Code := Key_Max + 24; + F_Begin_Line : constant Form_Request_Code := Key_Max + 25; + F_End_Line : constant Form_Request_Code := Key_Max + 26; + F_Left_Char : constant Form_Request_Code := Key_Max + 27; + F_Right_Char : constant Form_Request_Code := Key_Max + 28; + F_Up_Char : constant Form_Request_Code := Key_Max + 29; + F_Down_Char : constant Form_Request_Code := Key_Max + 30; + + F_New_Line : constant Form_Request_Code := Key_Max + 31; + F_Insert_Char : constant Form_Request_Code := Key_Max + 32; + F_Insert_Line : constant Form_Request_Code := Key_Max + 33; + F_Delete_Char : constant Form_Request_Code := Key_Max + 34; + F_Delete_Previous : constant Form_Request_Code := Key_Max + 35; + F_Delete_Line : constant Form_Request_Code := Key_Max + 36; + F_Delete_Word : constant Form_Request_Code := Key_Max + 37; + F_Clear_EOL : constant Form_Request_Code := Key_Max + 38; + F_Clear_EOF : constant Form_Request_Code := Key_Max + 39; + F_Clear_Field : constant Form_Request_Code := Key_Max + 40; + F_Overlay_Mode : constant Form_Request_Code := Key_Max + 41; + F_Insert_Mode : constant Form_Request_Code := Key_Max + 42; + + -- Vertical Scrolling + F_ScrollForward_Line : constant Form_Request_Code := Key_Max + 43; + F_ScrollBackward_Line : constant Form_Request_Code := Key_Max + 44; + F_ScrollForward_Page : constant Form_Request_Code := Key_Max + 45; + F_ScrollBackward_Page : constant Form_Request_Code := Key_Max + 46; + F_ScrollForward_HalfPage : constant Form_Request_Code := Key_Max + 47; + F_ScrollBackward_HalfPage : constant Form_Request_Code := Key_Max + 48; + + -- Horizontal Scrolling + F_HScrollForward_Char : constant Form_Request_Code := Key_Max + 49; + F_HScrollBackward_Char : constant Form_Request_Code := Key_Max + 50; + F_HScrollForward_Line : constant Form_Request_Code := Key_Max + 51; + F_HScrollBackward_Line : constant Form_Request_Code := Key_Max + 52; + F_HScrollForward_HalfLine : constant Form_Request_Code := Key_Max + 53; + F_HScrollBackward_HalfLine : constant Form_Request_Code := Key_Max + 54; + + F_Validate_Field : constant Form_Request_Code := Key_Max + 55; + F_Next_Choice : constant Form_Request_Code := Key_Max + 56; + F_Previous_Choice : constant Form_Request_Code := Key_Max + 57; + + -- For those who like the old 'C' style request names + REQ_NEXT_PAGE : Form_Request_Code renames F_Next_Page; + REQ_PREV_PAGE : Form_Request_Code renames F_Previous_Page; + REQ_FIRST_PAGE : Form_Request_Code renames F_First_Page; + REQ_LAST_PAGE : Form_Request_Code renames F_Last_Page; + + REQ_NEXT_FIELD : Form_Request_Code renames F_Next_Field; + REQ_PREV_FIELD : Form_Request_Code renames F_Previous_Field; + REQ_FIRST_FIELD : Form_Request_Code renames F_First_Field; + REQ_LAST_FIELD : Form_Request_Code renames F_Last_Field; + REQ_SNEXT_FIELD : Form_Request_Code renames F_Sorted_Next_Field; + REQ_SPREV_FIELD : Form_Request_Code renames F_Sorted_Previous_Field; + REQ_SFIRST_FIELD : Form_Request_Code renames F_Sorted_First_Field; + REQ_SLAST_FIELD : Form_Request_Code renames F_Sorted_Last_Field; + REQ_LEFT_FIELD : Form_Request_Code renames F_Left_Field; + REQ_RIGHT_FIELD : Form_Request_Code renames F_Right_Field; + REQ_UP_FIELD : Form_Request_Code renames F_Up_Field; + REQ_DOWN_FIELD : Form_Request_Code renames F_Down_Field; + + REQ_NEXT_CHAR : Form_Request_Code renames F_Next_Char; + REQ_PREV_CHAR : Form_Request_Code renames F_Previous_Char; + REQ_NEXT_LINE : Form_Request_Code renames F_Next_Line; + REQ_PREV_LINE : Form_Request_Code renames F_Previous_Line; + REQ_NEXT_WORD : Form_Request_Code renames F_Next_Word; + REQ_PREV_WORD : Form_Request_Code renames F_Previous_Word; + REQ_BEG_FIELD : Form_Request_Code renames F_Begin_Field; + REQ_END_FIELD : Form_Request_Code renames F_End_Field; + REQ_BEG_LINE : Form_Request_Code renames F_Begin_Line; + REQ_END_LINE : Form_Request_Code renames F_End_Line; + REQ_LEFT_CHAR : Form_Request_Code renames F_Left_Char; + REQ_RIGHT_CHAR : Form_Request_Code renames F_Right_Char; + REQ_UP_CHAR : Form_Request_Code renames F_Up_Char; + REQ_DOWN_CHAR : Form_Request_Code renames F_Down_Char; + + REQ_NEW_LINE : Form_Request_Code renames F_New_Line; + REQ_INS_CHAR : Form_Request_Code renames F_Insert_Char; + REQ_INS_LINE : Form_Request_Code renames F_Insert_Line; + REQ_DEL_CHAR : Form_Request_Code renames F_Delete_Char; + REQ_DEL_PREV : Form_Request_Code renames F_Delete_Previous; + REQ_DEL_LINE : Form_Request_Code renames F_Delete_Line; + REQ_DEL_WORD : Form_Request_Code renames F_Delete_Word; + REQ_CLR_EOL : Form_Request_Code renames F_Clear_EOL; + REQ_CLR_EOF : Form_Request_Code renames F_Clear_EOF; + REQ_CLR_FIELD : Form_Request_Code renames F_Clear_Field; + REQ_OVL_MODE : Form_Request_Code renames F_Overlay_Mode; + REQ_INS_MODE : Form_Request_Code renames F_Insert_Mode; + + REQ_SCR_FLINE : Form_Request_Code renames F_ScrollForward_Line; + REQ_SCR_BLINE : Form_Request_Code renames F_ScrollBackward_Line; + REQ_SCR_FPAGE : Form_Request_Code renames F_ScrollForward_Page; + REQ_SCR_BPAGE : Form_Request_Code renames F_ScrollBackward_Page; + REQ_SCR_FHPAGE : Form_Request_Code renames F_ScrollForward_HalfPage; + REQ_SCR_BHPAGE : Form_Request_Code renames F_ScrollBackward_HalfPage; + + REQ_SCR_FCHAR : Form_Request_Code renames F_HScrollForward_Char; + REQ_SCR_BCHAR : Form_Request_Code renames F_HScrollBackward_Char; + REQ_SCR_HFLINE : Form_Request_Code renames F_HScrollForward_Line; + REQ_SCR_HBLINE : Form_Request_Code renames F_HScrollBackward_Line; + REQ_SCR_HFHALF : Form_Request_Code renames F_HScrollForward_HalfLine; + REQ_SCR_HBHALF : Form_Request_Code renames F_HScrollBackward_HalfLine; + + REQ_VALIDATION : Form_Request_Code renames F_Validate_Field; + REQ_NEXT_CHOICE : Form_Request_Code renames F_Next_Choice; + REQ_PREV_CHOICE : Form_Request_Code renames F_Previous_Choice; + + + procedure Request_Name (Key : in Form_Request_Code; + Name : out String); + + function Request_Name (Key : Form_Request_Code) return String; + -- Same as function + pragma Inline (Request_Name); + + ------------------ + -- Exceptions -- + ------------------ + Form_Exception : exception; + + -- MANPAGE(`form_field_new.3x') + + -- ANCHOR(`new_field()',`Create') + function Create (Height : Line_Count; + Width : Column_Count; + Top : Line_Position; + Left : Column_Position; + Off_Screen : Natural := 0; + More_Buffers : Buffer_Number := Buffer_Number'First) + return Field; + -- AKA + -- An overloaded Create is defined later. Pragma Inline appears there. + + -- ANCHOR(`new_field()',`New_Field') + function New_Field (Height : Line_Count; + Width : Column_Count; + Top : Line_Position; + Left : Column_Position; + Off_Screen : Natural := 0; + More_Buffers : Buffer_Number := Buffer_Number'First) + return Field renames Create; + -- AKA + pragma Inline (New_Field); + + -- ANCHOR(`free_field()',`Delete') + procedure Delete (Fld : in out Field); + -- AKA + -- Reset Fld to Null_Field + -- An overloaded Delete is defined later. Pragma Inline appears there. + + -- ANCHOR(`dup_field()',`Duplicate') + function Duplicate (Fld : Field; + Top : Line_Position; + Left : Column_Position) return Field; + -- AKA + pragma Inline (Duplicate); + + -- ANCHOR(`link_field()',`Link') + function Link (Fld : Field; + Top : Line_Position; + Left : Column_Position) return Field; + -- AKA + pragma Inline (Link); + + -- MANPAGE(`form_field_just.3x') + + -- ANCHOR(`set_field_just()',`Set_Justification') + procedure Set_Justification (Fld : in Field; + Just : in Field_Justification := None); + -- AKA + pragma Inline (Set_Justification); + + -- ANCHOR(`field_just()',`Get_Justification') + function Get_Justification (Fld : Field) return Field_Justification; + -- AKA + pragma Inline (Get_Justification); + + -- MANPAGE(`form_field_buffer.3x') + + -- ANCHOR(`set_field_buffer()',`Set_Buffer') + procedure Set_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First; + Str : in String); + -- AKA + -- Not inlined + + -- ANCHOR(`field_buffer()',`Get_Buffer') + procedure Get_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First; + Str : out String); + -- AKA + + function Get_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First) return String; + -- AKA + -- Same but as function + pragma Inline (Get_Buffer); + + -- ANCHOR(`set_field_status()',`Set_Status') + procedure Set_Status (Fld : in Field; + Status : in Boolean := True); + -- AKA + pragma Inline (Set_Status); + + -- ANCHOR(`field_status()',`Changed') + function Changed (Fld : Field) return Boolean; + -- AKA + pragma Inline (Changed); + + -- ANCHOR(`set_field_max()',`Set_Maximum_Size') + procedure Set_Maximum_Size (Fld : in Field; + Max : in Natural := 0); + -- AKA + pragma Inline (Set_Maximum_Size); + + -- MANPAGE(`form_field_opts.3x') + + -- ANCHOR(`set_field_opts()',`Set_Options') + procedure Set_Options (Fld : in Field; + Options : in Field_Option_Set); + -- AKA + -- An overloaded version is defined later. Pragma Inline appears there + + -- ANCHOR(`field_opts_on()',`Switch_Options') + procedure Switch_Options (Fld : in Field; + Options : in Field_Option_Set; + On : Boolean := True); + -- AKA + -- ALIAS(`field_opts_off()') + -- An overloaded version is defined later. Pragma Inline appears there + + -- ANCHOR(`field_opts()',`Get_Options') + procedure Get_Options (Fld : in Field; + Options : out Field_Option_Set); + -- AKA + + -- ANCHOR(`field_opts()',`Get_Options') + function Get_Options (Fld : Field := Null_Field) + return Field_Option_Set; + -- AKA + -- An overloaded version is defined later. Pragma Inline appears there + + -- MANPAGE(`form_field_attributes.3x') + + -- ANCHOR(`set_field_fore()',`Set_Foreground') + procedure Set_Foreground + (Fld : in Field; + Fore : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Foreground); + + -- ANCHOR(`field_fore()',`Foreground') + procedure Foreground (Fld : in Field; + Fore : out Character_Attribute_Set); + -- AKA + + -- ANCHOR(`field_fore()',`Foreground') + procedure Foreground (Fld : in Field; + Fore : out Character_Attribute_Set; + Color : out Color_Pair); + -- AKA + pragma Inline (Foreground); + + -- ANCHOR(`set_field_back()',`Set_Background') + procedure Set_Background + (Fld : in Field; + Back : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Background); + + -- ANCHOR(`field_back()',`Background') + procedure Background (Fld : in Field; + Back : out Character_Attribute_Set); + -- AKA + + -- ANCHOR(`field_back()',`Background') + procedure Background (Fld : in Field; + Back : out Character_Attribute_Set; + Color : out Color_Pair); + -- AKA + pragma Inline (Background); + + -- ANCHOR(`set_field_pad()',`Set_Pad_Character') + procedure Set_Pad_Character (Fld : in Field; + Pad : in Character := Space); + -- AKA + pragma Inline (Set_Pad_Character); + + -- ANCHOR(`field_pad()',`Pad_Character') + procedure Pad_Character (Fld : in Field; + Pad : out Character); + -- AKA + pragma Inline (Pad_Character); + + -- MANPAGE(`form_field_info.3x') + + -- ANCHOR(`field_info()',`Info') + procedure Info (Fld : in Field; + Lines : out Line_Count; + Columns : out Column_Count; + First_Row : out Line_Position; + First_Column : out Column_Position; + Off_Screen : out Natural; + Additional_Buffers : out Buffer_Number); + -- AKA + pragma Inline (Info); + + -- ANCHOR(`dynamic_field_info()',`Dynamic_Info') + procedure Dynamic_Info (Fld : in Field; + Lines : out Line_Count; + Columns : out Column_Count; + Max : out Natural); + -- AKA + pragma Inline (Dynamic_Info); + + -- MANPAGE(`form_win.3x') + + -- ANCHOR(`set_form_win()',`Set_Window') + procedure Set_Window (Frm : in Form; + Win : in Window); + -- AKA + pragma Inline (Set_Window); + + -- ANCHOR(`form_win()',`Get_Window') + function Get_Window (Frm : Form) return Window; + -- AKA + pragma Inline (Get_Window); + + -- ANCHOR(`set_form_sub()',`Set_Sub_Window') + procedure Set_Sub_Window (Frm : in Form; + Win : in Window); + -- AKA + pragma Inline (Set_Sub_Window); + + -- ANCHOR(`form_sub()',`Get_Sub_Window') + function Get_Sub_Window (Frm : Form) return Window; + -- AKA + pragma Inline (Get_Sub_Window); + + -- ANCHOR(`scale_form()',`Scale') + procedure Scale (Frm : in Form; + Lines : out Line_Count; + Columns : out Column_Count); + -- AKA + pragma Inline (Scale); + + -- MANPAGE(`form_hook.3x') + + type Form_Hook_Function is access procedure (Frm : in Form); + pragma Convention (C, Form_Hook_Function); + + -- ANCHOR(`set_field_init()',`Set_Field_Init_Hook') + procedure Set_Field_Init_Hook (Frm : in Form; + Proc : in Form_Hook_Function); + -- AKA + pragma Inline (Set_Field_Init_Hook); + + -- ANCHOR(`set_field_term()',`Set_Field_Term_Hook') + procedure Set_Field_Term_Hook (Frm : in Form; + Proc : in Form_Hook_Function); + -- AKA + pragma Inline (Set_Field_Term_Hook); + + -- ANCHOR(`set_form_init()',`Set_Form_Init_Hook') + procedure Set_Form_Init_Hook (Frm : in Form; + Proc : in Form_Hook_Function); + -- AKA + pragma Inline (Set_Form_Init_Hook); + + -- ANCHOR(`set_form_term()',`Set_Form_Term_Hook') + procedure Set_Form_Term_Hook (Frm : in Form; + Proc : in Form_Hook_Function); + -- AKA + pragma Inline (Set_Form_Term_Hook); + + -- ANCHOR(`field_init()',`Get_Field_Init_Hook') + function Get_Field_Init_Hook (Frm : Form) return Form_Hook_Function; + -- AKA + pragma Import (C, Get_Field_Init_Hook, "field_init"); + + -- ANCHOR(`field_term()',`Get_Field_Term_Hook') + function Get_Field_Term_Hook (Frm : Form) return Form_Hook_Function; + -- AKA + pragma Import (C, Get_Field_Term_Hook, "field_term"); + + -- ANCHOR(`form_init()',`Get_Form_Init_Hook') + function Get_Form_Init_Hook (Frm : Form) return Form_Hook_Function; + -- AKA + pragma Import (C, Get_Form_Init_Hook, "form_init"); + + -- ANCHOR(`form_term()',`Get_Form_Term_Hook') + function Get_Form_Term_Hook (Frm : Form) return Form_Hook_Function; + -- AKA + pragma Import (C, Get_Form_Term_Hook, "form_term"); + + -- MANPAGE(`form_field.3x') + + -- ANCHOR(`set_form_fields()',`Redefine') + procedure Redefine (Frm : in Form; + Flds : in Field_Array_Access); + -- AKA + pragma Inline (Redefine); + + -- ANCHOR(`set_form_fields()',`Set_Fields') + procedure Set_Fields (Frm : in Form; + Flds : in Field_Array_Access) renames Redefine; + -- AKA + pragma Inline (Set_Fields); + + -- ANCHOR(`form_fields()',`Fields') + function Fields (Frm : Form; + Index : Positive) return Field; + -- AKA + pragma Inline (Fields); + + -- ANCHOR(`field_count()',`Field_Count') + function Field_Count (Frm : Form) return Natural; + -- AKA + pragma Inline (Field_Count); + + -- ANCHOR(`move_field()',`Move') + procedure Move (Fld : in Field; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Move); + + -- MANPAGE(`form_new.3x') + + -- ANCHOR(`new_form()',`Create') + function Create (Fields : Field_Array_Access) return Form; + -- AKA + pragma Inline (Create); + + -- ANCHOR(`new_form()',`New_Form') + function New_Form (Fields : Field_Array_Access) return Form + renames Create; + -- AKA + pragma Inline (New_Form); + + -- ANCHOR(`free_form()',`Delete') + procedure Delete (Frm : in out Form); + -- AKA + -- Reset Frm to Null_Form + pragma Inline (Delete); + + -- MANPAGE(`form_opts.3x') + + -- ANCHOR(`set_form_opts()',`Set_Options') + procedure Set_Options (Frm : in Form; + Options : in Form_Option_Set); + -- AKA + pragma Inline (Set_Options); + + -- ANCHOR(`form_opts_on()',`Switch_Options') + procedure Switch_Options (Frm : in Form; + Options : in Form_Option_Set; + On : Boolean := True); + -- AKA + -- ALIAS(`form_opts_off()') + pragma Inline (Switch_Options); + + -- ANCHOR(`form_opts()',`Get_Options') + procedure Get_Options (Frm : in Form; + Options : out Form_Option_Set); + -- AKA + + -- ANCHOR(`form_opts()',`Get_Options') + function Get_Options (Frm : Form := Null_Form) return Form_Option_Set; + -- AKA + pragma Inline (Get_Options); + + -- MANPAGE(`form_post.3x') + + -- ANCHOR(`post_form()',`Post') + procedure Post (Frm : in Form; + Post : in Boolean := True); + -- AKA + -- ALIAS(`unpost_form()') + pragma Inline (Post); + + -- MANPAGE(`form_cursor.3x') + + -- ANCHOR(`pos_form_cursor()',`Position_Cursor') + procedure Position_Cursor (Frm : Form); + -- AKA + pragma Inline (Position_Cursor); + + -- MANPAGE(`form_data.3x') + + -- ANCHOR(`data_ahead()',`Data_Ahead') + function Data_Ahead (Frm : Form) return Boolean; + -- AKA + pragma Inline (Data_Ahead); + + -- ANCHOR(`data_behind()',`Data_Behind') + function Data_Behind (Frm : Form) return Boolean; + -- AKA + pragma Inline (Data_Behind); + + -- MANPAGE(`form_driver.3x') + + type Driver_Result is (Form_Ok, + Request_Denied, + Unknown_Request, + Invalid_Field); + + -- ANCHOR(`form_driver()',`Driver') + function Driver (Frm : Form; + Key : Key_Code) return Driver_Result; + -- AKA + -- Driver not inlined + + -- MANPAGE(`form_page.3x') + + type Page_Number is new Natural; + + -- ANCHOR(`set_current_field()',`Set_Current') + procedure Set_Current (Frm : in Form; + Fld : in Field); + -- AKA + pragma Inline (Set_Current); + + -- ANCHOR(`current_field()',`Current') + function Current (Frm : in Form) return Field; + -- AKA + pragma Inline (Current); + + -- ANCHOR(`set_form_page()',`Set_Page') + procedure Set_Page (Frm : in Form; + Page : in Page_Number := Page_Number'First); + -- AKA + pragma Inline (Set_Page); + + -- ANCHOR(`form_page()',`Page') + function Page (Frm : Form) return Page_Number; + -- AKA + pragma Inline (Page); + + -- ANCHOR(`field_index()',`Get_Index') + function Get_Index (Fld : Field) return Positive; + -- AKA + -- Please note that in this binding we start the numbering of fields + -- with 1. So this is number is one more than you get from the low + -- level call. + pragma Inline (Get_Index); + + -- MANPAGE(`form_new_page.3x') + + -- ANCHOR(`set_new_page()',`Set_New_Page') + procedure Set_New_Page (Fld : in Field; + New_Page : in Boolean := True); + -- AKA + pragma Inline (Set_New_Page); + + -- ANCHOR(`new_page()',`Is_New_Page') + function Is_New_Page (Fld : Field) return Boolean; + -- AKA + pragma Inline (Is_New_Page); + +------------------------------------------------------------------------------ +private + type Field is new System.Storage_Elements.Integer_Address; + type Form is new System.Storage_Elements.Integer_Address; + + Null_Field : constant Field := 0; + Null_Form : constant Form := 0; + +end Terminal_Interface.Curses.Forms; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 new file mode 100644 index 0000000..d9b3503 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 @@ -0,0 +1,75 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-menus-item_user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menus.Item_User_Data -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ + +generic + type User is limited private; + type User_Access is access User; +package Terminal_Interface.Curses.Menus.Item_User_Data is + pragma Preelaborate (Terminal_Interface.Curses.Menus.Item_User_Data); + + -- The binding uses the same user pointer for menu items + -- as the low level C implementation. So you can safely + -- read or write the user pointer also with the C routines + -- + -- MANPAGE(`mitem_userptr.3x') + + -- ANCHOR(`set_item_userptr',`Set_User_Data') + procedure Set_User_Data (Itm : in Item; + Data : in User_Access); + -- AKA + pragma Inline (Set_User_Data); + + -- ANCHOR(`item_userptr',`Get_User_Data') + procedure Get_User_Data (Itm : in Item; + Data : out User_Access); + -- AKA + + -- ANCHOR(`item_userptr',`Get_User_Data') + function Get_User_Data (Itm : in Item) return User_Access; + -- AKA + -- Same as function + pragma Inline (Get_User_Data); + +end Terminal_Interface.Curses.Menus.Item_User_Data; + diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 new file mode 100644 index 0000000..57c57f7 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 @@ -0,0 +1,70 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-menus-menu_user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menus.Menu_User_Data -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ + +generic + type User is limited private; + type User_Access is access User; +package Terminal_Interface.Curses.Menus.Menu_User_Data is + pragma Preelaborate (Terminal_Interface.Curses.Menus.Menu_User_Data); + + -- MANPAGE(`menu_userptr.3x') + + -- ANCHOR(`set_menu_userptr',`Set_User_Data') + procedure Set_User_Data (Men : in Menu; + Data : in User_Access); + -- AKA + pragma Inline (Set_User_Data); + + -- ANCHOR(`menu_userptr',`Get_User_Data') + procedure Get_User_Data (Men : in Menu; + Data : out User_Access); + -- AKA + + -- ANCHOR(`menu_userptr',`Get_User_Data') + function Get_User_Data (Men : in Menu) return User_Access; + -- AKA + -- Same as function + pragma Inline (Get_User_Data); + +end Terminal_Interface.Curses.Menus.Menu_User_Data; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus.ads.m4 new file mode 100644 index 0000000..a718e97 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-menus.ads.m4 @@ -0,0 +1,594 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-menus__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menu -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +include(`Menu_Base_Defs') +with System; +with Ada.Characters.Latin_1; + +package Terminal_Interface.Curses.Menus is + pragma Preelaborate (Terminal_Interface.Curses.Menus); +include(`Menu_Linker_Options')dnl +include(`Linker_Options') + Space : Character renames Ada.Characters.Latin_1.Space; + + type Item is private; + type Menu is private; + + --------------------------- + -- Interface constants -- + --------------------------- + Null_Item : constant Item; + Null_Menu : constant Menu; + + subtype Menu_Request_Code is Key_Code + range (Key_Max + 1) .. (Key_Max + 17); + + -- The prefix M_ stands for "Menu Request" + M_Left_Item : constant Menu_Request_Code := Key_Max + 1; + M_Right_Item : constant Menu_Request_Code := Key_Max + 2; + M_Up_Item : constant Menu_Request_Code := Key_Max + 3; + M_Down_Item : constant Menu_Request_Code := Key_Max + 4; + M_ScrollUp_Line : constant Menu_Request_Code := Key_Max + 5; + M_ScrollDown_Line : constant Menu_Request_Code := Key_Max + 6; + M_ScrollDown_Page : constant Menu_Request_Code := Key_Max + 7; + M_ScrollUp_Page : constant Menu_Request_Code := Key_Max + 8; + M_First_Item : constant Menu_Request_Code := Key_Max + 9; + M_Last_Item : constant Menu_Request_Code := Key_Max + 10; + M_Next_Item : constant Menu_Request_Code := Key_Max + 11; + M_Previous_Item : constant Menu_Request_Code := Key_Max + 12; + M_Toggle_Item : constant Menu_Request_Code := Key_Max + 13; + M_Clear_Pattern : constant Menu_Request_Code := Key_Max + 14; + M_Back_Pattern : constant Menu_Request_Code := Key_Max + 15; + M_Next_Match : constant Menu_Request_Code := Key_Max + 16; + M_Previous_Match : constant Menu_Request_Code := Key_Max + 17; + + -- For those who like the old 'C' names for the request codes + REQ_LEFT_ITEM : Menu_Request_Code renames M_Left_Item; + REQ_RIGHT_ITEM : Menu_Request_Code renames M_Right_Item; + REQ_UP_ITEM : Menu_Request_Code renames M_Up_Item; + REQ_DOWN_ITEM : Menu_Request_Code renames M_Down_Item; + REQ_SCR_ULINE : Menu_Request_Code renames M_ScrollUp_Line; + REQ_SCR_DLINE : Menu_Request_Code renames M_ScrollDown_Line; + REQ_SCR_DPAGE : Menu_Request_Code renames M_ScrollDown_Page; + REQ_SCR_UPAGE : Menu_Request_Code renames M_ScrollUp_Page; + REQ_FIRST_ITEM : Menu_Request_Code renames M_First_Item; + REQ_LAST_ITEM : Menu_Request_Code renames M_Last_Item; + REQ_NEXT_ITEM : Menu_Request_Code renames M_Next_Item; + REQ_PREV_ITEM : Menu_Request_Code renames M_Previous_Item; + REQ_TOGGLE_ITEM : Menu_Request_Code renames M_Toggle_Item; + REQ_CLEAR_PATTERN : Menu_Request_Code renames M_Clear_Pattern; + REQ_BACK_PATTERN : Menu_Request_Code renames M_Back_Pattern; + REQ_NEXT_MATCH : Menu_Request_Code renames M_Next_Match; + REQ_PREV_MATCH : Menu_Request_Code renames M_Previous_Match; + + procedure Request_Name (Key : in Menu_Request_Code; + Name : out String); + + function Request_Name (Key : Menu_Request_Code) return String; + -- Same as function + + ------------------ + -- Exceptions -- + ------------------ + + Menu_Exception : exception; + -- + -- Menu options + -- + pragma Warnings (Off); +include(`Menu_Opt_Rep')dnl + + pragma Warnings (On); + + function Default_Menu_Options return Menu_Option_Set; + -- Initial default options for a menu. + pragma Inline (Default_Menu_Options); + -- + -- Item options + -- + pragma Warnings (Off); +include(`Item_Rep')dnl + + pragma Warnings (On); + + function Default_Item_Options return Item_Option_Set; + -- Initial default options for an item. + pragma Inline (Default_Item_Options); + + -- + -- Item Array + -- + type Item_Array is array (Positive range <>) of aliased Item; + pragma Convention (C, Item_Array); + + type Item_Array_Access is access Item_Array; + + procedure Free (IA : in out Item_Array_Access; + Free_Items : Boolean := False); + -- Release the memory for an allocated item array + -- If Free_Items is True, call Delete() for all the items in + -- the array. + + -- MANPAGE(`mitem_new.3x') + + -- ANCHOR(`new_item()',`Create') + function Create (Name : String; + Description : String := "") return Item; + -- AKA + -- Not inlined. + + -- ANCHOR(`new_item()',`New_Item') + function New_Item (Name : String; + Description : String := "") return Item + renames Create; + -- AKA + + -- ANCHOR(`free_item()',`Delete') + procedure Delete (Itm : in out Item); + -- AKA + -- Resets Itm to Null_Item + + -- MANPAGE(`mitem_value.3x') + + -- ANCHOR(`set_item_value()',`Set_Value') + procedure Set_Value (Itm : in Item; + Value : in Boolean := True); + -- AKA + pragma Inline (Set_Value); + + -- ANCHOR(`item_value()',`Value') + function Value (Itm : Item) return Boolean; + -- AKA + pragma Inline (Value); + + -- MANPAGE(`mitem_visible.3x') + + -- ANCHOR(`item_visible()',`Visible') + function Visible (Itm : Item) return Boolean; + -- AKA + pragma Inline (Visible); + + -- MANPAGE(`mitem_opts.3x') + + -- ANCHOR(`set_item_opts()',`Set_Options') + procedure Set_Options (Itm : in Item; + Options : in Item_Option_Set); + -- AKA + -- An overloaded Set_Options is defined later. Pragma Inline appears there + + -- ANCHOR(`item_opts_on()',`Switch_Options') + procedure Switch_Options (Itm : in Item; + Options : in Item_Option_Set; + On : Boolean := True); + -- AKA + -- ALIAS(`item_opts_off()') + -- An overloaded Switch_Options is defined later. + -- Pragma Inline appears there + + -- ANCHOR(`item_opts()',`Get_Options') + procedure Get_Options (Itm : in Item; + Options : out Item_Option_Set); + -- AKA + + -- ANCHOR(`item_opts()',`Get_Options') + function Get_Options (Itm : Item := Null_Item) return Item_Option_Set; + -- AKA + -- An overloaded Get_Options is defined later. Pragma Inline appears there + + -- MANPAGE(`mitem_name.3x') + + -- ANCHOR(`item_name()',`Name') + procedure Name (Itm : in Item; + Name : out String); + -- AKA + function Name (Itm : Item) return String; + -- AKA + -- Implemented as function + pragma Inline (Name); + + -- ANCHOR(`item_description();',`Description') + procedure Description (Itm : in Item; + Description : out String); + -- AKA + + function Description (Itm : Item) return String; + -- AKA + -- Implemented as function + pragma Inline (Description); + + -- MANPAGE(`mitem_current.3x') + + -- ANCHOR(`set_current_item()',`Set_Current') + procedure Set_Current (Men : in Menu; + Itm : in Item); + -- AKA + pragma Inline (Set_Current); + + -- ANCHOR(`current_item()',`Current') + function Current (Men : Menu) return Item; + -- AKA + pragma Inline (Current); + + -- ANCHOR(`set_top_row()',`Set_Top_Row') + procedure Set_Top_Row (Men : in Menu; + Line : in Line_Position); + -- AKA + pragma Inline (Set_Top_Row); + + -- ANCHOR(`top_row()',`Top_Row') + function Top_Row (Men : Menu) return Line_Position; + -- AKA + pragma Inline (Top_Row); + + -- ANCHOR(`item_index()',`Get_Index') + function Get_Index (Itm : Item) return Positive; + -- AKA + -- Please note that in this binding we start the numbering of items + -- with 1. So this is number is one more than you get from the low + -- level call. + pragma Inline (Get_Index); + + -- MANPAGE(`menu_post.3x') + + -- ANCHOR(`post_menu()',`Post') + procedure Post (Men : in Menu; + Post : in Boolean := True); + -- AKA + -- ALIAS(`unpost_menu()') + pragma Inline (Post); + + -- MANPAGE(`menu_opts.3x') + + -- ANCHOR(`set_menu_opts()',`Set_Options') + procedure Set_Options (Men : in Menu; + Options : in Menu_Option_Set); + -- AKA + pragma Inline (Set_Options); + + -- ANCHOR(`menu_opts_on()',`Switch_Options') + procedure Switch_Options (Men : in Menu; + Options : in Menu_Option_Set; + On : Boolean := True); + -- AKA + -- ALIAS(`menu_opts_off()') + pragma Inline (Switch_Options); + + -- ANCHOR(`menu_opts()',`Get_Options') + procedure Get_Options (Men : in Menu; + Options : out Menu_Option_Set); + -- AKA + + -- ANCHOR(`menu_opts()',`Get_Options') + function Get_Options (Men : Menu := Null_Menu) return Menu_Option_Set; + -- AKA + pragma Inline (Get_Options); + + -- MANPAGE(`menu_win.3x') + + -- ANCHOR(`set_menu_win()',`Set_Window') + procedure Set_Window (Men : in Menu; + Win : in Window); + -- AKA + pragma Inline (Set_Window); + + -- ANCHOR(`menu_win()',`Get_Window') + function Get_Window (Men : Menu) return Window; + -- AKA + pragma Inline (Get_Window); + + -- ANCHOR(`set_menu_sub()',`Set_Sub_Window') + procedure Set_Sub_Window (Men : in Menu; + Win : in Window); + -- AKA + pragma Inline (Set_Sub_Window); + + -- ANCHOR(`menu_sub()',`Get_Sub_Window') + function Get_Sub_Window (Men : Menu) return Window; + -- AKA + pragma Inline (Get_Sub_Window); + + -- ANCHOR(`scale_menu()',`Scale') + procedure Scale (Men : in Menu; + Lines : out Line_Count; + Columns : out Column_Count); + -- AKA + pragma Inline (Scale); + + -- MANPAGE(`menu_cursor.3x') + + -- ANCHOR(`pos_menu_cursor()',`Position_Cursor') + procedure Position_Cursor (Men : Menu); + -- AKA + pragma Inline (Position_Cursor); + + -- MANPAGE(`menu_mark.3x') + + -- ANCHOR(`set_menu_mark()',`Set_Mark') + procedure Set_Mark (Men : in Menu; + Mark : in String); + -- AKA + pragma Inline (Set_Mark); + + -- ANCHOR(`menu_mark()',`Mark') + procedure Mark (Men : in Menu; + Mark : out String); + -- AKA + + function Mark (Men : Menu) return String; + -- AKA + -- Implemented as function + pragma Inline (Mark); + + -- MANPAGE(`menu_attribs.3x') + + -- ANCHOR(`set_menu_fore()',`Set_Foreground') + procedure Set_Foreground + (Men : in Menu; + Fore : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Foreground); + + -- ANCHOR(`menu_fore()',`Foreground') + procedure Foreground (Men : in Menu; + Fore : out Character_Attribute_Set); + -- AKA + + -- ANCHOR(`menu_fore()',`Foreground') + procedure Foreground (Men : in Menu; + Fore : out Character_Attribute_Set; + Color : out Color_Pair); + -- AKA + pragma Inline (Foreground); + + -- ANCHOR(`set_menu_back()',`Set_Background') + procedure Set_Background + (Men : in Menu; + Back : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Background); + + -- ANCHOR(`menu_back()',`Background') + procedure Background (Men : in Menu; + Back : out Character_Attribute_Set); + -- AKA + -- ANCHOR(`menu_back()',`Background') + + procedure Background (Men : in Menu; + Back : out Character_Attribute_Set; + Color : out Color_Pair); + -- AKA + pragma Inline (Background); + + -- ANCHOR(`set_menu_grey()',`Set_Grey') + procedure Set_Grey + (Men : in Menu; + Grey : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Grey); + + -- ANCHOR(`menu_grey()',`Grey') + procedure Grey (Men : in Menu; + Grey : out Character_Attribute_Set); + -- AKA + + -- ANCHOR(`menu_grey()',`Grey') + procedure Grey + (Men : in Menu; + Grey : out Character_Attribute_Set; + Color : out Color_Pair); + -- AKA + pragma Inline (Grey); + + -- ANCHOR(`set_menu_pad()',`Set_Pad_Character') + procedure Set_Pad_Character (Men : in Menu; + Pad : in Character := Space); + -- AKA + pragma Inline (Set_Pad_Character); + + -- ANCHOR(`menu_pad()',`Pad_Character') + procedure Pad_Character (Men : in Menu; + Pad : out Character); + -- AKA + pragma Inline (Pad_Character); + + -- MANPAGE(`menu_spacing.3x') + + -- ANCHOR(`set_menu_spacing()',`Set_Spacing') + procedure Set_Spacing (Men : in Menu; + Descr : in Column_Position := 0; + Row : in Line_Position := 0; + Col : in Column_Position := 0); + -- AKA + pragma Inline (Set_Spacing); + + -- ANCHOR(`menu_spacing()',`Spacing') + procedure Spacing (Men : in Menu; + Descr : out Column_Position; + Row : out Line_Position; + Col : out Column_Position); + -- AKA + pragma Inline (Spacing); + + -- MANPAGE(`menu_pattern.3x') + + -- ANCHOR(`set_menu_pattern()',`Set_Pattern') + function Set_Pattern (Men : Menu; + Text : String) return Boolean; + -- AKA + -- Return TRUE if the pattern matches, FALSE otherwise + pragma Inline (Set_Pattern); + + -- ANCHOR(`menu_pattern()',`Pattern') + procedure Pattern (Men : in Menu; + Text : out String); + -- AKA + pragma Inline (Pattern); + + -- MANPAGE(`menu_format.3x') + + -- ANCHOR(`set_menu_format()',`Set_Format') + procedure Set_Format (Men : in Menu; + Lines : in Line_Count; + Columns : in Column_Count); + -- AKA + pragma Inline (Set_Format); + + -- ANCHOR(`menu_format()',`Format') + procedure Format (Men : in Menu; + Lines : out Line_Count; + Columns : out Column_Count); + -- AKA + pragma Inline (Format); + + -- MANPAGE(`menu_hook.3x') + + type Menu_Hook_Function is access procedure (Men : in Menu); + pragma Convention (C, Menu_Hook_Function); + + -- ANCHOR(`set_item_init()',`Set_Item_Init_Hook') + procedure Set_Item_Init_Hook (Men : in Menu; + Proc : in Menu_Hook_Function); + -- AKA + pragma Inline (Set_Item_Init_Hook); + + -- ANCHOR(`set_item_term()',`Set_Item_Term_Hook') + procedure Set_Item_Term_Hook (Men : in Menu; + Proc : in Menu_Hook_Function); + -- AKA + pragma Inline (Set_Item_Term_Hook); + + -- ANCHOR(`set_menu_init()',`Set_Menu_Init_Hook') + procedure Set_Menu_Init_Hook (Men : in Menu; + Proc : in Menu_Hook_Function); + -- AKA + pragma Inline (Set_Menu_Init_Hook); + + -- ANCHOR(`set_menu_term()',`Set_Menu_Term_Hook') + procedure Set_Menu_Term_Hook (Men : in Menu; + Proc : in Menu_Hook_Function); + -- AKA + pragma Inline (Set_Menu_Term_Hook); + + -- ANCHOR(`item_init()',`Get_Item_Init_Hook') + function Get_Item_Init_Hook (Men : Menu) return Menu_Hook_Function; + -- AKA + pragma Inline (Get_Item_Init_Hook); + + -- ANCHOR(`item_term()',`Get_Item_Term_Hook') + function Get_Item_Term_Hook (Men : Menu) return Menu_Hook_Function; + -- AKA + pragma Inline (Get_Item_Term_Hook); + + -- ANCHOR(`menu_init()',`Get_Menu_Init_Hook') + function Get_Menu_Init_Hook (Men : Menu) return Menu_Hook_Function; + -- AKA + pragma Inline (Get_Menu_Init_Hook); + + -- ANCHOR(`menu_term()',`Get_Menu_Term_Hook') + function Get_Menu_Term_Hook (Men : Menu) return Menu_Hook_Function; + -- AKA + pragma Inline (Get_Menu_Term_Hook); + + -- MANPAGE(`menu_items.3x') + + -- ANCHOR(`set_menu_items()',`Redefine') + procedure Redefine (Men : in Menu; + Items : in Item_Array_Access); + -- AKA + pragma Inline (Redefine); + + procedure Set_Items (Men : in Menu; + Items : in Item_Array_Access) renames Redefine; + pragma Inline (Set_Items); + + -- ANCHOR(`menu_items()',`Items') + function Items (Men : Menu; + Index : Positive) return Item; + -- AKA + pragma Inline (Items); + + -- ANCHOR(`item_count()',`Item_Count') + function Item_Count (Men : Menu) return Natural; + -- AKA + pragma Inline (Item_Count); + + -- MANPAGE(`menu_new.3x') + + -- ANCHOR(`new_menu()',`Create') + function Create (Items : Item_Array_Access) return Menu; + -- AKA + -- Not inlined + + function New_Menu (Items : Item_Array_Access) return Menu renames Create; + + -- ANCHOR(`free_menu()',`Delete') + procedure Delete (Men : in out Menu); + -- AKA + -- Reset Men to Null_Menu + -- Not inlined + + -- MANPAGE(`menu_new.3x') + + type Driver_Result is (Menu_Ok, + Request_Denied, + Unknown_Request, + No_Match); + + -- ANCHOR(`menu_driver()',`Driver') + function Driver (Men : Menu; + Key : Key_Code) return Driver_Result; + -- AKA + -- Driver is not inlined + +------------------------------------------------------------------------------- +private + type Item is new System.Storage_Elements.Integer_Address; + type Menu is new System.Storage_Elements.Integer_Address; + + Null_Item : constant Item := 0; + Null_Menu : constant Menu := 0; + +end Terminal_Interface.Curses.Menus; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-mouse.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-mouse.ads.m4 new file mode 100644 index 0000000..21e1ef3 --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-mouse.ads.m4 @@ -0,0 +1,173 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-mouse__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Mouse -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +include(`Mouse_Base_Defs') +with System; + +package Terminal_Interface.Curses.Mouse is + pragma Preelaborate (Terminal_Interface.Curses.Mouse); + + -- MANPAGE(`curs_mouse.3x') + -- Please note, that in ncurses-1.9.9e documentation mouse support + -- is still marked as experimental. So also this binding will change + -- if the ncurses methods change. + -- + type Event_Mask is private; + No_Events : constant Event_Mask; + All_Events : constant Event_Mask; + + type Mouse_Button is (Left, -- aka: Button 1 + Middle, -- aka: Button 2 + Right, -- aka: Button 3 + Button4, -- aka: Button 4 + Control, -- Control Key + Shift, -- Shift Key + Alt); -- ALT Key + + subtype Real_Buttons is Mouse_Button range Left .. Button4; + subtype Modifier_Keys is Mouse_Button range Control .. Alt; + + type Button_State is (Released, + Pressed, + Clicked, + Double_Clicked, + Triple_Clicked); + + type Button_States is array (Button_State) of Boolean; + pragma Pack (Button_States); + + All_Clicks : constant Button_States := (Clicked .. Triple_Clicked => True, + others => False); + All_States : constant Button_States := (others => True); + + type Mouse_Event is private; + + -- MANPAGE(`curs_mouse.3x') + + function Has_Mouse return Boolean; + -- Return true if a mouse device is supported, false otherwise. + + procedure Register_Reportable_Event + (Button : in Mouse_Button; + State : in Button_State; + Mask : in out Event_Mask); + -- Stores the event described by the button and the state in the mask. + -- Before you call this the first time, you should init the mask + -- with the Empty_Mask constant + pragma Inline (Register_Reportable_Event); + + procedure Register_Reportable_Events + (Button : in Mouse_Button; + State : in Button_States; + Mask : in out Event_Mask); + -- Register all events described by the Button and the State bitmap. + -- Before you call this the first time, you should init the mask + -- with the Empty_Mask constant + + -- ANCHOR(`mousemask()',`Start_Mouse') + -- There is one difference to mousmask(): we return the value of the + -- old mask, that means the event mask value before this call. + function Start_Mouse (Mask : Event_Mask := All_Events) + return Event_Mask; + -- AKA + pragma Inline (Start_Mouse); + + procedure End_Mouse (Mask : in Event_Mask := No_Events); + -- Terminates the mouse, restores the specified event mask + pragma Inline (End_Mouse); + + -- ANCHOR(`getmouse()',`Get_Mouse') + function Get_Mouse return Mouse_Event; + -- AKA + pragma Inline (Get_Mouse); + + procedure Get_Event (Event : in Mouse_Event; + Y : out Line_Position; + X : out Column_Position; + Button : out Mouse_Button; + State : out Button_State); + -- !!! Warning: X and Y are screen coordinates. Due to ripped of lines they + -- may not be identical to window coordinates. + pragma Inline (Get_Event); + + -- ANCHOR(`ungetmouse()',`Unget_Mouse') + procedure Unget_Mouse (Event : in Mouse_Event); + -- AKA + pragma Inline (Unget_Mouse); + + -- ANCHOR(`wenclose()',`Enclosed_In_Window') + function Enclosed_In_Window (Win : Window := Standard_Window; + Event : Mouse_Event) return Boolean; + -- AKA + -- But : use event instead of screen coordinates. + pragma Inline (Enclosed_In_Window); + + -- ANCHOR(`mouseinterval()',`Mouse_Interval') + function Mouse_Interval (Msec : Natural := 200) return Natural; + -- AKA + pragma Inline (Mouse_Interval); + +private + type Event_Mask is new Interfaces.C.unsigned_long; + + type Mouse_Event is + record + Id : Integer range Integer (Interfaces.C.short'First) .. + Integer (Interfaces.C.short'Last); + X, Y, Z : Integer range Integer (Interfaces.C.int'First) .. + Integer (Interfaces.C.int'Last); + Bstate : Event_Mask; + end record; + pragma Convention (C, Mouse_Event); + pragma Pack (Mouse_Event); + +include(`Mouse_Event_Rep') + Generation_Bit_Order : constant System.Bit_Order := System.M4_BIT_ORDER; + -- This constant may be different on your system. + +include(`Mouse_Events') + + No_Events : constant Event_Mask := 0; + All_Events : constant Event_Mask := ALL_MOUSE_EVENTS; + +end Terminal_Interface.Curses.Mouse; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 new file mode 100644 index 0000000..f126aee --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 @@ -0,0 +1,70 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-panels-user_data__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Panels.User_Data -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ + +generic + type User is limited private; + type User_Access is access all User; +package Terminal_Interface.Curses.Panels.User_Data is + pragma Preelaborate (Terminal_Interface.Curses.Panels.User_Data); + + -- MANPAGE(`panel.3x') + + -- ANCHOR(`set_panel_userptr',`Set_User_Data') + procedure Set_User_Data (Pan : in Panel; + Data : in User_Access); + -- AKA + pragma Inline (Set_User_Data); + + -- ANCHOR(`panel_userptr',`Get_User_Data') + procedure Get_User_Data (Pan : in Panel; + Data : out User_Access); + -- AKA + + -- ANCHOR(`panel_userptr',`Get_User_Data') + function Get_User_Data (Pan : in Panel) return User_Access; + -- AKA + -- Same as function + pragma Inline (Get_User_Data); + +end Terminal_Interface.Curses.Panels.User_Data; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels.ads.m4 new file mode 100644 index 0000000..f0982ef --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses-panels.ads.m4 @@ -0,0 +1,146 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses-panels__ads.htm')dnl +include(M4MACRO)dnl +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Panels -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with System; + +package Terminal_Interface.Curses.Panels is + pragma Preelaborate (Terminal_Interface.Curses.Panels); +include(`Panel_Linker_Options')dnl +include(`Linker_Options') + type Panel is private; + + --------------------------- + -- Interface constants -- + --------------------------- + Null_Panel : constant Panel; + + ------------------- + -- Exceptions -- + ------------------- + + Panel_Exception : exception; + + -- MANPAGE(`panel.3x') + + -- ANCHOR(`new_panel()',`Create') + function Create (Win : Window) return Panel; + -- AKA + pragma Inline (Create); + + -- ANCHOR(`new_panel()',`New_Panel') + function New_Panel (Win : Window) return Panel renames Create; + -- AKA + pragma Inline (New_Panel); + + -- ANCHOR(`bottom_panel()',`Bottom') + procedure Bottom (Pan : in Panel); + -- AKA + pragma Inline (Bottom); + + -- ANCHOR(`top_panel()',`Top') + procedure Top (Pan : in Panel); + -- AKA + pragma Inline (Top); + + -- ANCHOR(`show_panel()',`Show') + procedure Show (Pan : in Panel); + -- AKA + pragma Inline (Show); + + -- ANCHOR(`update_panels()',`Update_Panels') + procedure Update_Panels; + -- AKA + pragma Import (C, Update_Panels, "update_panels"); + + -- ANCHOR(`hide_panel()',`Hide') + procedure Hide (Pan : in Panel); + -- AKA + pragma Inline (Hide); + + -- ANCHOR(`panel_window()',`Get_Window') + function Get_Window (Pan : Panel) return Window; + -- AKA + pragma Inline (Get_Window); + + -- ANCHOR(`panel_window()',`Panel_Window') + function Panel_Window (Pan : Panel) return Window renames Get_Window; + pragma Inline (Panel_Window); + + -- ANCHOR(`replace_panel()',`Replace') + procedure Replace (Pan : in Panel; + Win : in Window); + -- AKA + pragma Inline (Replace); + + -- ANCHOR(`move_panel()',`Move') + procedure Move (Pan : in Panel; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Move); + + -- ANCHOR(`panel_hidden()',`Is_Hidden') + function Is_Hidden (Pan : Panel) return Boolean; + -- AKA + pragma Inline (Is_Hidden); + + -- ANCHOR(`panel_above()',`Above') + function Above (Pan : Panel) return Panel; + -- AKA + pragma Import (C, Above, "panel_above"); + + -- ANCHOR(`panel_below()',`Below') + function Below (Pan : Panel) return Panel; + -- AKA + pragma Import (C, Below, "panel_below"); + + -- ANCHOR(`del_panel()',`Delete') + procedure Delete (Pan : in out Panel); + -- AKA + pragma Inline (Delete); + +private + type Panel is new System.Storage_Elements.Integer_Address; + Null_Panel : constant Panel := 0; + +end Terminal_Interface.Curses.Panels; diff --git a/ncurses-5.2/Ada95/gen/terminal_interface-curses.ads.m4 b/ncurses-5.2/Ada95/gen/terminal_interface-curses.ads.m4 new file mode 100644 index 0000000..be2f02b --- /dev/null +++ b/ncurses-5.2/Ada95/gen/terminal_interface-curses.ads.m4 @@ -0,0 +1,1388 @@ +-- -*- ada -*- +define(`HTMLNAME',`terminal_interface-curses__ads.htm')dnl +include(M4MACRO)------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +include(`Base_Defs') +with System.Storage_Elements; +with Interfaces.C; -- We need this for some assertions. + +package Terminal_Interface.Curses is + pragma Preelaborate (Terminal_Interface.Curses); +include(`Linker_Options') +include(`Version_Info') + type Window is private; + Null_Window : constant Window; + + type Line_Position is new Natural; -- line coordinate + type Column_Position is new Natural; -- column coordinate + + subtype Line_Count is Line_Position range 1 .. Line_Position'Last; + -- Type to count lines. We do not allow null windows, so must be positive + subtype Column_Count is Column_Position range 1 .. Column_Position'Last; + -- Type to count columns. We do not allow null windows, so must be positive + + type Key_Code is new Natural; + -- That is anything including real characters, special keys and logical + -- request codes. + + subtype Real_Key_Code is Key_Code range 0 .. M4_KEY_MAX; + -- This are the codes that potentially represent a real keystroke. + -- Not all codes may be possible on a specific terminal. To check the + -- availability of a special key, the Has_Key function is provided. + + subtype Special_Key_Code is Real_Key_Code + range M4_SPECIAL_FIRST .. Real_Key_Code'Last; + -- Type for a function- or special key number + + subtype Normal_Key_Code is Real_Key_Code range + Character'Pos (Character'First) .. Character'Pos (Character'Last); + -- This are the codes for regular (incl. non-graphical) characters. + + -- Constants for function- and special keys + -- + Key_None : constant Special_Key_Code := M4_SPECIAL_FIRST; +include(`Key_Definitions') + Key_Max : constant Special_Key_Code + := Special_Key_Code'Last; + + subtype User_Key_Code is Key_Code + range (Key_Max + 129) .. Key_Code'Last; + -- This is reserved for user defined key codes. The range between Key_Max + -- and the first user code is reserved for subsystems like menu and forms. + + -- For those who like to use the original key names we produce them were + -- they differ from the original. Please note that they may differ in + -- lower/upper case. +include(`Old_Keys')dnl + +------------------------------------------------------------------------------ + + type Color_Number is range 0 .. Integer (Interfaces.C.short'Last); + for Color_Number'Size use Interfaces.C.short'Size; + -- (n)curses uses a short for the color index + -- The model is, that a Color_Number is an index into an array of + -- (potentially) definable colors. Some of those indices are + -- predefined (see below), although they may not really exist. + +include(`Color_Defs') + type RGB_Value is range 0 .. Integer (Interfaces.C.short'Last); + for RGB_Value'Size use Interfaces.C.short'Size; + -- Some system may allow to redefine a color by setting RGB values. + + type Color_Pair is range 0 .. 255; + for Color_Pair'Size use 8; + subtype Redefinable_Color_Pair is Color_Pair range 1 .. 255; + -- (n)curses reserves 1 Byte for the color-pair number. Color Pair 0 + -- is fixed (Black & White). A color pair is simply a combination of + -- two colors described by Color_Numbers, one for the foreground and + -- the other for the background + +include(`Character_Attribute_Set_Rep') + -- (n)curses uses all but the lowest 16 Bits for Attributes. + + Normal_Video : constant Character_Attribute_Set := (others => False); + + type Attributed_Character is + record + Attr : Character_Attribute_Set; + Color : Color_Pair; + Ch : Character; + end record; + pragma Convention (C, Attributed_Character); + -- This is the counterpart for the chtype in C. + +include(`AC_Rep') + Default_Character : constant Attributed_Character + := (Ch => Character'First, + Color => Color_Pair'First, + Attr => (others => False)); -- preelaboratable Normal_Video + + type Attributed_String is array (Positive range <>) of Attributed_Character; + pragma Pack (Attributed_String); + -- In this binding we allow strings of attributed characters. + + ------------------ + -- Exceptions -- + ------------------ + Curses_Exception : exception; + Wrong_Curses_Version : exception; + + -- Those exceptions are raised by the ETI (Extended Terminal Interface) + -- subpackets for Menu and Forms handling. + -- + Eti_System_Error : exception; + Eti_Bad_Argument : exception; + Eti_Posted : exception; + Eti_Connected : exception; + Eti_Bad_State : exception; + Eti_No_Room : exception; + Eti_Not_Posted : exception; + Eti_Unknown_Command : exception; + Eti_No_Match : exception; + Eti_Not_Selectable : exception; + Eti_Not_Connected : exception; + Eti_Request_Denied : exception; + Eti_Invalid_Field : exception; + Eti_Current : exception; + + -------------------------------------------------------------------------- + -- External C variables + -- Conceptually even in C this are kind of constants, but they are + -- initialized and sometimes changed by the library routines at runtime + -- depending on the type of terminal. I believe the best way to model + -- this is to use functions. + -------------------------------------------------------------------------- + + function Lines return Line_Count; + pragma Inline (Lines); + + function Columns return Column_Count; + pragma Inline (Columns); + + function Tab_Size return Natural; + pragma Inline (Tab_Size); + + function Number_Of_Colors return Natural; + pragma Inline (Number_Of_Colors); + + function Number_Of_Color_Pairs return Natural; + pragma Inline (Number_Of_Color_Pairs); + + ACS_Map : array (Character'Val (0) .. Character'Val (127)) of + Attributed_Character; + pragma Import (C, ACS_Map, "acs_map"); + -- + -- + -- Constants for several characters from the Alternate Character Set + -- You must use this constants as indices into the ACS_Map array + -- to get the corresponding attributed character at runtime. + -- +include(`ACS_Map')dnl + + -- MANPAGE(`curs_initscr.3x') + -- | Not implemented: newterm, set_term, delscreen + + -- ANCHOR(`stdscr',`Standard_Window') + function Standard_Window return Window; + -- AKA + pragma Inline (Standard_Window); + + -- ANCHOR(`initscr()',`Init_Screen') + procedure Init_Screen; + + -- ANCHOR(`initscr()',`Init_Windows') + procedure Init_Windows renames Init_Screen; + -- AKA + pragma Inline (Init_Screen); + pragma Inline (Init_Windows); + + -- ANCHOR(`endwin()',`End_Windows') + procedure End_Windows; + -- AKA + procedure End_Screen renames End_Windows; + pragma Inline (End_Windows); + pragma Inline (End_Screen); + + -- ANCHOR(`isendwin()',`Is_End_Window') + function Is_End_Window return Boolean; + -- AKA + pragma Inline (Is_End_Window); + + -- MANPAGE(`curs_move.3x') + + -- ANCHOR(`wmove()',`Move_Cursor') + procedure Move_Cursor (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Move_Cursor); + + -- MANPAGE(`curs_addch.3x') + + -- ANCHOR(`waddch()',`Add') + procedure Add (Win : in Window := Standard_Window; + Ch : in Attributed_Character); + -- AKA + + procedure Add (Win : in Window := Standard_Window; + Ch : in Character); + -- Add a single character at the current logical cursor position to + -- the window. Use the current windows attributes. + + -- ANCHOR(`mvwaddch()',`Add') + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Attributed_Character); + -- AKA + + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Character); + -- Move to the position and add a single character into the window + -- There are more Add routines, so the Inline pragma follows later + + -- ANCHOR(`wechochar()',`Add_With_Immediate_Echo') + procedure Add_With_Immediate_Echo + (Win : in Window := Standard_Window; + Ch : in Attributed_Character); + -- AKA + + procedure Add_With_Immediate_Echo + (Win : in Window := Standard_Window; + Ch : in Character); + -- Add a character and do an immediate refresh of the screen. + pragma Inline (Add_With_Immediate_Echo); + + -- MANPAGE(`curs_window.3x') + + -- ANCHOR(`newwin()',`Create') + function Create + (Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window; + -- AKA + pragma Inline (Create); + + function New_Window + (Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window + renames Create; + pragma Inline (New_Window); + + -- ANCHOR(`delwin()',`Delete') + procedure Delete (Win : in out Window); + -- AKA + -- Reset Win to Null_Window + pragma Inline (Delete); + + -- ANCHOR(`subwin()',`Sub_Window') + function Sub_Window + (Win : Window := Standard_Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window; + -- AKA + pragma Inline (Sub_Window); + + -- ANCHOR(`derwin()',`Derived_Window') + function Derived_Window + (Win : Window := Standard_Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window; + -- AKA + pragma Inline (Derived_Window); + + -- ANCHOR(`dupwin()',`Duplicate') + function Duplicate (Win : Window) return Window; + -- AKA + pragma Inline (Duplicate); + + -- ANCHOR(`mvwin()',`Move_Window') + procedure Move_Window (Win : in Window; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Move_Window); + + -- ANCHOR(`mvderwin()',`Move_Derived_Window') + procedure Move_Derived_Window (Win : in Window; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Move_Derived_Window); + + -- ANCHOR(`wsyncup()',`Synchronize_Upwards') + procedure Synchronize_Upwards (Win : in Window); + -- AKA + pragma Import (C, Synchronize_Upwards, "wsyncup"); + + -- ANCHOR(`wsyncdown()',`Synchronize_Downwards') + procedure Synchronize_Downwards (Win : in Window); + -- AKA + pragma Import (C, Synchronize_Downwards, "wsyncdown"); + + -- ANCHOR(`syncok()',`Set_Synch_Mode') + procedure Set_Synch_Mode (Win : in Window := Standard_Window; + Mode : in Boolean := False); + -- AKA + pragma Inline (Set_Synch_Mode); + + -- MANPAGE(`curs_addstr.3x') + + -- ANCHOR(`waddnstr()',`Add') + procedure Add (Win : in Window := Standard_Window; + Str : in String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`waddstr()') + + -- ANCHOR(`mvwaddnstr()',`Add') + procedure Add (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`mvwaddstr()') + + -- MANPAGE(`curs_addchstr.3x') + + -- ANCHOR(`waddchnstr()',`Add') + procedure Add (Win : in Window := Standard_Window; + Str : in Attributed_String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`waddchstr()') + + -- ANCHOR(`mvwaddchnstr()',`Add') + procedure Add (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in Attributed_String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`mvwaddchstr()') + pragma Inline (Add); + + -- MANPAGE(`curs_border.3x') + + -- ANCHOR(`wborder()',`Border') + procedure Border + (Win : in Window := Standard_Window; + Left_Side_Symbol : in Attributed_Character := Default_Character; + Right_Side_Symbol : in Attributed_Character := Default_Character; + Top_Side_Symbol : in Attributed_Character := Default_Character; + Bottom_Side_Symbol : in Attributed_Character := Default_Character; + Upper_Left_Corner_Symbol : in Attributed_Character := Default_Character; + Upper_Right_Corner_Symbol : in Attributed_Character := Default_Character; + Lower_Left_Corner_Symbol : in Attributed_Character := Default_Character; + Lower_Right_Corner_Symbol : in Attributed_Character := Default_Character + ); + -- AKA + pragma Inline (Border); + + -- ANCHOR(`box()',`Box') + procedure Box + (Win : in Window := Standard_Window; + Vertical_Symbol : in Attributed_Character := Default_Character; + Horizontal_Symbol : in Attributed_Character := Default_Character); + -- AKA + pragma Inline (Box); + + -- ANCHOR(`whline()',`Horizontal_Line') + procedure Horizontal_Line + (Win : in Window := Standard_Window; + Line_Size : in Natural; + Line_Symbol : in Attributed_Character := Default_Character); + -- AKA + pragma Inline (Horizontal_Line); + + -- ANCHOR(`wvline()',`Vertical_Line') + procedure Vertical_Line + (Win : in Window := Standard_Window; + Line_Size : in Natural; + Line_Symbol : in Attributed_Character := Default_Character); + -- AKA + pragma Inline (Vertical_Line); + + -- MANPAGE(`curs_getch.3x') + + -- ANCHOR(`wgetch()',`Get_Keystroke') + function Get_Keystroke (Win : Window := Standard_Window) + return Real_Key_Code; + -- AKA + -- Get a character from the keyboard and echo it - if enabled - to the + -- window. + -- If for any reason (i.e. a timeout) we couldn't get a character the + -- returned keycode is Key_None. + pragma Inline (Get_Keystroke); + + -- ANCHOR(`ungetch()',`Undo_Keystroke') + procedure Undo_Keystroke (Key : in Real_Key_Code); + -- AKA + pragma Inline (Undo_Keystroke); + + -- ANCHOR(`has_key()',`Has_Key') + function Has_Key (Key : Special_Key_Code) return Boolean; + -- AKA + pragma Inline (Has_Key); + + -- | + -- | Some helper functions + -- | + function Is_Function_Key (Key : Special_Key_Code) return Boolean; + -- Return True if the Key is a function key (i.e. one of F0 .. F63) + pragma Inline (Is_Function_Key); + + subtype Function_Key_Number is Integer range 0 .. 63; + -- (n)curses allows for 64 function keys. + + function Function_Key (Key : Real_Key_Code) return Function_Key_Number; + -- Return the number of the function key. If the code is not a + -- function key, a CONSTRAINT_ERROR will be raised. + pragma Inline (Function_Key); + + function Function_Key_Code (Key : Function_Key_Number) return Real_Key_Code; + -- Return the key code for a given function-key number. + pragma Inline (Function_Key_Code); + + -- MANPAGE(`curs_attr.3x') + + -- ANCHOR(`wattron()',`Switch_Character_Attribute') + procedure Switch_Character_Attribute + (Win : in Window := Standard_Window; + Attr : in Character_Attribute_Set := Normal_Video; + On : in Boolean := True); -- if False we switch Off. + -- AKA + -- ALIAS(`wattroff()') + + -- ANCHOR(`wattrset()',`Set_Character_Attributes') + procedure Set_Character_Attributes + (Win : in Window := Standard_Window; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Character_Attributes); + + -- ANCHOR(`wattr_get()',`Get_Character_Attributes') + function Get_Character_Attribute + (Win : in Window := Standard_Window) return Character_Attribute_Set; + -- AKA + + -- ANCHOR(`wattr_get()',`Get_Character_Attribute') + function Get_Character_Attribute + (Win : in Window := Standard_Window) return Color_Pair; + -- AKA + pragma Inline (Get_Character_Attribute); + + -- ANCHOR(`wcolor_set()',`Set_Color') + procedure Set_Color (Win : in Window := Standard_Window; + Pair : in Color_Pair); + -- AKA + pragma Inline (Set_Color); + + -- ANCHOR(`wchgat()',`Change_Attributes') + procedure Change_Attributes + (Win : in Window := Standard_Window; + Count : in Integer := -1; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + + -- ANCHOR(`mvwchgat()',`Change_Attributes') + procedure Change_Attributes + (Win : in Window := Standard_Window; + Line : in Line_Position := Line_Position'First; + Column : in Column_Position := Column_Position'First; + Count : in Integer := -1; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Change_Attributes); + + -- MANPAGE(`curs_beep.3x') + + -- ANCHOR(`beep()',`Beep') + procedure Beep; + -- AKA + pragma Inline (Beep); + + -- ANCHOR(`flash()',`Flash_Screen') + procedure Flash_Screen; + -- AKA + pragma Inline (Flash_Screen); + + -- MANPAGE(`curs_inopts.3x') + + -- | Not implemented : typeahead + -- + -- ANCHOR(`cbreak()',`Set_Cbreak_Mode') + procedure Set_Cbreak_Mode (SwitchOn : in Boolean := True); + -- AKA + -- ALIAS(`nocbreak()') + pragma Inline (Set_Cbreak_Mode); + + -- ANCHOR(`raw()',`Set_Raw_Mode') + procedure Set_Raw_Mode (SwitchOn : in Boolean := True); + -- AKA + -- ALIAS(`noraw()') + pragma Inline (Set_Raw_Mode); + + -- ANCHOR(`echo()',`Set_Echo_Mode') + procedure Set_Echo_Mode (SwitchOn : in Boolean := True); + -- AKA + -- ALIAS(`noecho()') + pragma Inline (Set_Echo_Mode); + + -- ANCHOR(`meta()',`Set_Meta_Mode') + procedure Set_Meta_Mode (Win : in Window := Standard_Window; + SwitchOn : in Boolean := True); + -- AKA + pragma Inline (Set_Meta_Mode); + + -- ANCHOR(`keypad()',`Set_KeyPad_Mode') + procedure Set_KeyPad_Mode (Win : in Window := Standard_Window; + SwitchOn : in Boolean := True); + -- AKA + pragma Inline (Set_KeyPad_Mode); + + type Half_Delay_Amount is range 1 .. 255; + + -- ANCHOR(`halfdelay()',`Half_Delay') + procedure Half_Delay (Amount : in Half_Delay_Amount); + -- AKA + pragma Inline (Half_Delay); + + -- ANCHOR(`intrflush()',`Set_Flush_On_Interrupt_Mode') + procedure Set_Flush_On_Interrupt_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := True); + -- AKA + pragma Inline (Set_Flush_On_Interrupt_Mode); + + -- ANCHOR(`qiflush()',`Set_Queue_Interrupt_Mode') + procedure Set_Queue_Interrupt_Mode + (Win : in Window := Standard_Window; + Flush : in Boolean := True); + -- AKA + -- ALIAS(`noqiflush()') + pragma Inline (Set_Queue_Interrupt_Mode); + + -- ANCHOR(`nodelay()',`Set_NoDelay_Mode') + procedure Set_NoDelay_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := False); + -- AKA + pragma Inline (Set_NoDelay_Mode); + + type Timeout_Mode is (Blocking, Non_Blocking, Delayed); + + -- ANCHOR(`wtimeout()',`Set_Timeout_Mode') + procedure Set_Timeout_Mode (Win : in Window := Standard_Window; + Mode : in Timeout_Mode; + Amount : in Natural); -- in Milliseconds + -- AKA + -- Instead of overloading the semantic of the sign of amount, we + -- introduce the Timeout_Mode parameter. This should improve + -- readability. For Blocking and Non_Blocking, the Amount is not + -- evaluated. + -- We don't inline this procedure. + + -- ANCHOR(`notimeout()',`Set_Escape_Time_Mode') + procedure Set_Escape_Timer_Mode + (Win : in Window := Standard_Window; + Timer_Off : in Boolean := False); + -- AKA + pragma Inline (Set_Escape_Timer_Mode); + + -- MANPAGE(`curs_outopts.3x') + + -- ANCHOR(`nl()',`Set_NL_Mode') + procedure Set_NL_Mode (SwitchOn : in Boolean := True); + -- AKA + -- ALIAS(`nonl()') + pragma Inline (Set_NL_Mode); + + -- ANCHOR(`clearok()',`Clear_On_Next_Update') + procedure Clear_On_Next_Update + (Win : in Window := Standard_Window; + Do_Clear : in Boolean := True); + -- AKA + pragma Inline (Clear_On_Next_Update); + + -- ANCHOR(`idlok()',`Use_Insert_Delete_Line') + procedure Use_Insert_Delete_Line + (Win : in Window := Standard_Window; + Do_Idl : in Boolean := True); + -- AKA + pragma Inline (Use_Insert_Delete_Line); + + -- ANCHOR(`idcok()',`Use_Insert_Delete_Character') + procedure Use_Insert_Delete_Character + (Win : in Window := Standard_Window; + Do_Idc : in Boolean := True); + -- AKA + pragma Inline (Use_Insert_Delete_Character); + + -- ANCHOR(`leaveok()',`Leave_Cursor_After_Update') + procedure Leave_Cursor_After_Update + (Win : in Window := Standard_Window; + Do_Leave : in Boolean := True); + -- AKA + pragma Inline (Leave_Cursor_After_Update); + + -- ANCHOR(`immedok()',`Immediate_Update_Mode') + procedure Immediate_Update_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := False); + -- AKA + pragma Inline (Immediate_Update_Mode); + + -- ANCHOR(`scrollok()',`Allow_Scrolling') + procedure Allow_Scrolling + (Win : in Window := Standard_Window; + Mode : in Boolean := False); + -- AKA + pragma Inline (Allow_Scrolling); + + function Scrolling_Allowed (Win : Window := Standard_Window) return Boolean; + -- There is no such function in the C interface. + pragma Inline (Scrolling_Allowed); + + -- ANCHOR(`wsetscrreg()',`Set_Scroll_Region') + procedure Set_Scroll_Region + (Win : in Window := Standard_Window; + Top_Line : in Line_Position; + Bottom_Line : in Line_Position); + -- AKA + pragma Inline (Set_Scroll_Region); + + -- MANPAGE(`curs_refresh.3x') + + -- ANCHOR(`doupdate()',`Update_Screen') + procedure Update_Screen; + -- AKA + pragma Inline (Update_Screen); + + -- ANCHOR(`wrefresh()',`Refresh') + procedure Refresh (Win : in Window := Standard_Window); + -- AKA + -- There is an overloaded Refresh for Pads. + -- The Inline pragma appears there + + -- ANCHOR(`wnoutrefresh()',`Refresh_Without_Update') + procedure Refresh_Without_Update + (Win : in Window := Standard_Window); + -- AKA + -- There is an overloaded Refresh_Without_Update for Pads. + -- The Inline pragma appears there + + -- ANCHOR(`redrawwin()',`Redraw') + procedure Redraw (Win : in Window := Standard_Window); + -- AKA + + -- ANCHOR(`wredrawln()',`Redraw') + procedure Redraw (Win : in Window := Standard_Window; + Begin_Line : in Line_Position; + Line_Count : in Positive); + -- AKA + pragma Inline (Redraw); + + -- MANPAGE(`curs_clear.3x') + + -- ANCHOR(`werase()',`Erase') + procedure Erase (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Erase); + + -- ANCHOR(`wclear()',`Clear') + procedure Clear + (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Clear); + + -- ANCHOR(`wclrtobot()',`Clear_To_End_Of_Screen') + procedure Clear_To_End_Of_Screen + (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Clear_To_End_Of_Screen); + + -- ANCHOR(`wclrtoeol()',`Clear_To_End_Of_Line') + procedure Clear_To_End_Of_Line + (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Clear_To_End_Of_Line); + + -- MANPAGE(`curs_bkgd.3x') + + -- ANCHOR(`wbkgdset()',`Set_Background') + procedure Set_Background + (Win : in Window := Standard_Window; + Ch : in Attributed_Character); + -- AKA + pragma Inline (Set_Background); + + -- ANCHOR(`wbkgd()',`Change_Background') + procedure Change_Background + (Win : in Window := Standard_Window; + Ch : in Attributed_Character); + -- AKA + pragma Inline (Change_Background); + + -- ANCHOR(`wbkgdget()',`Get_Background') + function Get_Background (Win : Window := Standard_Window) + return Attributed_Character; + -- AKA + pragma Inline (Get_Background); + + -- MANPAGE(`curs_touch.3x') + + -- ANCHOR(`untouchwin()',`Untouch') + procedure Untouch (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Untouch); + + -- ANCHOR(`touchwin()',`Touch') + procedure Touch (Win : in Window := Standard_Window); + -- AKA + + -- ANCHOR(`touchline()',`Touch') + procedure Touch (Win : in Window := Standard_Window; + Start : in Line_Position; + Count : in Positive); + -- AKA + pragma Inline (Touch); + + -- ANCHOR(`wtouchln()',`Change_Line_Status') + procedure Change_Lines_Status (Win : in Window := Standard_Window; + Start : in Line_Position; + Count : in Positive; + State : in Boolean); + -- AKA + pragma Inline (Change_Lines_Status); + + -- ANCHOR(`is_linetouched()',`Is_Touched') + function Is_Touched (Win : Window := Standard_Window; + Line : Line_Position) return Boolean; + -- AKA + + -- ANCHOR(`is_wintouched()',`Is_Touched') + function Is_Touched (Win : Window := Standard_Window) return Boolean; + -- AKA + pragma Inline (Is_Touched); + + -- MANPAGE(`curs_overlay.3x') + + -- ANCHOR(`copywin()',`Copy') + procedure Copy + (Source_Window : in Window; + Destination_Window : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position; + Non_Destructive_Mode : in Boolean := True); + -- AKA + pragma Inline (Copy); + + -- ANCHOR(`overwrite()',`Overwrite') + procedure Overwrite (Source_Window : in Window; + Destination_Window : in Window); + -- AKA + pragma Inline (Overwrite); + + -- ANCHOR(`overlay()',`Overlay') + procedure Overlay (Source_Window : in Window; + Destination_Window : in Window); + -- AKA + pragma Inline (Overlay); + + -- MANPAGE(`curs_deleteln.3x') + + -- ANCHOR(`winsdelln()',`Insert_Delete_Lines') + procedure Insert_Delete_Lines + (Win : in Window := Standard_Window; + Lines : in Integer := 1); -- default is to insert one line above + -- AKA + pragma Inline (Insert_Delete_Lines); + + -- ANCHOR(`wdeleteln()',`Delete_Line') + procedure Delete_Line (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Delete_Line); + + -- ANCHOR(`winsertln()',`Insert_Line') + procedure Insert_Line (Win : in Window := Standard_Window); + -- AKA + pragma Inline (Insert_Line); + + -- MANPAGE(`curs_getyx.3x') + + -- ANCHOR(`getmaxyx()',`Get_Size') + procedure Get_Size + (Win : in Window := Standard_Window; + Number_Of_Lines : out Line_Count; + Number_Of_Columns : out Column_Count); + -- AKA + pragma Inline (Get_Size); + + -- ANCHOR(`getbegyx()',`Get_Window_Position') + procedure Get_Window_Position + (Win : in Window := Standard_Window; + Top_Left_Line : out Line_Position; + Top_Left_Column : out Column_Position); + -- AKA + pragma Inline (Get_Window_Position); + + -- ANCHOR(`getyx()',`Get_Cursor_Position') + procedure Get_Cursor_Position + (Win : in Window := Standard_Window; + Line : out Line_Position; + Column : out Column_Position); + -- AKA + pragma Inline (Get_Cursor_Position); + + -- ANCHOR(`getparyx()',`Get_Origin_Relative_To_Parent') + procedure Get_Origin_Relative_To_Parent + (Win : in Window; + Top_Left_Line : out Line_Position; + Top_Left_Column : out Column_Position; + Is_Not_A_Subwindow : out Boolean); + -- AKA + -- Instead of placing -1 in the coordinates as return, we use a boolean + -- to return the info that the window has no parent. + pragma Inline (Get_Origin_Relative_To_Parent); + + -- MANPAGE(`curs_pad.3x') + + -- ANCHOR(`newpad()',`New_Pad') + function New_Pad (Lines : Line_Count; + Columns : Column_Count) return Window; + -- AKA + pragma Inline (New_Pad); + + -- ANCHOR(`subpad()',`Sub_Pad') + function Sub_Pad + (Pad : Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window; + -- AKA + pragma Inline (Sub_Pad); + + -- ANCHOR(`prefresh()',`Refresh') + procedure Refresh + (Pad : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position); + -- AKA + pragma Inline (Refresh); + + -- ANCHOR(`pnoutrefresh()',`Refresh_Without_Update') + procedure Refresh_Without_Update + (Pad : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position); + -- AKA + pragma Inline (Refresh_Without_Update); + + -- ANCHOR(`pechochar()',`Add_Character_To_Pad_And_Echo_It') + procedure Add_Character_To_Pad_And_Echo_It + (Pad : in Window; + Ch : in Attributed_Character); + -- AKA + + procedure Add_Character_To_Pad_And_Echo_It + (Pad : in Window; + Ch : in Character); + pragma Inline (Add_Character_To_Pad_And_Echo_It); + + -- MANPAGE(`curs_scroll.3x') + + -- ANCHOR(`wscrl()',`Scroll') + procedure Scroll (Win : in Window := Standard_Window; + Amount : in Integer := 1); + -- AKA + pragma Inline (Scroll); + + -- MANPAGE(`curs_delch.3x') + + -- ANCHOR(`wdelch()',`Delete_Character') + procedure Delete_Character (Win : in Window := Standard_Window); + -- AKA + + -- ANCHOR(`mvwdelch()',`Delete_Character') + procedure Delete_Character + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position); + -- AKA + pragma Inline (Delete_Character); + + -- MANPAGE(`curs_inch.3x') + + -- ANCHOR(`winch()',`Peek') + function Peek (Win : Window := Standard_Window) + return Attributed_Character; + -- AKA + + -- ANCHOR(`mvwinch()',`Peek') + function Peek + (Win : Window := Standard_Window; + Line : Line_Position; + Column : Column_Position) return Attributed_Character; + -- AKA + -- More Peek's follow, pragma Inline appears later. + + -- MANPAGE(`curs_winch.3x') + + -- ANCHOR(`winsch()',`Insert') + procedure Insert (Win : in Window := Standard_Window; + Ch : in Attributed_Character); + -- AKA + + -- ANCHOR(`mvwinsch()',`Insert') + procedure Insert (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Attributed_Character); + -- AKA + + -- MANPAGE(`curs_winch.3x') + + -- ANCHOR(`winsnstr()',`Insert') + procedure Insert (Win : in Window := Standard_Window; + Str : in String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`winsstr()') + + -- ANCHOR(`mvwinsnstr()',`Insert') + procedure Insert (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`mvwinsstr()') + pragma Inline (Insert); + + -- MANPAGE(`curs_instr.3x') + + -- ANCHOR(`winnstr()',`Peek') + procedure Peek (Win : in Window := Standard_Window; + Str : out String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`winstr()') + + -- ANCHOR(`mvwinnstr()',`Peek') + procedure Peek (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`mvwinstr()') + + -- MANPAGE(`curs_inchstr.3x') + + -- ANCHOR(`winchnstr()',`Peek') + procedure Peek (Win : in Window := Standard_Window; + Str : out Attributed_String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`winchstr()') + + -- ANCHOR(`mvwinchnstr()',`Peek') + procedure Peek (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out Attributed_String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`mvwinchstr()') + -- We don't inline the Peek procedures + + -- MANPAGE(`curs_getstr.3x') + + -- ANCHOR(`wgetnstr()',`Get') + procedure Get (Win : in Window := Standard_Window; + Str : out String; + Len : in Integer := -1); + -- AKA + -- ALIAS(`wgetstr()') + + procedure Get (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out String; + Len : in Integer := -1); + -- AKA + -- not specified in ncurses, should be: mvwgetnstr() + -- and mvwgetstr() (which exists) + -- Get is not inlined + + -- MANPAGE(`curs_slk.3x') + + type Soft_Label_Key_Format is (Three_Two_Three, + Four_Four, + PC_Style, -- ncurses specific + PC_Style_With_Index); -- " + type Label_Number is new Positive range 1 .. 12; + type Label_Justification is (Left, Centered, Right); + + -- ANCHOR(`slk_init()',`Init_Soft_Label_Keys') + procedure Init_Soft_Label_Keys + (Format : in Soft_Label_Key_Format := Three_Two_Three); + -- AKA + pragma Inline (Init_Soft_Label_Keys); + + -- ANCHOR(`slk_set()',`Set_Soft_Label_Key') + procedure Set_Soft_Label_Key (Label : in Label_Number; + Text : in String; + Fmt : in Label_Justification := Left); + -- AKA + -- We don't inline this procedure + + -- ANCHOR(`slk_refresh()',`Refresh_Soft_Label_Key') + procedure Refresh_Soft_Label_Keys; + -- AKA + pragma Inline (Refresh_Soft_Label_Keys); + + -- ANCHOR(`slk_noutrefresh()',`Refresh_Soft_Label_Keys_Without_Update') + procedure Refresh_Soft_Label_Keys_Without_Update; + -- AKA + pragma Inline (Refresh_Soft_Label_Keys_Without_Update); + + -- ANCHOR(`slk_label()',`Get_Soft_Label_Key') + procedure Get_Soft_Label_Key (Label : in Label_Number; + Text : out String); + -- AKA + + -- ANCHOR(`slk_label()',`Get_Soft_Label_Key') + function Get_Soft_Label_Key (Label : in Label_Number) return String; + -- AKA + -- Same as function + pragma Inline (Get_Soft_Label_Key); + + -- ANCHOR(`slk_clear()',`Clear_Soft_Label_Keys') + procedure Clear_Soft_Label_Keys; + -- AKA + pragma Inline (Clear_Soft_Label_Keys); + + -- ANCHOR(`slk_restore()',`Restore_Soft_Label_Keys') + procedure Restore_Soft_Label_Keys; + -- AKA + pragma Inline (Restore_Soft_Label_Keys); + + -- ANCHOR(`slk_touch()',`Touch_Soft_Label_Keys') + procedure Touch_Soft_Label_Keys; + -- AKA + pragma Inline (Touch_Soft_Label_Keys); + + -- ANCHOR(`slk_attron()',`Switch_Soft_Label_Key_Attributes') + procedure Switch_Soft_Label_Key_Attributes + (Attr : in Character_Attribute_Set; + On : in Boolean := True); + -- AKA + -- ALIAS(`slk_attroff()') + pragma Inline (Switch_Soft_Label_Key_Attributes); + + -- ANCHOR(`slk_attrset()',`Set_Soft_Label_Key_Attributes') + procedure Set_Soft_Label_Key_Attributes + (Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First); + -- AKA + pragma Inline (Set_Soft_Label_Key_Attributes); + + -- ANCHOR(`slk_attr()',`Get_Soft_Label_Key_Attributes') + function Get_Soft_Label_Key_Attributes return Character_Attribute_Set; + -- AKA + + -- ANCHOR(`slk_attr()',`Get_Soft_Label_Key_Attributes') + function Get_Soft_Label_Key_Attributes return Color_Pair; + -- AKA + pragma Inline (Get_Soft_Label_Key_Attributes); + + -- ANCHOR(`slk_color()',`Set_Soft_Label_Key_Color') + procedure Set_Soft_Label_Key_Color (Pair : in Color_Pair); + -- AKA + pragma Inline (Set_Soft_Label_Key_Color); + + -- MANPAGE(`keyok.3x') + + -- ANCHOR(`keyok()',`Enable_Key') + procedure Enable_Key (Key : in Special_Key_Code; + Enable : in Boolean := True); + -- AKA + pragma Inline (Enable_Key); + + -- MANPAGE(`define_key.3x') + + -- ANCHOR(`define_key()',`Define_Key') + procedure Define_Key (Definition : in String; + Key : in Special_Key_Code); + -- AKA + pragma Inline (Define_Key); + + -- MANPAGE(`curs_util.3x') + + -- | Not implemented : filter, use_env, putwin, getwin + -- + -- ANCHOR(`keyname()',`Key_Name') + procedure Key_Name (Key : in Real_Key_Code; + Name : out String); + -- AKA + -- The external name for a real keystroke. + + -- ANCHOR(`keyname()',`Key_Name') + function Key_Name (Key : in Real_Key_Code) return String; + -- AKA + -- Same as function + -- We don't inline this routine + + -- ANCHOR(`unctrl()',`Un_Control') + procedure Un_Control (Ch : in Attributed_Character; + Str : out String); + -- AKA + + -- ANCHOR(`unctrl()',`Un_Control') + function Un_Control (Ch : in Attributed_Character) return String; + -- AKA + -- Same as function + pragma Inline (Un_Control); + + -- ANCHOR(`delay_output()',`Delay_Output') + procedure Delay_Output (Msecs : in Natural); + -- AKA + pragma Inline (Delay_Output); + + -- ANCHOR(`flushinp()',`Flush_Input') + procedure Flush_Input; + -- AKA + pragma Inline (Flush_Input); + + -- MANPAGE(`curs_termattrs.3x') + + -- ANCHOR(`baudrate()',`Baudrate') + function Baudrate return Natural; + -- AKA + pragma Inline (Baudrate); + + -- ANCHOR(`erasechar()',`Erase_Character') + function Erase_Character return Character; + -- AKA + pragma Inline (Erase_Character); + + -- ANCHOR(`killchar()',`Kill_Character') + function Kill_Character return Character; + -- AKA + pragma Inline (Kill_Character); + + -- ANCHOR(`has_ic()',`Has_Insert_Character') + function Has_Insert_Character return Boolean; + -- AKA + pragma Inline (Has_Insert_Character); + + -- ANCHOR(`has_il()',`Has_Insert_Line') + function Has_Insert_Line return Boolean; + -- AKA + pragma Inline (Has_Insert_Line); + + -- ANCHOR(`termattrs()',`Supported_Attributes') + function Supported_Attributes return Character_Attribute_Set; + -- AKA + pragma Inline (Supported_Attributes); + + -- ANCHOR(`longname()',`Long_Name') + procedure Long_Name (Name : out String); + -- AKA + + -- ANCHOR(`longname()',`Long_Name') + function Long_Name return String; + -- AKA + -- Same as function + pragma Inline (Long_Name); + + -- ANCHOR(`termname()',`Terminal_Name') + procedure Terminal_Name (Name : out String); + -- AKA + + -- ANCHOR(`termname()',`Terminal_Name') + function Terminal_Name return String; + -- AKA + -- Same as function + pragma Inline (Terminal_Name); + + -- MANPAGE(`curs_color.3x') + + -- ANCHOR(`start_color()',`Start_Color') + procedure Start_Color; + -- AKA + pragma Import (C, Start_Color, "start_color"); + + -- ANCHOR(`init_pair()',`Init_Pair') + procedure Init_Pair (Pair : in Redefinable_Color_Pair; + Fore : in Color_Number; + Back : in Color_Number); + -- AKA + pragma Inline (Init_Pair); + + -- ANCHOR(`pair_content()',`Pair_Content') + procedure Pair_Content (Pair : in Color_Pair; + Fore : out Color_Number; + Back : out Color_Number); + -- AKA + pragma Inline (Pair_Content); + + -- ANCHOR(`has_colors()',`Has_Colors') + function Has_Colors return Boolean; + -- AKA + pragma Inline (Has_Colors); + + -- ANCHOR(`init_color()',`Init_Color') + procedure Init_Color (Color : in Color_Number; + Red : in RGB_Value; + Green : in RGB_Value; + Blue : in RGB_Value); + -- AKA + pragma Inline (Init_Color); + + -- ANCHOR(`can_change_color()',`Can_Change_Color') + function Can_Change_Color return Boolean; + -- AKA + pragma Inline (Can_Change_Color); + + -- ANCHOR(`color_content()',`Color_Content') + procedure Color_Content (Color : in Color_Number; + Red : out RGB_Value; + Green : out RGB_Value; + Blue : out RGB_Value); + -- AKA + pragma Inline (Color_Content); + + -- MANPAGE(`curs_kernel.3x') + + -- | Not implemented: getsyx, setsyx + -- + type Curses_Mode is (Curses, Shell); + + -- ANCHOR(`def_prog_mode()',`Save_Curses_Mode') + procedure Save_Curses_Mode (Mode : in Curses_Mode); + -- AKA + -- ALIAS(`def_shell_mode()') + pragma Inline (Save_Curses_Mode); + + -- ANCHOR(`reset_prog_mode()',`Reset_Curses_Mode') + procedure Reset_Curses_Mode (Mode : in Curses_Mode); + -- AKA + -- ALIAS(`reset_shell_mode()') + pragma Inline (Reset_Curses_Mode); + + -- ANCHOR(`savetty()',`Save_Terminal_State') + procedure Save_Terminal_State; + -- AKA + pragma Inline (Save_Terminal_State); + + -- ANCHOR(`resetty();',`Reset_Terminal_State') + procedure Reset_Terminal_State; + -- AKA + pragma Inline (Reset_Terminal_State); + + type Stdscr_Init_Proc is access + function (Win : Window; + Columns : Column_Count) return Integer; + pragma Convention (C, Stdscr_Init_Proc); + -- N.B.: the return value is actually ignored, but it seems to be + -- a good practice to return 0 if you think all went fine + -- and -1 otherwise. + + -- ANCHOR(`ripoffline()',`Rip_Off_Lines') + procedure Rip_Off_Lines (Lines : in Integer; + Proc : in Stdscr_Init_Proc); + -- AKA + -- N.B.: to be more precise, this uses a ncurses specific enhancement of + -- ripoffline(), in which the Lines argument absolute value is the + -- number of lines to be ripped of. The official ripoffline() only + -- uses the sign of Lines to rip of a single line from bottom or top. + pragma Inline (Rip_Off_Lines); + + type Cursor_Visibility is (Invisible, Normal, Very_Visible); + + -- ANCHOR(`curs_set()',`Set_Cursor_Visibility') + procedure Set_Cursor_Visibility (Visibility : in out Cursor_Visibility); + -- AKA + pragma Inline (Set_Cursor_Visibility); + + -- ANCHOR(`napms()',`Nap_Milli_Seconds') + procedure Nap_Milli_Seconds (Ms : in Natural); + -- AKA + pragma Inline (Nap_Milli_Seconds); + + -- |===================================================================== + -- | Some useful helpers. + -- |===================================================================== + type Transform_Direction is (From_Screen, To_Screen); + procedure Transform_Coordinates + (W : in Window := Standard_Window; + Line : in out Line_Position; + Column : in out Column_Position; + Dir : in Transform_Direction := From_Screen); + -- This procedure transforms screen coordinates into coordinates relative + -- to the window and vice versa, depending on the Dir parameter. + -- Screen coordinates are the position informations on the physical device. + -- An Curses_Exception will be raised if Line and Column are not in the + -- Window or if you pass the Null_Window as argument. + -- We don't inline this procedure + +private + type Window is new System.Storage_Elements.Integer_Address; + Null_Window : constant Window := 0; + + -- The next constants are generated and may be different on your + -- architecture. + -- +include(`Window_Offsets')dnl + Curses_Bool_False : constant Curses_Bool := 0; + +end Terminal_Interface.Curses; diff --git a/ncurses-5.2/Ada95/samples/Makefile.in b/ncurses-5.2/Ada95/samples/Makefile.in new file mode 100644 index 0000000..9e9f0c7 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/Makefile.in @@ -0,0 +1,137 @@ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Juergen Pfeifer 1996 +# +# Version Control +# $Revision$ +# +.SUFFIXES: + +SHELL = /bin/sh +THIS = Makefile + +x = @PROG_EXT@ + +srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +AWK = @AWK@ +LN_S = @LN_S@ + +CC = @CC@ +CFLAGS = @CFLAGS@ + +CPPFLAGS = @ACPPFLAGS@ \ + -DHAVE_CONFIG_H -I$(srcdir) + +CCFLAGS = $(CPPFLAGS) $(CFLAGS) + +CFLAGS_NORMAL = $(CCFLAGS) +CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE +CFLAGS_PROFILE = $(CCFLAGS) -pg +CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@ + +CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@) + +LINK = $(CC) +LDFLAGS = @LDFLAGS@ @LD_MODEL@ @LIBS@ + +RANLIB = @RANLIB@ +################################################################################ +ada_srcdir=../src + +LD_FLAGS = @LD_MODEL@ $(LOCAL_LIBS) @LDFLAGS@ @LIBS@ @LOCAL_LDFLAGS2@ $(LDFLAGS) + +ADA = @cf_ada_compiler@ +ADAFLAGS = @ADAFLAGS@ -I$(srcdir) + +ADAMAKE = @cf_ada_make@ +ADAMAKEFLAGS = -a -A$(srcdir) -A$(ada_srcdir) -A$(srcdir)/$(ada_srcdir) + +ALIB = @cf_ada_package@ +ABASE = $(ALIB)-curses + +CARGS =-cargs $(ADAFLAGS) +LARGS =-largs -L../../lib $(LD_FLAGS) -lAdaCurses -lncurses@LIB_SUFFIX@ + +PROGS = tour rain + +TOUR_OBJS = tour.o sample.o sample-curses_demo.o sample-explanation.o \ + sample-form_demo.o sample-function_key_setting.o \ + sample-header_handler.o sample-helpers.o \ + sample-keyboard_handler.o sample-manifest.o sample-menu_demo.o \ + sample-menu_demo-aux.o sample-text_io_demo.o \ + sample-curses_demo-attributes.o sample-curses_demo-mouse.o \ + sample-form_demo-aux.o sample-my_field_type.o + +RAIN_OBJS = rain.o status.o + +all :: tour$x rain$x + @ + +sources : + @ + +libs \ +install \ +install.libs :: + @ + +uninstall \ +uninstall.libs :: + @ + +tour$x : explain.msg + $(ADAMAKE) $(ADAMAKEFLAGS) tour $(CARGS) $(LARGS) + +explain.msg: $(srcdir)/explain.txt + cp $(srcdir)/explain.txt $@ + +rain$x : + $(ADAMAKE) $(ADAMAKEFLAGS) rain $(CARGS) $(LARGS) + +mostlyclean: + @ + +clean :: mostlyclean + rm -f *.o *.ali b_t*.* *.s $(PROGS) a.out core b_*_test.c *.xr[bs] explain.msg + +distclean :: clean + rm -f Makefile + +realclean :: distclean + @ + + diff --git a/ncurses-5.2/Ada95/samples/README b/ncurses-5.2/Ada95/samples/README new file mode 100644 index 0000000..6ea8a18 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/README @@ -0,0 +1,6 @@ +The intention of the demo at this point in time is not to demonstrate all +the features of (n)curses and it's subsystems, but to give some sample +sources how to use the binding at all. + +Ideally in the future we can combine both goals. + diff --git a/ncurses-5.2/Ada95/samples/explain.txt b/ncurses-5.2/Ada95/samples/explain.txt new file mode 100644 index 0000000..570f617 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/explain.txt @@ -0,0 +1,186 @@ +#VERSION +This is Version 00.90.00 of the demo package. +#MENUKEYS +In a menu you can use the following Keys in the whole application: + + - CTRL-X eXit the menu + - CTRL-N Go to next item + - CTRL-P Go to previous item + - CTRL-U Scroll up one line + - CTRL-D Scroll down one line + - CTRL-F Scroll down one page + - PAGE DOWN Scroll down one page + - PAGE UP Scroll back one page + - CTRL-B Scroll back one page + - CTRL-Y Clear pattern + - CTRL-H Delete last character from pattern + - Backspace Delete last character from pattern + - CTRL-A Next pattern match + - CTRL-E Previous pattern match + - CTRL-T Toggle item in a multi-selection menu + - CR or LF Select an item + - HOME Key Go to the first item + - F3 Quit the menu + - Cursor Down Down one item + - Cursor Up Up one item + - Cursor Left Left one item + - Cursor Right Right one item + - END Key Go to last item +#FORMKEYS + - CTRL-X eXit the form + - CTRL-F Go forward to the next field + - CTRL-B Go backward to the previous field + - CTRL-L Go to the field left of the current one + - CTRL-R Go to the field right of the current one + - CTRL-U Go to the field above the current one + - CTRL-D Go to the field below the current one + + - CTRL-W Go to the next word in the field + - CTRL-T Go to the previous word in the field + + - CTRL-A Go to the beginning of the field + - CTRL-E Go to the end of the field + + - CTRL-I Insert a blank character at the current position + - CTRL-O Insert a line + - CTRL-V Delete a character + - CTRL-H Delete previous character + - CTRL-Y Delete a line + - CTRL-G Delete a word + - CTRL-K Clear to end of field + + - CTRL-N Next choice in a choice field (Enumerations etc.) + - CTRL-P Previous choice in a choice field. +#HELP +#HELPKEYS +You may scroll with the Cursor Up/Down Keys. +You may leave the help with the Function Key labelled 'Quit'. +#INHELP +You are already in the help system. +You may leave the help with the Function Key labelled 'Quit'. +#MAIN +This is the main menu of the sample program for the ncurses Ada95 +binding. The main intention of the demo is not to demonstate or +test all the features of ncurses and it's subsystems, but to provide +to you some sample code how to use the binding with Ada95. + +You may select this options: + + * Look at some ncurses core functions + * Look at some features of the menu subsystem + * Look at some features of the form subsystem + * Look at the output of the Ada.Text_IO like functions + for ncurses. + +#MAINPAD +You may press at any place in this demo CTRL-C. This will give you a command +window. You can just type in the Label-String of a function key, then this +key will be simulated. This should help you to run the application even if +you run it on a terminal with no or only a few function keys. With CTRL-N +and CTRL-P you may browse through the possible values in the command window. +#MENU00 +Here we give you a selection of various menu demonstrations. +#MENU-PAD00 +This menu itself is a demo for a single valued, 1-column menu with +descriptions for the items, a marker and a padding character between +the item name and the description. +#MENU01 +This is a demo of the some of the menu layout options. One of them +is the spacing functionality. Just press the Key labelled "Flip" to +flip between the non-spaced and a spaced version of the menu. Please +note that this functionality is unique for ncurses and is not found +in the SVr4 menu implementation. + +This is a menu that sometimes doesn't fit into it's window and +therefore it becomes a scroll menu. + +You can also see here very nicely the pattern matching functionality +of menus. Type for example a 'J' and you will be positioned to the +next item after the current starting with a 'J'. Any more characters +you type in make the pattern more specific. With CTRL-A and CTRL-Z +(for more details press the Key labelled "Keys") you can browse +through all the items matching the pattern. + +You may change the format of the menu. Just press one of the keys +labelled "4x1", "4x2" or "4x3" to get a menu with that many rows +and columns. + +With the Keys "O-Row" or "O-Col" (they occupy the same label and +switch on selection) you can change the major order scheme for +the menu. If "O-Col" is visible, the menu is currently major +ordered by rows, you can switch to major column order by pressing +the key. If "O-Row" is visible, it's just the reverse situation. +This Key is not visible in "4x1" layout mode, because in this case +the functionality makes no sense. + +With the Keys "Multi" or "Singl" (they occupy the same label and +switch on selection) you can change whether or not the menu allows +multiple or only single selection. + +With the Keys "+Desc" or "-Desc" (they occupy the same label and +switch on selection) you can change whether or not the descriptions +for each item should be displayed. Please not that this key is +not visible in the "4x3" layout mode, because in this case the +menu wouldn't fit on a typicall 80x24 screen. + +With the Keys "Disab" or "Enab" (they occupy the same label and +switch on selection) you can dis- or enable the selectability of +the month with 31 days. +#MENU-PAD01 +You may press "Flip" to see the effect of ncurses unique menu-spacing. +The Keys "4x1", "4x2" and "4x3" will change the format of the menu. +Please note that this is a scrolling menu. You may also play with the +pattern matching functionality or try to change the format of the menu. +For more details press the Key labelled "Help". +#FORM00 +This is a demo of the forms package. +#FORM-PAD00 +Please note that this demo is far from being complete. It really shows +only a small part of the functionality of the forms package. Let's hope +the next version will have a richer demo (You wan't to contribute ?). +#NOTIMPL +Sorry this functionality of the demo is not implemented at the moment. +Remember this is a freeware project, so I can use only my very rare +free time to continue coding. If you would like to contribute, you +are very welcome ! +#CURSES00 +This is a menu where you can select some different demos of the ncurses +functionality. +#CURSES-PAD00 +Please note that this demo is far from being complete. It really shows +only a small part of the functionality of the curses package. Let's hope +the next version will have a richer demo (You wan't to contribute ?). +#MOUSEKEYS +In this demo you may use this keys: + + - Key labelled "Help" to get a help + - Key labelled "Keys" is what you are reading now + - Key labelled "Quit" to leave the demo + +You may click the mouse buttons at any location at the screen and look +at the protocol window ! +#MOUSE00 +A rather simple use of a mouse as demo. It's there just to test the +code and to provide the sample source. + +It might be of interest, that the output into the protocol window is +done by the (n)curses Text_IO subpackages. Especially the output of +the button and state names is done by Ads's enumeration IO, which +allows you to print the names of enumeration literals. That's really +nice. +#MOUSE-PAD00 +This is a very simple demo of the mouse features of ncurses. It's there +just to test whether or not the generated code for the binding really +works on the different architectures (seems so). +#ATTRIBDEMO +Again this is a more than simple demo and just here to give you the +sourcecode. +#ATTRIBKEYS +You may press one of the three well known standard keys of this demo. +#ATTRIB-PAD00 +Again this is a more than simple demo and just here to give you the +sourcecode. Feel free to contribute more. +#TEXTIO +#TEXTIOKEYS +#TEXTIO-PAD00 +#END diff --git a/ncurses-5.2/Ada95/samples/rain.adb b/ncurses-5.2/Ada95/samples/rain.adb new file mode 100644 index 0000000..6d5fd63 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/rain.adb @@ -0,0 +1,161 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Rain -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Laurent Pautet 1997 (modified by J.Pfeifer) +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- -- +with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random; +with Status; use Status; +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +procedure Rain is + + Visibility : Cursor_Visibility; + + subtype X_Position is Line_Position; + subtype Y_Position is Column_Position; + + Xpos : array (1 .. 5) of X_Position; + Ypos : array (1 .. 5) of Y_Position; + + N : Integer; + + G : Generator; + + Max_X, X : X_Position; + Max_Y, Y : Y_Position; + + procedure Next (J : in out Integer); + procedure Cursor (X : X_Position; Y : Y_Position); + + procedure Next (J : in out Integer) is + begin + if J = 5 then + J := 1; + else + J := J + 1; + end if; + end Next; + + procedure Cursor (X : X_Position; Y : Y_Position) is + begin + Move_Cursor (Line => X, Column => Y); + end Cursor; + pragma Inline (Cursor); + +begin + + Init_Screen; + Set_NL_Mode; + Set_Echo_Mode (False); + + Visibility := Invisible; + Set_Cursor_Visibility (Visibility); + + Max_X := Lines - 5; + Max_Y := Columns - 5; + + for I in Xpos'Range loop + Xpos (I) := X_Position (Float (Max_X) * Random (G)) + 2; + Ypos (I) := Y_Position (Float (Max_Y) * Random (G)) + 2; + end loop; + + N := 1; + while Process.Continue loop + + X := X_Position (Float (Max_X) * Random (G)) + 2; + Y := Y_Position (Float (Max_Y) * Random (G)) + 2; + + Cursor (X, Y); + Add (Ch => '.'); + + Cursor (Xpos (N), Ypos (N)); + Add (Ch => 'o'); + + -- + Next (N); + Cursor (Xpos (N), Ypos (N)); + Add (Ch => 'O'); + + -- + Next (N); + Cursor (Xpos (N) - 1, Ypos (N)); + Add (Ch => '-'); + Cursor (Xpos (N), Ypos (N) - 1); + Add (Str => "|.|"); + Cursor (Xpos (N) + 1, Ypos (N)); + Add (Ch => '-'); + + -- + Next (N); + Cursor (Xpos (N) - 2, Ypos (N)); + Add (Ch => '-'); + Cursor (Xpos (N) - 1, Ypos (N) - 1); + Add (Str => "/\\"); + Cursor (Xpos (N), Ypos (N) - 2); + Add (Str => "| O |"); + Cursor (Xpos (N) + 1, Ypos (N) - 1); + Add (Str => "\\/"); + Cursor (Xpos (N) + 2, Ypos (N)); + Add (Ch => '-'); + + -- + Next (N); + Cursor (Xpos (N) - 2, Ypos (N)); + Add (Ch => ' '); + Cursor (Xpos (N) - 1, Ypos (N) - 1); + Add (Str => " "); + Cursor (Xpos (N), Ypos (N) - 2); + Add (Str => " "); + Cursor (Xpos (N) + 1, Ypos (N) - 1); + Add (Str => " "); + Cursor (Xpos (N) + 2, Ypos (N)); + Add (Ch => ' '); + + Xpos (N) := X; + Ypos (N) := Y; + + Refresh; + Nap_Milli_Seconds (50); + end loop; + + Visibility := Normal; + Set_Cursor_Visibility (Visibility); + End_Windows; + +end Rain; diff --git a/ncurses-5.2/Ada95/samples/rain.ads b/ncurses-5.2/Ada95/samples/rain.ads new file mode 100644 index 0000000..64b42a9 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/rain.ads @@ -0,0 +1,42 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Rain -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Laurent Pautet 1997 (modified by J.Pfeifer) +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- -- +procedure Rain; diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.adb b/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.adb new file mode 100644 index 0000000..ac0f54c --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.adb @@ -0,0 +1,122 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo.Attributes -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Curses_Demo.Attributes is + + procedure Demo + is + P : Panel := Create (Standard_Window); + K : Real_Key_Code; + begin + Set_Meta_Mode; + Set_KeyPad_Mode; + + Top (P); + + Push_Environment ("ATTRIBDEMO"); + Default_Labels; + Notepad ("ATTRIB-PAD00"); + + Set_Character_Attributes (Attr => (others => False)); + Add (Line => 1, Column => Columns / 2 - 10, + Str => "This is NORMAL"); + + Set_Character_Attributes (Attr => (Stand_Out => True, + others => False)); + Add (Line => 2, Column => Columns / 2 - 10, + Str => "This is Stand_Out"); + + Set_Character_Attributes (Attr => (Under_Line => True, + others => False)); + Add (Line => 3, Column => Columns / 2 - 10, + Str => "This is Under_Line"); + + Set_Character_Attributes (Attr => (Reverse_Video => True, + others => False)); + Add (Line => 4, Column => Columns / 2 - 10, + Str => "This is Reverse_Video"); + + Set_Character_Attributes (Attr => (Blink => True, + others => False)); + Add (Line => 5, Column => Columns / 2 - 10, + Str => "This is Blink"); + + Set_Character_Attributes (Attr => (Dim_Character => True, + others => False)); + Add (Line => 6, Column => Columns / 2 - 10, + Str => "This is Dim_Character"); + + Set_Character_Attributes (Attr => (Bold_Character => True, + others => False)); + Add (Line => 7, Column => Columns / 2 - 10, + Str => "This is Bold_Character"); + + Refresh_Without_Update; + Update_Panels; Update_Screen; + + loop + K := Get_Key; + if K in Special_Key_Code'Range then + case K is + when QUIT_CODE => exit; + when HELP_CODE => Explain_Context; + when EXPLAIN_CODE => Explain ("ATTRIBKEYS"); + when others => null; + end case; + end if; + end loop; + + Pop_Environment; + Clear; + Refresh_Without_Update; + Delete (P); + Update_Panels; Update_Screen; + + end Demo; + +end Sample.Curses_Demo.Attributes; diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.ads b/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.ads new file mode 100644 index 0000000..a9a0121 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo-attributes.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo.Attributes -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Curses_Demo.Attributes is + + procedure Demo; + +end Sample.Curses_Demo.Attributes; diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.adb b/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.adb new file mode 100644 index 0000000..3b20b69 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.adb @@ -0,0 +1,220 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo.Mouse -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Mouse; use Terminal_Interface.Curses.Mouse; +with Terminal_Interface.Curses.Text_IO; use Terminal_Interface.Curses.Text_IO; +with Terminal_Interface.Curses.Text_IO.Integer_IO; +with Terminal_Interface.Curses.Text_IO.Enumeration_IO; + +with Sample.Helpers; use Sample.Helpers; +with Sample.Manifest; use Sample.Manifest; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Curses_Demo.Mouse is + + package Int_IO is new + Terminal_Interface.Curses.Text_IO.Integer_IO (Integer); + use Int_IO; + + package Button_IO is new + Terminal_Interface.Curses.Text_IO.Enumeration_IO (Mouse_Button); + use Button_IO; + + package State_IO is new + Terminal_Interface.Curses.Text_IO.Enumeration_IO (Button_State); + use State_IO; + + procedure Demo is + + type Controls is array (1 .. 3) of Panel; + + Frame : Window; + Msg : Window; + Ctl : Controls; + Pan : Panel; + K : Real_Key_Code; + V : Cursor_Visibility := Invisible; + W : Window; + Note : Window; + Msg_L : constant Line_Count := 8; + Lins : Line_Position := Lines; + Cols : Column_Position; + Mask : Event_Mask; + procedure Show_Mouse_Event; + + procedure Show_Mouse_Event + is + Evt : constant Mouse_Event := Get_Mouse; + Y : Line_Position; + X : Column_Position; + Button : Mouse_Button; + State : Button_State; + W : Window; + begin + Get_Event (Evt, Y, X, Button, State); + Put (Msg, "Event at"); + Put (Msg, " X="); Put (Msg, Integer (X), 3); + Put (Msg, ", Y="); Put (Msg, Integer (Y), 3); + Put (Msg, ", Btn="); Put (Msg, Button, 10); + Put (Msg, ", Stat="); Put (Msg, State, 15); + for I in Ctl'Range loop + W := Get_Window (Ctl (I)); + if Enclosed_In_Window (W, Evt) then + Transform_Coordinates (W, Y, X, From_Screen); + Put (Msg, ",Box("); + Put (Msg, Integer (I), 1); Put (Msg, ","); + Put (Msg, Integer (Y), 1); Put (Msg, ","); + Put (Msg, Integer (X), 1); Put (Msg, ")"); + end if; + end loop; + New_Line (Msg); + Flush (Msg); + Update_Panels; Update_Screen; + end Show_Mouse_Event; + + begin + Push_Environment ("MOUSE00"); + Notepad ("MOUSE-PAD00"); + Default_Labels; + Set_Cursor_Visibility (V); + + Note := Notepad_Window; + if Note /= Null_Window then + Get_Window_Position (Note, Lins, Cols); + end if; + Frame := Create (Msg_L, Columns, Lins - Msg_L, 0); + if Has_Colors then + Set_Background (Win => Frame, + Ch => (Color => Default_Colors, + Attr => Normal_Video, + Ch => ' ')); + Set_Character_Attributes (Win => Frame, + Attr => Normal_Video, + Color => Default_Colors); + Erase (Frame); + end if; + Msg := Derived_Window (Frame, Msg_L - 2, Columns - 2, 1, 1); + Pan := Create (Frame); + + Set_Meta_Mode; + Set_KeyPad_Mode; + Mask := Start_Mouse; + + Box (Frame); + Window_Title (Frame, "Mouse Protocol"); + Refresh_Without_Update (Frame); + Allow_Scrolling (Msg, True); + + declare + Middle_Column : constant Integer := Integer (Columns) / 2; + Middle_Index : constant Natural := Ctl'First + (Ctl'Length / 2); + Width : constant Column_Count := 5; + Height : constant Line_Count := 3; + Half : constant Column_Count := Width / 2; + Space : constant Column_Count := 3; + Position : Integer; + W : Window; + begin + for I in Ctl'Range loop + Position := (Integer (I) - Integer (Middle_Index)) * + Integer (Half + Space + Width) + Middle_Column; + W := Create (Height, + Width, + 1, + Column_Position (Position)); + if Has_Colors then + Set_Background (Win => W, + Ch => (Color => Menu_Back_Color, + Attr => Normal_Video, + Ch => ' ')); + Set_Character_Attributes (Win => W, + Attr => Normal_Video, + Color => Menu_Fore_Color); + Erase (W); + end if; + Ctl (I) := Create (W); + Box (W); + Move_Cursor (W, 1, Half); + Put (W, Integer (I), 1); + Refresh_Without_Update (W); + end loop; + end; + + Update_Panels; Update_Screen; + + loop + K := Get_Key; + if K in Special_Key_Code'Range then + case K is + when QUIT_CODE => exit; + when HELP_CODE => Explain_Context; + when EXPLAIN_CODE => Explain ("MOUSEKEYS"); + when Key_Mouse => Show_Mouse_Event; + when others => null; + end case; + end if; + end loop; + + for I in Ctl'Range loop + W := Get_Window (Ctl (I)); + Clear (W); + Delete (Ctl (I)); + Delete (W); + end loop; + + Clear (Frame); + Delete (Pan); + Delete (Msg); + Delete (Frame); + + Set_Cursor_Visibility (V); + End_Mouse (Mask); + + Pop_Environment; + Update_Panels; Update_Screen; + + end Demo; + +end Sample.Curses_Demo.Mouse; + diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.ads b/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.ads new file mode 100644 index 0000000..603050a --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo-mouse.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo.Mouse -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Curses_Demo.Mouse is + + procedure Demo; + +end Sample.Curses_Demo.Mouse; diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo.adb b/ncurses-5.2/Ada95/samples/sample-curses_demo.adb new file mode 100644 index 0000000..02c751a --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo.adb @@ -0,0 +1,142 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Menus; use Terminal_Interface.Curses.Menus; +with Terminal_Interface.Curses.Mouse; use Terminal_Interface.Curses.Mouse; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Panels.User_Data; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Helpers; use Sample.Helpers; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; + +with Sample.Explanation; use Sample.Explanation; + +with Sample.Menu_Demo.Handler; +with Sample.Curses_Demo.Mouse; +with Sample.Curses_Demo.Attributes; + +package body Sample.Curses_Demo is + + type User_Data is new Integer; + type User_Data_Access is access all User_Data; + package PUD is new Panels.User_Data (User_Data, User_Data_Access); + -- We use above instantiation of the generic User_Data package to + -- demonstrate and test the use of the user data maechanism. + + procedure Demo + is + function My_Driver (M : Menu; + K : Key_Code; + Pan : Panel) return Boolean; + package Mh is new Sample.Menu_Demo.Handler (My_Driver); + + Itm : Item_Array_Access := new Item_Array' + (New_Item ("Attributes Demo"), + New_Item ("Mouse Demo"), + Null_Item); + M : Menu := New_Menu (Itm); + U1 : User_Data_Access := new User_Data'(4711); + U2 : User_Data_Access; + + function My_Driver (M : Menu; + K : Key_Code; + Pan : Panel) return Boolean + is + Idx : constant Positive := Get_Index (Current (M)); + Result : Boolean := False; + begin + PUD.Set_User_Data (Pan, U1); -- set some user data, just for fun + if K in User_Key_Code'Range then + if K = QUIT then + Result := True; + elsif K = SELECT_ITEM then + if Idx in Itm'Range then + Hide (Pan); + Update_Panels; + end if; + case Idx is + when 1 => Sample.Curses_Demo.Attributes.Demo; + when 2 => Sample.Curses_Demo.Mouse.Demo; + when others => Not_Implemented; + end case; + if Idx in Itm'Range then + Top (Pan); + Show (Pan); + Update_Panels; + Update_Screen; + end if; + end if; + end if; + PUD.Get_User_Data (Pan, U2); -- get the user data + pragma Assert (U1.all = U2.all and then U1 = U2); + return Result; + end My_Driver; + + begin + + if (1 + Item_Count (M)) /= Itm'Length then + raise Constraint_Error; + end if; + + if not Has_Mouse then + declare + O : Item_Option_Set; + begin + Get_Options (Itm (2), O); + O.Selectable := False; + Set_Options (Itm (2), O); + end; + end if; + + Push_Environment ("CURSES00"); + Notepad ("CURSES-PAD00"); + Default_Labels; + Refresh_Soft_Label_Keys_Without_Update; + + Mh.Drive_Me (M, " Demo "); + Pop_Environment; + + Delete (M); + Free (Itm, True); + end Demo; + +end Sample.Curses_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-curses_demo.ads b/ncurses-5.2/Ada95/samples/sample-curses_demo.ads new file mode 100644 index 0000000..9b791b6 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-curses_demo.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Curses_Demo -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Curses_Demo is + + procedure Demo; + +end Sample.Curses_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-explanation.adb b/ncurses-5.2/Ada95/samples/sample-explanation.adb new file mode 100644 index 0000000..f42652c --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-explanation.adb @@ -0,0 +1,408 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Explanation -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- Poor mans help system. This scans a sequential file for key lines and +-- then reads the lines up to the next key. Those lines are presented in +-- a window as help or explanation. +-- +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Unchecked_Deallocation; +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; + +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Manifest; use Sample.Manifest; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Helpers; use Sample.Helpers; + +package body Sample.Explanation is + + Help_Keys : constant String := "HELPKEYS"; + In_Help : constant String := "INHELP"; + + File_Name : String := "explain.msg"; + F : File_Type; + + type Help_Line; + type Help_Line_Access is access Help_Line; + pragma Controlled (Help_Line_Access); + type String_Access is access String; + pragma Controlled (String_Access); + + type Help_Line is + record + Prev, Next : Help_Line_Access; + Line : String_Access; + end record; + + procedure Explain (Key : in String; + Win : in Window); + + procedure Release_String is + new Ada.Unchecked_Deallocation (String, + String_Access); + procedure Release_Help_Line is + new Ada.Unchecked_Deallocation (Help_Line, + Help_Line_Access); + + function Search (Key : String) return Help_Line_Access; + procedure Release_Help (Root : in out Help_Line_Access); + + procedure Explain (Key : in String) + is + begin + Explain (Key, Null_Window); + end Explain; + + procedure Explain (Key : in String; + Win : in Window) + is + -- Retrieve the text associated with this key and display it in this + -- window. If no window argument is passed, the routine will create + -- a temporary window and use it. + + function Filter_Key return Real_Key_Code; + procedure Unknown_Key; + procedure Redo; + procedure To_Window (C : in out Help_Line_Access; + More : in out Boolean); + + Frame : Window := Null_Window; + + W : Window := Win; + K : Real_Key_Code; + P : Panel; + + Height : Line_Count; + Width : Column_Count; + Help : Help_Line_Access := Search (Key); + Current : Help_Line_Access; + Top_Line : Help_Line_Access; + + Has_More : Boolean; + + procedure Unknown_Key + is + begin + Add (W, "Help message with ID "); + Add (W, Key); + Add (W, " not found."); + Add (W, Character'Val (10)); + Add (W, "Press the Function key labelled 'Quit' key to continue."); + end Unknown_Key; + + procedure Redo + is + H : Help_Line_Access := Top_Line; + begin + if Top_Line /= null then + for L in 0 .. (Height - 1) loop + Add (W, L, 0, H.Line.all); + exit when H.Next = null; + H := H.Next; + end loop; + else + Unknown_Key; + end if; + end Redo; + + function Filter_Key return Real_Key_Code + is + K : Real_Key_Code; + begin + loop + K := Get_Key (W); + if K in Special_Key_Code'Range then + case K is + when HELP_CODE => + if not Find_Context (In_Help) then + Push_Environment (In_Help, False); + Explain (In_Help, W); + Pop_Environment; + Redo; + end if; + when EXPLAIN_CODE => + if not Find_Context (Help_Keys) then + Push_Environment (Help_Keys, False); + Explain (Help_Keys, W); + Pop_Environment; + Redo; + end if; + when others => exit; + end case; + else + exit; + end if; + end loop; + return K; + end Filter_Key; + + procedure To_Window (C : in out Help_Line_Access; + More : in out Boolean) + is + L : Line_Position := 0; + begin + loop + Add (W, L, 0, C.Line.all); + L := L + 1; + exit when C.Next = null or else L = Height; + C := C.Next; + end loop; + if C.Next /= null then + pragma Assert (L = Height); + More := True; + else + More := False; + end if; + end To_Window; + + begin + if W = Null_Window then + Push_Environment ("HELP"); + Default_Labels; + Frame := New_Window (Lines - 2, Columns, 0, 0); + if Has_Colors then + Set_Background (Win => Frame, + Ch => (Ch => ' ', + Color => Help_Color, + Attr => Normal_Video)); + Set_Character_Attributes (Win => Frame, + Attr => Normal_Video, + Color => Help_Color); + Erase (Frame); + end if; + Box (Frame); + Set_Character_Attributes (Frame, (Reverse_Video => True, + others => False)); + Add (Frame, Lines - 3, 2, "Cursor Up/Down scrolls"); + Set_Character_Attributes (Frame); -- Back to default. + Window_Title (Frame, "Explanation"); + W := Derived_Window (Frame, Lines - 4, Columns - 2, 1, 1); + Refresh_Without_Update (Frame); + Get_Size (W, Height, Width); + Set_Meta_Mode (W); + Set_KeyPad_Mode (W); + Allow_Scrolling (W, True); + Set_Echo_Mode (False); + P := Create (Frame); + Top (P); + Update_Panels; + else + Clear (W); + Refresh_Without_Update (W); + end if; + + Current := Help; Top_Line := Help; + + if null = Help then + Unknown_Key; + loop + K := Filter_Key; + exit when K = QUIT_CODE; + end loop; + else + To_Window (Current, Has_More); + if Has_More then + -- This means there are more lines available, so we have to go + -- into a scroll manager. + loop + K := Filter_Key; + if K in Special_Key_Code'Range then + case K is + when Key_Cursor_Down => + if Current.Next /= null then + Move_Cursor (W, Height - 1, 0); + Scroll (W, 1); + Current := Current.Next; + Top_Line := Top_Line.Next; + Add (W, Current.Line.all); + end if; + when Key_Cursor_Up => + if Top_Line.Prev /= null then + Move_Cursor (W, 0, 0); + Scroll (W, -1); + Top_Line := Top_Line.Prev; + Current := Current.Prev; + Add (W, Top_Line.Line.all); + end if; + when QUIT_CODE => exit; + when others => null; + end case; + end if; + end loop; + else + loop + K := Filter_Key; + exit when K = QUIT_CODE; + end loop; + end if; + end if; + + Clear (W); + + if Frame /= Null_Window then + Clear (Frame); + Delete (P); + Delete (W); + Delete (Frame); + Pop_Environment; + end if; + + Update_Panels; + Update_Screen; + + Release_Help (Help); + + end Explain; + + function Search (Key : String) return Help_Line_Access + is + Last : Natural; + Buffer : String (1 .. 256); + Root : Help_Line_Access := null; + Current : Help_Line_Access; + Tail : Help_Line_Access := null; + + function Next_Line return Boolean; + + function Next_Line return Boolean + is + H_End : constant String := "#END"; + begin + Get_Line (F, Buffer, Last); + if Last = H_End'Length and then H_End = Buffer (1 .. Last) then + return False; + else + return True; + end if; + end Next_Line; + begin + Reset (F); + Outer : + loop + exit when not Next_Line; + if Last = (1 + Key'Length) and then Key = Buffer (2 .. Last) + and then Buffer (1) = '#' then + loop + exit when not Next_Line; + exit when Buffer (1) = '#'; + Current := new Help_Line'(null, null, + new String'(Buffer (1 .. Last))); + if Tail = null then + Release_Help (Root); + Root := Current; + else + Tail.Next := Current; + Current.Prev := Tail; + end if; + Tail := Current; + end loop; + exit Outer; + end if; + end loop Outer; + return Root; + end Search; + + procedure Release_Help (Root : in out Help_Line_Access) + is + Next : Help_Line_Access; + begin + loop + exit when Root = null; + Next := Root.Next; + Release_String (Root.Line); + Release_Help_Line (Root); + Root := Next; + end loop; + end Release_Help; + + procedure Explain_Context + is + begin + Explain (Context); + end Explain_Context; + + procedure Notepad (Key : in String) + is + H : constant Help_Line_Access := Search (Key); + T : Help_Line_Access := H; + N : Line_Count := 1; + L : Line_Position := 0; + W : Window; + P : Panel; + begin + if H /= null then + loop + T := T.Next; + exit when T = null; + N := N + 1; + end loop; + W := New_Window (N + 2, Columns, Lines - N - 2, 0); + if Has_Colors then + Set_Background (Win => W, + Ch => (Ch => ' ', + Color => Notepad_Color, + Attr => Normal_Video)); + Set_Character_Attributes (Win => W, + Attr => Normal_Video, + Color => Notepad_Color); + Erase (W); + end if; + Box (W); + Window_Title (W, "Notepad"); + P := New_Panel (W); + T := H; + loop + Add (W, L + 1, 1, T.Line.all, Integer (Columns - 2)); + L := L + 1; + T := T.Next; + exit when T = null; + end loop; + T := H; + Release_Help (T); + Refresh_Without_Update (W); + Notepad_To_Context (P); + end if; + end Notepad; + +begin + Open (F, In_File, File_Name); +end Sample.Explanation; + diff --git a/ncurses-5.2/Ada95/samples/sample-explanation.ads b/ncurses-5.2/Ada95/samples/sample-explanation.ads new file mode 100644 index 0000000..056b5af --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-explanation.ads @@ -0,0 +1,59 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Explanation -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- Poor mans help system. This scans a sequential file for key lines and +-- then reads the lines up to the next key. Those lines are presented in +-- a window as help or explanation. +-- +package Sample.Explanation is + + procedure Explain (Key : in String); + -- Retrieve the text associated with this key and display it. + + procedure Explain_Context; + -- Explain the current context. + + procedure Notepad (Key : in String); + -- Put a note on the screen and maintain it with the context + + Explanation_Not_Found : exception; + Explanation_Error : exception; + +end Sample.Explanation; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb b/ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb new file mode 100644 index 0000000..92c8868 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo-aux.adb @@ -0,0 +1,259 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo.Aux -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Characters.Latin_1; use Ada.Characters.Latin_1; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Helpers; use Sample.Helpers; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Form_Demo.Aux is + + procedure Geometry (F : in Form; + L : out Line_Count; -- Lines used for menu + C : out Column_Count; -- Columns used for menu + Y : out Line_Position; -- Proposed Line for menu + X : out Column_Position) -- Proposed Column for menu + is + begin + Scale (F, L, C); + + L := L + 2; -- count for frame at top and bottom + C := C + 2; -- " + + -- Calculate horizontal coordinate at the screen center + X := (Columns - C) / 2; + Y := 1; -- start always in line 1 + end Geometry; + + function Create (F : Form; + Title : String; + Lin : Line_Position; + Col : Column_Position) return Panel + is + W, S : Window; + L : Line_Count; + C : Column_Count; + Y : Line_Position; + X : Column_Position; + Pan : Panel; + begin + Geometry (F, L, C, Y, X); + W := New_Window (L, C, Lin, Col); + Set_Meta_Mode (W); + Set_KeyPad_Mode (W); + if Has_Colors then + Set_Background (Win => W, + Ch => (Ch => ' ', + Color => Default_Colors, + Attr => Normal_Video)); + Set_Character_Attributes (Win => W, + Color => Default_Colors, + Attr => Normal_Video); + Erase (W); + end if; + S := Derived_Window (W, L - 2, C - 2, 1, 1); + Set_Meta_Mode (S); + Set_KeyPad_Mode (S); + Box (W); + Set_Window (F, W); + Set_Sub_Window (F, S); + if Title'Length > 0 then + Window_Title (W, Title); + end if; + Pan := New_Panel (W); + Post (F); + return Pan; + end Create; + + procedure Destroy (F : in Form; + P : in out Panel) + is + W, S : Window; + begin + W := Get_Window (F); + S := Get_Sub_Window (F); + Post (F, False); + Erase (W); + Delete (P); + Set_Window (F, Null_Window); + Set_Sub_Window (F, Null_Window); + Delete (S); + Delete (W); + Update_Panels; + end Destroy; + + function Get_Request (F : Form; + P : Panel; + Handle_CRLF : Boolean := True) return Key_Code + is + W : constant Window := Get_Window (F); + K : Real_Key_Code; + Ch : Character; + begin + Top (P); + loop + K := Get_Key (W); + if K in Special_Key_Code'Range then + case K is + when HELP_CODE => Explain_Context; + when EXPLAIN_CODE => Explain ("FORMKEYS"); + when Key_Home => return F_First_Field; + when Key_End => return F_Last_Field; + when QUIT_CODE => return QUIT; + when Key_Cursor_Down => return F_Down_Char; + when Key_Cursor_Up => return F_Up_Char; + when Key_Cursor_Left => return F_Previous_Char; + when Key_Cursor_Right => return F_Next_Char; + when Key_Next_Page => return F_Next_Page; + when Key_Previous_Page => return F_Previous_Page; + when Key_Backspace => return F_Delete_Previous; + when Key_Clear_Screen => return F_Clear_Field; + when Key_Clear_End_Of_Line => return F_Clear_EOF; + when others => return K; + end case; + elsif K in Normal_Key_Code'Range then + Ch := Character'Val (K); + case Ch is + when CAN => return QUIT; -- CTRL-X + + when ACK => return F_Next_Field; -- CTRL-F + when STX => return F_Previous_Field; -- CTRL-B + when FF => return F_Left_Field; -- CTRL-L + when DC2 => return F_Right_Field; -- CTRL-R + when NAK => return F_Up_Field; -- CTRL-U + when EOT => return F_Down_Field; -- CTRL-D + + when ETB => return F_Next_Word; -- CTRL-W + when DC4 => return F_Previous_Word; -- CTRL-T + + when SOH => return F_Begin_Field; -- CTRL-A + when ENQ => return F_End_Field; -- CTRL-E + + when HT => return F_Insert_Char; -- CTRL-I + when SI => return F_Insert_Line; -- CTRL-O + when SYN => return F_Delete_Char; -- CTRL-V + when BS => return F_Delete_Previous; -- CTRL-H + when EM => return F_Delete_Line; -- CTRL-Y + when BEL => return F_Delete_Word; -- CTRL-G + when VT => return F_Clear_EOF; -- CTRL-K + + when SO => return F_Next_Choice; -- CTRL-N + when DLE => return F_Previous_Choice; -- CTRL-P + + when CR | LF => + if Handle_CRLF then + return F_New_Line; + else + return K; + end if; + when others => return K; + end case; + else + return K; + end if; + end loop; + end Get_Request; + + function Make (Top : Line_Position; + Left : Column_Position; + Text : String) return Field + is + Fld : Field; + C : Column_Count := Column_Count (Text'Length); + begin + Fld := New_Field (1, C, Top, Left); + Set_Buffer (Fld, 0, Text); + Switch_Options (Fld, (Active => True, others => False), False); + if Has_Colors then + Set_Background (Fld => Fld, Color => Default_Colors); + end if; + return Fld; + end Make; + + function Make (Height : Line_Count := 1; + Width : Column_Count; + Top : Line_Position; + Left : Column_Position; + Off_Screen : Natural := 0) return Field + is + Fld : Field := New_Field (Height, Width, Top, Left, Off_Screen); + begin + if Has_Colors then + Set_Foreground (Fld => Fld, Color => Form_Fore_Color); + Set_Background (Fld => Fld, Color => Form_Back_Color); + else + Set_Background (Fld, (Reverse_Video => True, others => False)); + end if; + return Fld; + end Make; + + function Default_Driver (F : Form; + K : Key_Code; + P : Panel) return Boolean + is + begin + if K in User_Key_Code'Range and then K = QUIT then + if Driver (F, F_Validate_Field) = Form_Ok then + return True; + end if; + end if; + return False; + end Default_Driver; + + function Count_Active (F : Form) return Natural + is + N : Natural := 0; + O : Field_Option_Set; + H : constant Natural := Field_Count (F); + begin + if H > 0 then + for I in 1 .. H loop + Get_Options (Fields (F, I), O); + if O.Active then + N := N + 1; + end if; + end loop; + end if; + return N; + end Count_Active; + +end Sample.Form_Demo.Aux; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads b/ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads new file mode 100644 index 0000000..d3e6d8d --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo-aux.ads @@ -0,0 +1,92 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo.Aux -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Forms; use Terminal_Interface.Curses.Forms; + +package Sample.Form_Demo.Aux is + + procedure Geometry (F : in Form; + L : out Line_Count; + C : out Column_Count; + Y : out Line_Position; + X : out Column_Position); + -- Calculate the geometry for a panel beeing able to be used to display + -- the menu. + + function Create (F : Form; + Title : String; + Lin : Line_Position; + Col : Column_Position) return Panel; + -- Create a panel decorated with a frame and the title at the specified + -- position. The dimension of the panel is derived from the menus layout. + + procedure Destroy (F : in Form; + P : in out Panel); + -- Destroy all the windowing structures associated with this menu and + -- panel. + + function Get_Request (F : Form; + P : Panel; + Handle_CRLF : Boolean := True) return Key_Code; + -- Centralized request driver for all menus in this sample. This + -- gives us a common key binding for all menus. + + function Make (Top : Line_Position; + Left : Column_Position; + Text : String) return Field; + -- create a label + + function Make (Height : Line_Count := 1; + Width : Column_Count; + Top : Line_Position; + Left : Column_Position; + Off_Screen : Natural := 0) return Field; + -- create a editable field + + function Default_Driver (F : Form; + K : Key_Code; + P : Panel) return Boolean; + + function Count_Active (F : Form) return Natural; + -- Count the number of active fields in the form + +end Sample.Form_Demo.Aux; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo-handler.adb b/ncurses-5.2/Ada95/samples/sample-form_demo-handler.adb new file mode 100644 index 0000000..6cffc9c --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo-handler.adb @@ -0,0 +1,97 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo.Handler -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Sample.Form_Demo.Aux; + +package body Sample.Form_Demo.Handler is + + package Aux renames Sample.Form_Demo.Aux; + + procedure Drive_Me (F : in Form; + Title : in String := "") + is + L : Line_Count; + C : Column_Count; + Y : Line_Position; + X : Column_Position; + begin + Aux.Geometry (F, L, C, Y, X); + Drive_Me (F, Y, X, Title); + end Drive_Me; + + procedure Drive_Me (F : in Form; + Lin : in Line_Position; + Col : in Column_Position; + Title : in String := "") + is + Pan : Panel := Aux.Create (F, Title, Lin, Col); + V : Cursor_Visibility := Normal; + Handle_CRLF : Boolean := True; + + begin + Set_Cursor_Visibility (V); + if Aux.Count_Active (F) = 1 then + Handle_CRLF := False; + end if; + loop + declare + K : Key_Code := Aux.Get_Request (F, Pan, Handle_CRLF); + R : Driver_Result; + begin + if (K = 13 or else K = 10) and then not Handle_CRLF then + R := Unknown_Request; + else + R := Driver (F, K); + end if; + case R is + when Form_Ok => null; + when Unknown_Request => + if My_Driver (F, K, Pan) then + exit; + end if; + when others => Beep; + end case; + end; + end loop; + Set_Cursor_Visibility (V); + Aux.Destroy (F, Pan); + end Drive_Me; + +end Sample.Form_Demo.Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo-handler.ads b/ncurses-5.2/Ada95/samples/sample-form_demo-handler.ads new file mode 100644 index 0000000..9f8da7d --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo-handler.ads @@ -0,0 +1,64 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo.Handler -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; +use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; +use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Forms; +use Terminal_Interface.Curses.Forms; + +generic + with function My_Driver (Frm : Form; + K : Key_Code; + Pan : Panel) return Boolean; +package Sample.Form_Demo.Handler is + + procedure Drive_Me (F : in Form; + Lin : in Line_Position; + Col : in Column_Position; + Title : in String := ""); + -- Position the menu at the given point and drive it. + + procedure Drive_Me (F : in Form; + Title : in String := ""); + -- Center menu and drive it. + +end Sample.Form_Demo.Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo.adb b/ncurses-5.2/Ada95/samples/sample-form_demo.adb new file mode 100644 index 0000000..ec4a762 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo.adb @@ -0,0 +1,134 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Forms; use Terminal_Interface.Curses.Forms; +with Terminal_Interface.Curses.Forms.Field_User_Data; +with Terminal_Interface.Curses.Forms.Form_User_Data; +with Sample.My_Field_Type; use Sample.My_Field_Type; +with Sample.Explanation; use Sample.Explanation; +with Sample.Form_Demo.Aux; use Sample.Form_Demo.Aux; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Form_Demo.Handler; + +with Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada; +with Terminal_Interface.Curses.Forms.Field_Types.Enumeration; +use Terminal_Interface.Curses.Forms.Field_Types.Enumeration; +with Terminal_Interface.Curses.Forms.Field_Types.IntField; +use Terminal_Interface.Curses.Forms.Field_Types.IntField; + +package body Sample.Form_Demo is + + type User_Data is + record + Data : Integer; + end record; + type User_Access is access User_Data; + + package Fld_U is new + Terminal_Interface.Curses.Forms.Field_User_Data (User_Data, + User_Access); + + package Frm_U is new + Terminal_Interface.Curses.Forms.Form_User_Data (User_Data, + User_Access); + + type Weekday is (Sunday, Monday, Tuesday, Wednesday, Thursday, + Friday, Saturday); + + package Weekday_Enum is new + Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada (Weekday); + + Enum_Field : constant Enumeration_Field := + Weekday_Enum.Create; + + procedure Demo + is + + Mft : My_Data := (Ch => 'X'); + + FA : Field_Array_Access := new Field_Array' + (Make (0, 14, "Sample Entry Form"), + Make (2, 0, "WeekdayEnumeration"), + Make (2, 20, "Numeric 1-10"), + Make (2, 34, "Only 'X'"), + Make (5, 0, "Multiple Lines offscreen(Scroll)"), + Make (Width => 18, Top => 3, Left => 0), + Make (Width => 12, Top => 3, Left => 20), + Make (Width => 12, Top => 3, Left => 34), + Make (Width => 46, Top => 6, Left => 0, Height => 4, Off_Screen => 2), + Null_Field + ); + + Frm : Terminal_Interface.Curses.Forms.Form := Create (FA); + + I_F : constant Integer_Field := (Precision => 0, + Lower_Limit => 1, + Upper_Limit => 10); + + F1, F2 : User_Access; + + package Fh is new Sample.Form_Demo.Handler (Default_Driver); + + begin + Push_Environment ("FORM00"); + Notepad ("FORM-PAD00"); + Default_Labels; + + Set_Field_Type (FA (6), Enum_Field); + Set_Field_Type (FA (7), I_F); + Set_Field_Type (FA (8), Mft); + + F1 := new User_Data'(Data => 4711); + Fld_U.Set_User_Data (FA (1), F1); + + Fh.Drive_Me (Frm); + + Fld_U.Get_User_Data (FA (1), F2); + pragma Assert (F1 = F2); + pragma Assert (F1.Data = F2.Data); + + Pop_Environment; + Delete (Frm); + + Free (FA, True); + end Demo; + +end Sample.Form_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-form_demo.ads b/ncurses-5.2/Ada95/samples/sample-form_demo.ads new file mode 100644 index 0000000..61d9cbf --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-form_demo.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Form_Demo -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Form_Demo is + + procedure Demo; + +end Sample.Form_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-function_key_setting.adb b/ncurses-5.2/Ada95/samples/sample-function_key_setting.adb new file mode 100644 index 0000000..3579153 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-function_key_setting.adb @@ -0,0 +1,213 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Function_Key_Setting -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Deallocation; +with Sample.Manifest; use Sample.Manifest; + +-- This package implements a simple stack of function key label environments. +-- +package body Sample.Function_Key_Setting is + + Max_Label_Length : constant Positive := 8; + Number_Of_Keys : Label_Number := Label_Number'Last; + Justification : Label_Justification := Left; + + subtype Label is String (1 .. Max_Label_Length); + type Label_Array is array (Label_Number range <>) of Label; + + type Key_Environment (N : Label_Number := Label_Number'Last); + type Env_Ptr is access Key_Environment; + pragma Controlled (Env_Ptr); + + type String_Access is access String; + pragma Controlled (String_Access); + + Active_Context : String_Access := new String'("MAIN"); + Active_Notepad : Panel := Null_Panel; + + type Key_Environment (N : Label_Number := Label_Number'Last) is + record + Prev : Env_Ptr; + Help : String_Access; + Notepad : Panel; + Labels : Label_Array (1 .. N); + end record; + + procedure Release_String is + new Ada.Unchecked_Deallocation (String, + String_Access); + + procedure Release_Environment is + new Ada.Unchecked_Deallocation (Key_Environment, + Env_Ptr); + + Top_Of_Stack : Env_Ptr := null; + + procedure Push_Environment (Key : in String; + Reset : in Boolean := True) + is + P : constant Env_Ptr := new Key_Environment (Number_Of_Keys); + begin + -- Store the current labels in the environment + for I in 1 .. Number_Of_Keys loop + Get_Soft_Label_Key (I, P.Labels (I)); + if Reset then + Set_Soft_Label_Key (I, " "); + end if; + end loop; + P.Prev := Top_Of_Stack; + -- now store active help context and notepad + P.Help := Active_Context; + P.Notepad := Active_Notepad; + -- The notepad must now vanish and the new notepad is empty. + if (P.Notepad /= Null_Panel) then + Hide (P.Notepad); + Update_Panels; + end if; + Active_Notepad := Null_Panel; + Active_Context := new String'(Key); + + Top_Of_Stack := P; + if Reset then + Refresh_Soft_Label_Keys_Without_Update; + end if; + end Push_Environment; + + procedure Pop_Environment + is + P : Env_Ptr := Top_Of_Stack; + begin + if Top_Of_Stack = null then + raise Function_Key_Stack_Error; + else + for I in 1 .. Number_Of_Keys loop + Set_Soft_Label_Key (I, P.Labels (I), Justification); + end loop; + pragma Assert (Active_Context /= null); + Release_String (Active_Context); + Active_Context := P.Help; + Refresh_Soft_Label_Keys_Without_Update; + Notepad_To_Context (P.Notepad); + Top_Of_Stack := P.Prev; + Release_Environment (P); + end if; + end Pop_Environment; + + function Context return String + is + begin + if Active_Context /= null then + return Active_Context.all; + else + return ""; + end if; + end Context; + + function Find_Context (Key : String) return Boolean + is + P : Env_Ptr := Top_Of_Stack; + begin + if Active_Context.all = Key then + return True; + else + loop + exit when P = null; + if P.Help.all = Key then + return True; + else + P := P.Prev; + end if; + end loop; + return False; + end if; + end Find_Context; + + procedure Notepad_To_Context (Pan : in Panel) + is + W : Window; + begin + if Active_Notepad /= Null_Panel then + W := Get_Window (Active_Notepad); + Clear (W); + Delete (Active_Notepad); + Delete (W); + end if; + Active_Notepad := Pan; + if Pan /= Null_Panel then + Top (Pan); + end if; + Update_Panels; + Update_Screen; + end Notepad_To_Context; + + procedure Initialize (Mode : Soft_Label_Key_Format := PC_Style; + Just : Label_Justification := Left) + is + begin + case Mode is + when PC_Style .. PC_Style_With_Index + => Number_Of_Keys := 12; + when others + => Number_Of_Keys := 8; + end case; + Init_Soft_Label_Keys (Mode); + Justification := Just; + end Initialize; + + procedure Default_Labels + is + begin + Set_Soft_Label_Key (FKEY_QUIT, "Quit"); + Set_Soft_Label_Key (FKEY_HELP, "Help"); + Set_Soft_Label_Key (FKEY_EXPLAIN, "Keys"); + Refresh_Soft_Label_Keys_Without_Update; + end Default_Labels; + + function Notepad_Window return Window + is + begin + if Active_Notepad /= Null_Panel then + return Get_Window (Active_Notepad); + else + return Null_Window; + end if; + end Notepad_Window; + +end Sample.Function_Key_Setting; diff --git a/ncurses-5.2/Ada95/samples/sample-function_key_setting.ads b/ncurses-5.2/Ada95/samples/sample-function_key_setting.ads new file mode 100644 index 0000000..eb375d3 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-function_key_setting.ads @@ -0,0 +1,82 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Function_Key_Setting -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; + +-- This package implements a simple stack of function key label environments. +-- +package Sample.Function_Key_Setting is + + procedure Push_Environment (Key : in String; + Reset : in Boolean := True); + -- Push the definition of the current function keys on an internal + -- stack. If the reset flag is true, all labels are reset while + -- pushed, so the new environment can assume a tabula rasa. + -- The Key defines the new Help Context associated with the new + -- Environment. This saves also the currently active Notepad. + + procedure Pop_Environment; + -- Pop the Definitions from the stack and make them the current ones. + -- This also restores the Help context and the previous Notepad. + + procedure Initialize (Mode : Soft_Label_Key_Format := PC_Style; + Just : Label_Justification := Left); + -- Initialize the environment + + function Context return String; + -- Return the current context identitfier + + function Find_Context (Key : String) return Boolean; + -- Look for a context, return true if it is in the stack, + -- false otherwise. + + procedure Notepad_To_Context (Pan : in Panel); + -- Add a panel representing a notepad to the current context. + + Function_Key_Stack_Error : exception; + + procedure Default_Labels; + -- Set the default labels used in all environments + + function Notepad_Window return Window; + -- Return the current notepad window or Null_Window if there is none. + +end Sample.Function_Key_Setting; diff --git a/ncurses-5.2/Ada95/samples/sample-header_handler.adb b/ncurses-5.2/Ada95/samples/sample-header_handler.adb new file mode 100644 index 0000000..77cd187 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-header_handler.adb @@ -0,0 +1,180 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Header_Handler -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Calendar; use Ada.Calendar; +with Terminal_Interface.Curses.Text_IO.Integer_IO; +with Sample.Manifest; use Sample.Manifest; + +-- This package handles the painting of the header line of the screen. +-- +package body Sample.Header_Handler is + + package Int_IO is new + Terminal_Interface.Curses.Text_IO.Integer_IO (Integer); + use Int_IO; + + Header_Window : Window := Null_Window; + + Display_Hour : Integer := -1; -- hour last displayed + Display_Min : Integer := -1; -- minute last displayed + Display_Day : Integer := -1; -- day last displayed + Display_Month : Integer := -1; -- month last displayed + + -- This is the routine handed over to the curses library to be called + -- as initialization routine when ripping of the header lines from + -- the screen. This routine must follow C conventions. + function Init_Header_Window (Win : Window; + Columns : Column_Count) return Integer; + pragma Convention (C, Init_Header_Window); + + procedure Internal_Update_Header_Window (Do_Update : in Boolean); + + + -- The initialization must be called before Init_Screen. It steals two + -- lines from the top of the screen. + procedure Init_Header_Handler + is + begin + Rip_Off_Lines (2, Init_Header_Window'Access); + end Init_Header_Handler; + + procedure N_Out (N : in Integer); + + -- Emit a two digit number and ensure that a leading zero is generated if + -- necessary. + procedure N_Out (N : in Integer) + is + begin + if N < 10 then + Add (Header_Window, '0'); + Put (Header_Window, N, 1); + else + Put (Header_Window, N, 2); + end if; + end N_Out; + + -- Paint the header window. The input parameter is a flag indicating + -- whether or not the screen should be updated physically after painting. + procedure Internal_Update_Header_Window (Do_Update : in Boolean) + is + type Month_Name_Array is + array (Month_Number'First .. Month_Number'Last) of String (1 .. 9); + + Month_Names : constant Month_Name_Array := + ("January ", + "February ", + "March ", + "April ", + "May ", + "June ", + "July ", + "August ", + "September", + "October ", + "November ", + "December "); + + Now : Time := Clock; + Sec : Integer := Integer (Seconds (Now)); + Hour : Integer := Sec / 3600; + Minute : Integer := (Sec - Hour * 3600) / 60; + Mon : Month_Number := Month (Now); + D : Day_Number := Day (Now); + begin + if Header_Window /= Null_Window then + if Minute /= Display_Min or else Hour /= Display_Hour + or else Display_Day /= D or else Display_Month /= Mon then + Move_Cursor (Header_Window, 0, 0); + N_Out (D); Add (Header_Window, '.'); + Add (Header_Window, Month_Names (Mon)); + Move_Cursor (Header_Window, 1, 0); + N_Out (Hour); Add (Header_Window, ':'); + N_Out (Minute); + Display_Min := Minute; + Display_Hour := Hour; + Display_Month := Mon; + Display_Day := D; + Refresh_Without_Update (Header_Window); + if Do_Update then + Update_Screen; + end if; + end if; + end if; + end Internal_Update_Header_Window; + + -- This routine is called in the keyboard input timeout handler. So it will + -- periodically update the header line of the screen. + procedure Update_Header_Window + is + begin + Internal_Update_Header_Window (True); + end Update_Header_Window; + + function Init_Header_Window (Win : Window; + Columns : Column_Count) return Integer + is + Title : constant String := "Ada 95 ncurses Binding Sample"; + Pos : Column_Position; + begin + Header_Window := Win; + if Win /= Null_Window then + if Has_Colors then + Set_Background (Win => Win, + Ch => (Ch => ' ', + Color => Header_Color, + Attr => Normal_Video)); + Set_Character_Attributes (Win => Win, + Attr => Normal_Video, + Color => Header_Color); + Erase (Win); + end if; + Leave_Cursor_After_Update (Win, True); + Pos := Columns - Column_Position (Title'Length); + Add (Win, 0, Pos / 2, Title); + -- In this phase we must not allow a physical update, because + -- ncurses isn´t properly initialized at this point. + Internal_Update_Header_Window (False); + return 0; + else + return -1; + end if; + end Init_Header_Window; + +end Sample.Header_Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-header_handler.ads b/ncurses-5.2/Ada95/samples/sample-header_handler.ads new file mode 100644 index 0000000..35973b3 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-header_handler.ads @@ -0,0 +1,53 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Header_Handler -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +-- This package handles the painting of the header line of the screen. +-- +package Sample.Header_Handler is + + procedure Init_Header_Handler; + -- Initialize the handler for the headerlines. + + procedure Update_Header_Window; + -- Update the information in the header window + +end Sample.Header_Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-helpers.adb b/ncurses-5.2/Ada95/samples/sample-helpers.adb new file mode 100644 index 0000000..7b15895 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-helpers.adb @@ -0,0 +1,69 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Helpers -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +with Sample.Explanation; use Sample.Explanation; + +-- This package contains some conveniant helper routines used throughout +-- this example. +-- +package body Sample.Helpers is + + procedure Window_Title (Win : in Window; + Title : in String) + is + Height : Line_Count; + Width : Column_Count; + Pos : Column_Position := 0; + begin + Get_Size (Win, Height, Width); + if Title'Length < Width then + Pos := (Width - Title'Length) / 2; + end if; + Add (Win, 0, Pos, Title); + end Window_Title; + + procedure Not_Implemented is + begin + Explain ("NOTIMPL"); + end Not_Implemented; + +end Sample.Helpers; diff --git a/ncurses-5.2/Ada95/samples/sample-helpers.ads b/ncurses-5.2/Ada95/samples/sample-helpers.ads new file mode 100644 index 0000000..f8dc0d9 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-helpers.ads @@ -0,0 +1,54 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Helpers -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +-- This package contains some conveniant helper routines used throughout +-- this example. +-- +package Sample.Helpers is + + procedure Window_Title (Win : in Window; + Title : in String); + -- Put a title string into the first line of the window + + procedure Not_Implemented; + +end Sample.Helpers; diff --git a/ncurses-5.2/Ada95/samples/sample-keyboard_handler.adb b/ncurses-5.2/Ada95/samples/sample-keyboard_handler.adb new file mode 100644 index 0000000..8dfda23 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-keyboard_handler.adb @@ -0,0 +1,191 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Keyboard_Handler -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Fixed; use Ada.Strings.Fixed; +with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants; +with Ada.Characters.Latin_1; use Ada.Characters.Latin_1; +with Ada.Characters.Handling; use Ada.Characters.Handling; + +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Forms; use Terminal_Interface.Curses.Forms; +with Terminal_Interface.Curses.Forms.Field_Types.Enumeration; +use Terminal_Interface.Curses.Forms.Field_Types.Enumeration; + +with Sample.Header_Handler; use Sample.Header_Handler; +with Sample.Form_Demo.Aux; use Sample.Form_Demo.Aux; +with Sample.Manifest; use Sample.Manifest; +with Sample.Form_Demo.Handler; + +-- This package contains a centralized keyboard handler used throughout +-- this example. The handler establishes a timeout mechanism that provides +-- periodical updates of the common header lines used in this example. +-- + +package body Sample.Keyboard_Handler is + + In_Command : Boolean := False; + + function Get_Key (Win : Window := Standard_Window) return Real_Key_Code + is + K : Real_Key_Code; + + function Command return Real_Key_Code; + + + function Command return Real_Key_Code + is + function My_Driver (F : Form; + C : Key_Code; + P : Panel) return Boolean; + package Fh is new Sample.Form_Demo.Handler (My_Driver); + + type Label_Array is array (Label_Number) of String (1 .. 8); + + Labels : Label_Array; + + FA : Field_Array_Access := new Field_Array' + (Make (0, 0, "Command:"), + Make (Top => 0, Left => 9, Width => Columns - 11), + Null_Field); + + K : Real_Key_Code := Key_None; + N : Natural := 0; + + function My_Driver (F : Form; + C : Key_Code; + P : Panel) return Boolean + is + Ch : Character; + begin + if C in User_Key_Code'Range and then C = QUIT then + if Driver (F, F_Validate_Field) = Form_Ok then + K := Key_None; + return True; + end if; + elsif C in Normal_Key_Code'Range then + Ch := Character'Val (C); + if (Ch = LF or else Ch = CR) then + if Driver (F, F_Validate_Field) = Form_Ok then + declare + Buffer : String (1 .. Positive (Columns - 11)); + Cmdc : String (1 .. 8); + begin + Get_Buffer (Fld => FA (2), Str => Buffer); + Trim (Buffer, Left); + if Buffer (1) /= ' ' then + Cmdc := To_Upper (Buffer (Cmdc'Range)); + for I in Labels'Range loop + if Cmdc = Labels (I) then + K := Function_Key_Code + (Function_Key_Number (I)); + exit; + end if; + end loop; + end if; + return True; + end; + end if; + end if; + end if; + return False; + end My_Driver; + + begin + In_Command := True; + for I in Label_Number'Range loop + Get_Soft_Label_Key (I, Labels (I)); + Trim (Labels (I), Left); + Translate (Labels (I), Upper_Case_Map); + if Labels (I) (1) /= ' ' then + N := N + 1; + end if; + end loop; + if N > 0 then -- some labels were really set + declare + Enum_Info : Enumeration_Info (N); + Enum_Field : Enumeration_Field; + J : Positive := Enum_Info.Names'First; + + Frm : Form := Create (FA); + + begin + for I in Label_Number'Range loop + if Labels (I) (1) /= ' ' then + Enum_Info.Names (J) := new String'(Labels (I)); + J := J + 1; + end if; + end loop; + Enum_Field := Create (Enum_Info, True); + Set_Field_Type (FA (2), Enum_Field); + Set_Background (FA (2), Normal_Video); + + Fh.Drive_Me (Frm, Lines - 3, 0); + Delete (Frm); + Update_Panels; Update_Screen; + end; + end if; + Free (FA, True); + In_Command := False; + return K; + end Command; + + begin + Set_Timeout_Mode (Win, Delayed, 30000); + loop + K := Get_Keystroke (Win); + if K = Key_None then -- a timeout occured + Update_Header_Window; + elsif K = 3 and then not In_Command then -- CTRL-C + K := Command; + exit when K /= Key_None; + else + exit; + end if; + end loop; + return K; + end Get_Key; + + procedure Init_Keyboard_Handler is + begin + null; + end Init_Keyboard_Handler; + +end Sample.Keyboard_Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-keyboard_handler.ads b/ncurses-5.2/Ada95/samples/sample-keyboard_handler.ads new file mode 100644 index 0000000..5601aa4 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-keyboard_handler.ads @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Keyboard_Handler -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +-- This package contains a centralized keyboard handler used throughout +-- this example. The handler establishes a timeout mechanism that provides +-- periodical updates of the common header lines used in this example. +-- +package Sample.Keyboard_Handler is + + function Get_Key (Win : Window := Standard_Window) return Real_Key_Code; + -- The central routine for handling keystrokes. + + procedure Init_Keyboard_Handler; + -- Initialize the keyboard + +end Sample.Keyboard_Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-manifest.ads b/ncurses-5.2/Ada95/samples/sample-manifest.ads new file mode 100644 index 0000000..7ed79e1 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-manifest.ads @@ -0,0 +1,67 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Manifest -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; + +package Sample.Manifest is + + QUIT : constant User_Key_Code := User_Key_Code'First; + SELECT_ITEM : constant User_Key_Code := QUIT + 1; + + FKEY_HELP : constant Label_Number := 1; + HELP_CODE : constant Special_Key_Code := Key_F1; + FKEY_EXPLAIN : constant Label_Number := 2; + EXPLAIN_CODE : constant Special_Key_Code := Key_F2; + FKEY_QUIT : constant Label_Number := 3; + QUIT_CODE : constant Special_Key_Code := Key_F3; + + Menu_Marker : constant String := "=> "; + + Default_Colors : constant Redefinable_Color_Pair := 1; + Menu_Fore_Color : constant Redefinable_Color_Pair := 2; + Menu_Back_Color : constant Redefinable_Color_Pair := 3; + Menu_Grey_Color : constant Redefinable_Color_Pair := 4; + Form_Fore_Color : constant Redefinable_Color_Pair := 5; + Form_Back_Color : constant Redefinable_Color_Pair := 6; + Notepad_Color : constant Redefinable_Color_Pair := 7; + Help_Color : constant Redefinable_Color_Pair := 8; + Header_Color : constant Redefinable_Color_Pair := 9; + +end Sample.Manifest; diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb b/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb new file mode 100644 index 0000000..2c1931c --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.adb @@ -0,0 +1,204 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo.Aux -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Characters.Latin_1; use Ada.Characters.Latin_1; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Helpers; use Sample.Helpers; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Menu_Demo.Aux is + + procedure Geometry (M : in Menu; + L : out Line_Count; + C : out Column_Count; + Y : out Line_Position; + X : out Column_Position; + Fy : out Line_Position; + Fx : out Column_Position); + + procedure Geometry (M : in Menu; + L : out Line_Count; -- Lines used for menu + C : out Column_Count; -- Columns used for menu + Y : out Line_Position; -- Proposed Line for menu + X : out Column_Position; -- Proposed Column for menu + Fy : out Line_Position; -- Vertical inner frame + Fx : out Column_Position) -- Horiz. inner frame + is + Spc_Desc : Column_Position; -- spaces between description and item + begin + Set_Mark (M, Menu_Marker); + + Spacing (M, Spc_Desc, Fy, Fx); + Scale (M, L, C); + + Fx := Fx + Column_Position (Fy - 1); -- looks a bit nicer + + L := L + 2 * Fy; -- count for frame at top and bottom + C := C + 2 * Fx; -- " + + -- Calculate horizontal coordinate at the screen center + X := (Columns - C) / 2; + Y := 1; -- always startin line 1 + + end Geometry; + + procedure Geometry (M : in Menu; + L : out Line_Count; -- Lines used for menu + C : out Column_Count; -- Columns used for menu + Y : out Line_Position; -- Proposed Line for menu + X : out Column_Position) -- Proposed Column for menu + is + Fy : Line_Position; + Fx : Column_Position; + begin + Geometry (M, L, C, Y, X, Fy, Fx); + end Geometry; + + function Create (M : Menu; + Title : String; + Lin : Line_Position; + Col : Column_Position) return Panel + is + W, S : Window; + L : Line_Count; + C : Column_Count; + Y, Fy : Line_Position; + X, Fx : Column_Position; + Pan : Panel; + begin + Geometry (M, L, C, Y, X, Fy, Fx); + W := New_Window (L, C, Lin, Col); + Set_Meta_Mode (W); + Set_KeyPad_Mode (W); + if Has_Colors then + Set_Background (Win => W, + Ch => (Ch => ' ', + Color => Menu_Back_Color, + Attr => Normal_Video)); + Set_Foreground (Men => M, Color => Menu_Fore_Color); + Set_Background (Men => M, Color => Menu_Back_Color); + Set_Grey (Men => M, Color => Menu_Grey_Color); + Erase (W); + end if; + S := Derived_Window (W, L - Fy, C - Fx, Fy, Fx); + Set_Meta_Mode (S); + Set_KeyPad_Mode (S); + Box (W); + Set_Window (M, W); + Set_Sub_Window (M, S); + if Title'Length > 0 then + Window_Title (W, Title); + end if; + Pan := New_Panel (W); + Post (M); + return Pan; + end Create; + + procedure Destroy (M : in Menu; + P : in out Panel) + is + W, S : Window; + begin + W := Get_Window (M); + S := Get_Sub_Window (M); + Post (M, False); + Erase (W); + Delete (P); + Set_Window (M, Null_Window); + Set_Sub_Window (M, Null_Window); + Delete (S); + Delete (W); + Update_Panels; + end Destroy; + + function Get_Request (M : Menu; P : Panel) return Key_Code + is + W : constant Window := Get_Window (M); + K : Real_Key_Code; + Ch : Character; + begin + Top (P); + loop + K := Get_Key (W); + if K in Special_Key_Code'Range then + case K is + when HELP_CODE => Explain_Context; + when EXPLAIN_CODE => Explain ("MENUKEYS"); + when Key_Home => return REQ_FIRST_ITEM; + when QUIT_CODE => return QUIT; + when Key_Cursor_Down => return REQ_DOWN_ITEM; + when Key_Cursor_Up => return REQ_UP_ITEM; + when Key_Cursor_Left => return REQ_LEFT_ITEM; + when Key_Cursor_Right => return REQ_RIGHT_ITEM; + when Key_End => return REQ_LAST_ITEM; + when Key_Backspace => return REQ_BACK_PATTERN; + when Key_Next_Page => return REQ_SCR_DPAGE; + when Key_Previous_Page => return REQ_SCR_UPAGE; + when others => return K; + end case; + elsif K in Normal_Key_Code'Range then + Ch := Character'Val (K); + case Ch is + when CAN => return QUIT; -- CTRL-X + when SO => return REQ_NEXT_ITEM; -- CTRL-N + when DLE => return REQ_PREV_ITEM; -- CTRL-P + when NAK => return REQ_SCR_ULINE; -- CTRL-U + when EOT => return REQ_SCR_DLINE; -- CTRL-D + when ACK => return REQ_SCR_DPAGE; -- CTRL-F + when STX => return REQ_SCR_UPAGE; -- CTRL-B + when EM => return REQ_CLEAR_PATTERN; -- CTRL-Y + when BS => return REQ_BACK_PATTERN; -- CTRL-H + when SOH => return REQ_NEXT_MATCH; -- CTRL-A + when ENQ => return REQ_PREV_MATCH; -- CTRL-E + when DC4 => return REQ_TOGGLE_ITEM; -- CTRL-T + + when CR | LF => return SELECT_ITEM; + when others => return K; + end case; + else + return K; + end if; + end loop; + end Get_Request; + +end Sample.Menu_Demo.Aux; + diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads b/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads new file mode 100644 index 0000000..88de9bd --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo-aux.ads @@ -0,0 +1,71 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo.Aux -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Menus; use Terminal_Interface.Curses.Menus; + +package Sample.Menu_Demo.Aux is + + procedure Geometry (M : in Menu; + L : out Line_Count; + C : out Column_Count; + Y : out Line_Position; + X : out Column_Position); + -- Calculate the geometry for a panel beeing able to be used to display + -- the menu. + + function Create (M : Menu; + Title : String; + Lin : Line_Position; + Col : Column_Position) return Panel; + -- Create a panel decorated with a frame and the title at the specified + -- position. The dimension of the panel is derived from the menus layout. + + procedure Destroy (M : in Menu; + P : in out Panel); + -- Destroy all the windowing structures associated with this menu and + -- panel. + + function Get_Request (M : Menu; P : Panel) return Key_Code; + -- Centralized request driver for all menus in this sample. This + -- gives us a common key binding for all menus. + +end Sample.Menu_Demo.Aux; diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.adb b/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.adb new file mode 100644 index 0000000..90f4e39 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.adb @@ -0,0 +1,107 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo.Handler -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Sample.Menu_Demo.Aux; +with Sample.Manifest; use Sample.Manifest; +with Terminal_Interface.Curses.Mouse; use Terminal_Interface.Curses.Mouse; + +package body Sample.Menu_Demo.Handler is + + package Aux renames Sample.Menu_Demo.Aux; + + procedure Drive_Me (M : in Menu; + Title : in String := "") + is + L : Line_Count; + C : Column_Count; + Y : Line_Position; + X : Column_Position; + begin + Aux.Geometry (M, L, C, Y, X); + Drive_Me (M, Y, X, Title); + end Drive_Me; + + procedure Drive_Me (M : in Menu; + Lin : in Line_Position; + Col : in Column_Position; + Title : in String := "") + is + Mask : Event_Mask := No_Events; + Old : Event_Mask; + Pan : Panel := Aux.Create (M, Title, Lin, Col); + V : Cursor_Visibility := Invisible; + begin + -- We are only interested in Clicks with the left button + Register_Reportable_Events (Left, All_Clicks, Mask); + Old := Start_Mouse (Mask); + Set_Cursor_Visibility (V); + loop + declare + K : Key_Code := Aux.Get_Request (M, Pan); + R : Driver_Result := Driver (M, K); + begin + case R is + when Menu_Ok => null; + when Unknown_Request => + declare + I : constant Item := Current (M); + O : Item_Option_Set; + begin + if K = Key_Mouse then + K := SELECT_ITEM; + end if; + Get_Options (I, O); + if K = SELECT_ITEM and then not O.Selectable then + Beep; + else + if My_Driver (M, K, Pan) then + exit; + end if; + end if; + end; + when others => Beep; + end case; + end; + end loop; + End_Mouse (Old); + Aux.Destroy (M, Pan); + end Drive_Me; + +end Sample.Menu_Demo.Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.ads b/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.ads new file mode 100644 index 0000000..7e58ace --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo-handler.ads @@ -0,0 +1,64 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo.Handler -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; +use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; +use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Menus; +use Terminal_Interface.Curses.Menus; + +generic + with function My_Driver (Men : Menu; + K : Key_Code; + Pan : Panel) return Boolean; +package Sample.Menu_Demo.Handler is + + procedure Drive_Me (M : in Menu; + Lin : in Line_Position; + Col : in Column_Position; + Title : in String := ""); + -- Position the menu at the given point and drive it. + + procedure Drive_Me (M : in Menu; + Title : in String := ""); + -- Center menu and drive it. + +end Sample.Menu_Demo.Handler; diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo.adb b/ncurses-5.2/Ada95/samples/sample-menu_demo.adb new file mode 100644 index 0000000..3a2c21e --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo.adb @@ -0,0 +1,390 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Menus; use Terminal_Interface.Curses.Menus; +with Terminal_Interface.Curses.Menus.Menu_User_Data; +with Terminal_Interface.Curses.Menus.Item_User_Data; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Menu_Demo.Handler; +with Sample.Helpers; use Sample.Helpers; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Menu_Demo is + + package Spacing_Demo is + procedure Spacing_Test; + end Spacing_Demo; + + package body Spacing_Demo is + + procedure Spacing_Test + is + function My_Driver (M : Menu; + K : Key_Code; + P : Panel) return Boolean; + + procedure Set_Option_Key; + procedure Set_Select_Key; + procedure Set_Description_Key; + procedure Set_Hide_Key; + + package Mh is new Sample.Menu_Demo.Handler (My_Driver); + + I : Item_Array_Access := new Item_Array' + (New_Item ("January", "31 Days"), + New_Item ("February", "28/29 Days"), + New_Item ("March", "31 Days"), + New_Item ("April", "30 Days"), + New_Item ("May", "31 Days"), + New_Item ("June", "30 Days"), + New_Item ("July", "31 Days"), + New_Item ("August", "31 Days"), + New_Item ("September", "30 Days"), + New_Item ("October", "31 Days"), + New_Item ("November", "30 Days"), + New_Item ("December", "31 Days"), + Null_Item); + + M : Menu := New_Menu (I); + Flip_State : Boolean := True; + Hide_Long : Boolean := False; + + type Format_Code is (Four_By_1, Four_By_2, Four_By_3); + type Operations is (Flip, Reorder, Reformat, Reselect, Describe); + + type Change is array (Operations) of Boolean; + pragma Pack (Change); + No_Change : constant Change := Change'(others => False); + + Current_Format : Format_Code := Four_By_1; + To_Change : Change := No_Change; + + function My_Driver (M : Menu; + K : Key_Code; + P : Panel) return Boolean + is + begin + To_Change := No_Change; + if K in User_Key_Code'Range then + if K = QUIT then + return True; + end if; + end if; + if K in Special_Key_Code'Range then + case K is + when Key_F4 => + To_Change (Flip) := True; + return True; + when Key_F5 => + To_Change (Reformat) := True; + Current_Format := Four_By_1; + return True; + when Key_F6 => + To_Change (Reformat) := True; + Current_Format := Four_By_2; + return True; + when Key_F7 => + To_Change (Reformat) := True; + Current_Format := Four_By_3; + return True; + when Key_F8 => + To_Change (Reorder) := True; + return True; + when Key_F9 => + To_Change (Reselect) := True; + return True; + when Key_F10 => + if Current_Format /= Four_By_3 then + To_Change (Describe) := True; + return True; + else + return False; + end if; + when Key_F11 => + Hide_Long := not Hide_Long; + declare + O : Item_Option_Set; + begin + for J in I'Range loop + Get_Options (I (J), O); + O.Selectable := True; + if Hide_Long then + case J is + when 1 | 3 | 5 | 7 | 8 | 10 | 12 => + O.Selectable := False; + when others => null; + end case; + end if; + Set_Options (I (J), O); + end loop; + end; + return False; + when others => null; + end case; + end if; + return False; + end My_Driver; + + procedure Set_Option_Key + is + O : Menu_Option_Set; + begin + if Current_Format = Four_By_1 then + Set_Soft_Label_Key (8, ""); + else + Get_Options (M, O); + if O.Row_Major_Order then + Set_Soft_Label_Key (8, "O-Col"); + else + Set_Soft_Label_Key (8, "O-Row"); + end if; + end if; + Refresh_Soft_Label_Keys_Without_Update; + end Set_Option_Key; + + procedure Set_Select_Key + is + O : Menu_Option_Set; + begin + Get_Options (M, O); + if O.One_Valued then + Set_Soft_Label_Key (9, "Multi"); + else + Set_Soft_Label_Key (9, "Singl"); + end if; + Refresh_Soft_Label_Keys_Without_Update; + end Set_Select_Key; + + procedure Set_Description_Key + is + O : Menu_Option_Set; + begin + if Current_Format = Four_By_3 then + Set_Soft_Label_Key (10, ""); + else + Get_Options (M, O); + if O.Show_Descriptions then + Set_Soft_Label_Key (10, "-Desc"); + else + Set_Soft_Label_Key (10, "+Desc"); + end if; + end if; + Refresh_Soft_Label_Keys_Without_Update; + end Set_Description_Key; + + procedure Set_Hide_Key + is + begin + if Hide_Long then + Set_Soft_Label_Key (11, "Enab"); + else + Set_Soft_Label_Key (11, "Disab"); + end if; + Refresh_Soft_Label_Keys_Without_Update; + end Set_Hide_Key; + + begin + Push_Environment ("MENU01"); + Notepad ("MENU-PAD01"); + Default_Labels; + Set_Soft_Label_Key (4, "Flip"); + Set_Soft_Label_Key (5, "4x1"); + Set_Soft_Label_Key (6, "4x2"); + Set_Soft_Label_Key (7, "4x3"); + Set_Option_Key; + Set_Select_Key; + Set_Description_Key; + Set_Hide_Key; + + Set_Format (M, 4, 1); + loop + Mh.Drive_Me (M); + exit when To_Change = No_Change; + if To_Change (Flip) then + if Flip_State then + Flip_State := False; + Set_Spacing (M, 3, 2, 0); + else + Flip_State := True; + Set_Spacing (M); + end if; + elsif To_Change (Reformat) then + case Current_Format is + when Four_By_1 => Set_Format (M, 4, 1); + when Four_By_2 => Set_Format (M, 4, 2); + when Four_By_3 => + declare + O : Menu_Option_Set; + begin + Get_Options (M, O); + O.Show_Descriptions := False; + Set_Options (M, O); + Set_Format (M, 4, 3); + end; + end case; + Set_Option_Key; + Set_Description_Key; + elsif To_Change (Reorder) then + declare + O : Menu_Option_Set; + begin + Get_Options (M, O); + O.Row_Major_Order := not O.Row_Major_Order; + Set_Options (M, O); + Set_Option_Key; + end; + elsif To_Change (Reselect) then + declare + O : Menu_Option_Set; + begin + Get_Options (M, O); + O.One_Valued := not O.One_Valued; + Set_Options (M, O); + Set_Select_Key; + end; + elsif To_Change (Describe) then + declare + O : Menu_Option_Set; + begin + Get_Options (M, O); + O.Show_Descriptions := not O.Show_Descriptions; + Set_Options (M, O); + Set_Description_Key; + end; + else + null; + end if; + end loop; + Set_Spacing (M); + Flip_State := True; + + Pop_Environment; + pragma Assert (Get_Index (Items (M, 1)) = Get_Index (I (1))); + Delete (M); + Free (I, True); + end Spacing_Test; + end Spacing_Demo; + + procedure Demo + is + -- We use this datatype only to test the instantiation of + -- the Menu_User_Data generic package. No functionality + -- behind it. + type User_Data is new Integer; + type User_Data_Access is access User_Data; + + -- Those packages are only instantiated to test the usability. + -- No real functionality is shown in the demo. + package MUD is new Menu_User_Data (User_Data, User_Data_Access); + package IUD is new Item_User_Data (User_Data, User_Data_Access); + + function My_Driver (M : Menu; + K : Key_Code; + P : Panel) return Boolean; + + package Mh is new Sample.Menu_Demo.Handler (My_Driver); + + Itm : Item_Array_Access := new Item_Array' + (New_Item ("Menu Layout Options"), + New_Item ("Demo of Hook functions"), + Null_Item); + M : Menu := New_Menu (Itm); + + U1 : User_Data_Access := new User_Data'(4711); + U2 : User_Data_Access; + U3 : User_Data_Access := new User_Data'(4712); + U4 : User_Data_Access; + + function My_Driver (M : Menu; + K : Key_Code; + P : Panel) return Boolean + is + Idx : constant Positive := Get_Index (Current (M)); + begin + if K in User_Key_Code'Range then + if K = QUIT then + return True; + elsif K = SELECT_ITEM then + if Idx in Itm'Range then + Hide (P); + Update_Panels; + end if; + case Idx is + when 1 => Spacing_Demo.Spacing_Test; + when others => Not_Implemented; + end case; + if Idx in Itm'Range then + Top (P); + Show (P); + Update_Panels; + Update_Screen; + end if; + end if; + end if; + return False; + end My_Driver; + begin + Push_Environment ("MENU00"); + Notepad ("MENU-PAD00"); + Default_Labels; + Refresh_Soft_Label_Keys_Without_Update; + Set_Pad_Character (M, '|'); + + MUD.Set_User_Data (M, U1); + IUD.Set_User_Data (Itm (1), U3); + + Mh.Drive_Me (M); + + MUD.Get_User_Data (M, U2); + pragma Assert (U1 = U2 and U1.all = 4711); + + IUD.Get_User_Data (Itm (1), U4); + pragma Assert (U3 = U4 and U3.all = 4712); + + Pop_Environment; + Delete (M); + Free (Itm, True); + end Demo; + +end Sample.Menu_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-menu_demo.ads b/ncurses-5.2/Ada95/samples/sample-menu_demo.ads new file mode 100644 index 0000000..d147789 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-menu_demo.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Menu_Demo -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Menu_Demo is + + procedure Demo; + +end Sample.Menu_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-my_field_type.adb b/ncurses-5.2/Ada95/samples/sample-my_field_type.adb new file mode 100644 index 0000000..42937a3 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-my_field_type.adb @@ -0,0 +1,65 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.My_Field_Type -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Forms; use Terminal_Interface.Curses.Forms; + +-- This is a very simple user defined field type. It accepts only a +-- defined character as input into the field. +-- +package body Sample.My_Field_Type is + + -- That's simple. There are no field validity checks. + function Field_Check (Fld : Field; + Typ : My_Data) return Boolean + is + begin + return True; + end Field_Check; + + -- Check exactly against the specified character. + function Character_Check (Ch : Character; + Typ : My_Data) return Boolean + is + C : constant Character := Typ.Ch; + begin + return Ch = C; + end Character_Check; + +end Sample.My_Field_Type; diff --git a/ncurses-5.2/Ada95/samples/sample-my_field_type.ads b/ncurses-5.2/Ada95/samples/sample-my_field_type.ads new file mode 100644 index 0000000..d35e475 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-my_field_type.ads @@ -0,0 +1,62 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.My_Field_Type -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Forms; use Terminal_Interface.Curses.Forms; +with Terminal_Interface.Curses.Forms.Field_Types.User; +use Terminal_Interface.Curses.Forms.Field_Types.User; + +-- This is a very simple user defined field type. It accepts only a +-- defined character as input into the field. +-- +package Sample.My_Field_Type is + + type My_Data is new User_Defined_Field_Type with + record + Ch : Character; + end record; + + function Field_Check (Fld : Field; + Typ : My_Data) return Boolean; + + function Character_Check (Ch : Character; + Typ : My_Data) return Boolean; + +end Sample.My_Field_Type; + diff --git a/ncurses-5.2/Ada95/samples/sample-text_io_demo.adb b/ncurses-5.2/Ada95/samples/sample-text_io_demo.adb new file mode 100644 index 0000000..743c161 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-text_io_demo.adb @@ -0,0 +1,180 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Text_IO_Demo -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Numerics.Generic_Elementary_Functions; +with Ada.Numerics.Complex_Types; +use Ada.Numerics.Complex_Types; + +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Text_IO; +use Terminal_Interface.Curses.Text_IO; +with Terminal_Interface.Curses.Text_IO.Integer_IO; +with Terminal_Interface.Curses.Text_IO.Float_IO; +with Terminal_Interface.Curses.Text_IO.Enumeration_IO; +with Terminal_Interface.Curses.Text_IO.Complex_IO; +with Terminal_Interface.Curses.Text_IO.Fixed_IO; +with Terminal_Interface.Curses.Text_IO.Decimal_IO; +with Terminal_Interface.Curses.Text_IO.Modular_IO; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Explanation; use Sample.Explanation; + +package body Sample.Text_IO_Demo is + + type Weekday is (Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday); + + type Fix is delta 0.1 range 0.0 .. 4.0; + type Dec is delta 0.01 digits 5 range 0.0 .. 4.0; + type Md is mod 5; + + package Math is new + Ada.Numerics.Generic_Elementary_Functions (Float); + + package Int_IO is new + Terminal_Interface.Curses.Text_IO.Integer_IO (Integer); + use Int_IO; + + package Real_IO is new + Terminal_Interface.Curses.Text_IO.Float_IO (Float); + use Real_IO; + + package Enum_IO is new + Terminal_Interface.Curses.Text_IO.Enumeration_IO (Weekday); + use Enum_IO; + + package C_IO is new + Terminal_Interface.Curses.Text_IO.Complex_IO (Ada.Numerics.Complex_Types); + use C_IO; + + package F_IO is new + Terminal_Interface.Curses.Text_IO.Fixed_IO (Fix); + use F_IO; + + package D_IO is new + Terminal_Interface.Curses.Text_IO.Decimal_IO (Dec); + use D_IO; + + package M_IO is new + Terminal_Interface.Curses.Text_IO.Modular_IO (Md); + use M_IO; + + procedure Demo + is + W : Window; + P : Panel := Create (Standard_Window); + K : Real_Key_Code; + Im : Complex := (0.0, 1.0); + Fx : Fix := 3.14; + Dc : Dec := 2.72; + L : Md; + + begin + Push_Environment ("TEXTIO"); + Default_Labels; + Notepad ("TEXTIO-PAD00"); + + Set_Echo_Mode (False); + Set_Meta_Mode; + Set_KeyPad_Mode; + W := Sub_Window (Standard_Window, Lines - 2, Columns - 2, 1, 1); + Box; + Refresh_Without_Update; + Set_Meta_Mode (W); + Set_KeyPad_Mode (W); + Immediate_Update_Mode (W, True); + + Set_Window (W); + + for I in 1 .. 10 loop + Put ("Square root of "); + Put (Item => I, Width => 5); + Put (" is "); + Put (Item => Math.Sqrt (Float (I)), Exp => 0, Aft => 7); + New_Line; + end loop; + + for W in Weekday loop + Put (Item => W); Put (' '); + end loop; + New_Line; + + L := Md'First; + for I in 1 .. 2 loop + for J in Md'Range loop + Put (L); Put (' '); + L := L + 1; + end loop; + end loop; + New_Line; + + Put (Im); New_Line; + Put (Fx); New_Line; + Put (Dc); New_Line; + + loop + K := Get_Key; + if K in Special_Key_Code'Range then + case K is + when QUIT_CODE => exit; + when HELP_CODE => Explain_Context; + when EXPLAIN_CODE => Explain ("TEXTIOKEYS"); + when others => null; + end case; + end if; + end loop; + + Set_Window (Null_Window); + Erase; Refresh_Without_Update; + Delete (P); + Delete (W); + + Pop_Environment; + end Demo; + +end Sample.Text_IO_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample-text_io_demo.ads b/ncurses-5.2/Ada95/samples/sample-text_io_demo.ads new file mode 100644 index 0000000..171bc58 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample-text_io_demo.ads @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample.Text_IO_Demo -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample.Text_IO_Demo is + + procedure Demo; + +end Sample.Text_IO_Demo; diff --git a/ncurses-5.2/Ada95/samples/sample.adb b/ncurses-5.2/Ada95/samples/sample.adb new file mode 100644 index 0000000..4dd064d --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample.adb @@ -0,0 +1,218 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Text_IO; + +with Ada.Exceptions; use Ada.Exceptions; + +with Terminal_Interface.Curses; use Terminal_Interface.Curses; +with Terminal_Interface.Curses.Panels; use Terminal_Interface.Curses.Panels; +with Terminal_Interface.Curses.Menus; use Terminal_Interface.Curses.Menus; +with Terminal_Interface.Curses.Menus.Menu_User_Data; +with Terminal_Interface.Curses.Menus.Item_User_Data; + +with Sample.Manifest; use Sample.Manifest; +with Sample.Function_Key_Setting; use Sample.Function_Key_Setting; +with Sample.Keyboard_Handler; use Sample.Keyboard_Handler; +with Sample.Header_Handler; use Sample.Header_Handler; +with Sample.Explanation; use Sample.Explanation; + +with Sample.Menu_Demo.Handler; +with Sample.Curses_Demo; +with Sample.Form_Demo; +with Sample.Menu_Demo; +with Sample.Text_IO_Demo; + +with GNAT.OS_Lib; + +package body Sample is + + type User_Data is + record + Data : Integer; + end record; + type User_Access is access User_Data; + + package Ud is new + Terminal_Interface.Curses.Menus.Menu_User_Data + (User_Data, User_Access); + + package Id is new + Terminal_Interface.Curses.Menus.Item_User_Data + (User_Data, User_Access); + + procedure Whow is + procedure Main_Menu; + procedure Main_Menu + is + function My_Driver (M : Menu; + K : Key_Code; + Pan : Panel) return Boolean; + + package Mh is new Sample.Menu_Demo.Handler (My_Driver); + + I : Item_Array_Access := new Item_Array' + (New_Item ("Curses Core Demo"), + New_Item ("Menu Demo"), + New_Item ("Form Demo"), + New_Item ("Text IO Demo"), + Null_Item); + + M : Menu := New_Menu (I); + + D1, D2 : User_Access; + I1, I2 : User_Access; + + function My_Driver (M : Menu; + K : Key_Code; + Pan : Panel) return Boolean + is + Idx : constant Positive := Get_Index (Current (M)); + begin + if K in User_Key_Code'Range then + if K = QUIT then + return True; + elsif K = SELECT_ITEM then + if Idx in 1 .. 4 then + Hide (Pan); + Update_Panels; + end if; + case Idx is + when 1 => Sample.Curses_Demo.Demo; + when 2 => Sample.Menu_Demo.Demo; + when 3 => Sample.Form_Demo.Demo; + when 4 => Sample.Text_IO_Demo.Demo; + when others => null; + end case; + if Idx in 1 .. 4 then + Top (Pan); + Show (Pan); + Update_Panels; + Update_Screen; + end if; + end if; + end if; + return False; + end My_Driver; + + begin + + if (1 + Item_Count (M)) /= I'Length then + raise Constraint_Error; + end if; + + D1 := new User_Data'(Data => 4711); + Ud.Set_User_Data (M, D1); + + I1 := new User_Data'(Data => 1174); + Id.Set_User_Data (I (1), I1); + + Set_Spacing (Men => M, Row => 2); + + Default_Labels; + Notepad ("MAINPAD"); + + Mh.Drive_Me (M, " Demo "); + + Ud.Get_User_Data (M, D2); + pragma Assert (D1 = D2); + pragma Assert (D1.Data = D2.Data); + + Id.Get_User_Data (I (1), I2); + pragma Assert (I1 = I2); + pragma Assert (I1.Data = I2.Data); + + Delete (M); + Free (I, True); + end Main_Menu; + + begin + Initialize (PC_Style_With_Index); + Init_Header_Handler; + Init_Screen; + + if Has_Colors then + Start_Color; + + Init_Pair (Pair => Default_Colors, Fore => Black, Back => White); + Init_Pair (Pair => Menu_Back_Color, Fore => Black, Back => Cyan); + Init_Pair (Pair => Menu_Fore_Color, Fore => Red, Back => Cyan); + Init_Pair (Pair => Menu_Grey_Color, Fore => White, Back => Cyan); + Init_Pair (Pair => Notepad_Color, Fore => Black, Back => Yellow); + Init_Pair (Pair => Help_Color, Fore => Blue, Back => Cyan); + Init_Pair (Pair => Form_Back_Color, Fore => Black, Back => Cyan); + Init_Pair (Pair => Form_Fore_Color, Fore => Red, Back => Cyan); + Init_Pair (Pair => Header_Color, Fore => Black, Back => Green); + + Set_Background (Ch => (Color => Default_Colors, + Attr => Normal_Video, + Ch => ' ')); + Set_Character_Attributes (Attr => Normal_Video, + Color => Default_Colors); + Erase; + + Set_Soft_Label_Key_Attributes (Color => Header_Color); + -- This propagates the attributes to the label window + Clear_Soft_Label_Keys; Restore_Soft_Label_Keys; + end if; + + Init_Keyboard_Handler; + + Set_Echo_Mode (False); + Set_Raw_Mode; + Set_Meta_Mode; + Set_KeyPad_Mode; + + -- Initialize the Function Key Environment + -- We have some fixed key throughout this sample + Main_Menu; + End_Windows; + + exception + when Event : others => + Terminal_Interface.Curses.End_Windows; + Text_IO.Put ("Exception: "); + Text_IO.Put (Exception_Name (Event)); + Text_IO.New_Line; + GNAT.OS_Lib.OS_Exit (1); + + end Whow; + +end Sample; diff --git a/ncurses-5.2/Ada95/samples/sample.ads b/ncurses-5.2/Ada95/samples/sample.ads new file mode 100644 index 0000000..7558876 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/sample.ads @@ -0,0 +1,43 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Sample -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Sample is + procedure Whow; +end Sample; diff --git a/ncurses-5.2/Ada95/samples/status.adb b/ncurses-5.2/Ada95/samples/status.adb new file mode 100644 index 0000000..0bdbad2 --- /dev/null +++ b/ncurses-5.2/Ada95/samples/status.adb @@ -0,0 +1,56 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Status -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- This package has been contributed by Laurent Pautet -- +-- -- +package body Status is + + protected body Process is + procedure Stop is + begin + Done := True; + end Stop; + function Continue return Boolean is + begin + return not Done; + end Continue; + end Process; + +end Status; diff --git a/ncurses-5.2/Ada95/samples/status.ads b/ncurses-5.2/Ada95/samples/status.ads new file mode 100644 index 0000000..90e1a1b --- /dev/null +++ b/ncurses-5.2/Ada95/samples/status.ads @@ -0,0 +1,59 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Status -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- This package has been contributed by Laurent Pautet -- +-- -- +with Ada.Interrupts.Names; + +package Status is + + pragma Warnings (Off); -- the next pragma exists since 3.11p + pragma Unreserve_All_Interrupts; + pragma Warnings (On); + + protected Process is + procedure Stop; + function Continue return Boolean; + pragma Attach_Handler (Stop, Ada.Interrupts.Names.SIGINT); + private + Done : Boolean := False; + end Process; + +end Status; diff --git a/ncurses-5.2/Ada95/samples/tour.adb b/ncurses-5.2/Ada95/samples/tour.adb new file mode 100644 index 0000000..2398b6e --- /dev/null +++ b/ncurses-5.2/Ada95/samples/tour.adb @@ -0,0 +1,46 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- tour -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Sample; use Sample; + +procedure Tour is +begin + Whow; +end Tour; diff --git a/ncurses-5.2/Ada95/samples/tour.ads b/ncurses-5.2/Ada95/samples/tour.ads new file mode 100644 index 0000000..4eea20b --- /dev/null +++ b/ncurses-5.2/Ada95/samples/tour.ads @@ -0,0 +1,41 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding Samples -- +-- -- +-- Tour -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +procedure Tour; diff --git a/ncurses-5.2/Ada95/src/Makefile.in b/ncurses-5.2/Ada95/src/Makefile.in new file mode 100644 index 0000000..cd8e546 --- /dev/null +++ b/ncurses-5.2/Ada95/src/Makefile.in @@ -0,0 +1,352 @@ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Juergen Pfeifer 1996 +# +# Version Control +# $Revision$ +# +.SUFFIXES: + +SHELL = /bin/sh +THIS = Makefile + +MODEL = ../../@DFT_OBJ_SUBDIR@ +DESTDIR = @DESTDIR@ +srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +ADA_INCLUDE = @ADA_INCLUDE@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +AR = @AR@ +AR_OPTS = @AR_OPTS@ +AWK = @AWK@ +LN_S = @LN_S@ + +CC = @CC@ +CFLAGS = @CFLAGS@ + +CPPFLAGS = @ACPPFLAGS@ \ + -DHAVE_CONFIG_H -I$(srcdir) + +CCFLAGS = $(CPPFLAGS) $(CFLAGS) + +CFLAGS_NORMAL = $(CCFLAGS) +CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE +CFLAGS_PROFILE = $(CCFLAGS) -pg +CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@ + +CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@) + +LINK = $(CC) +LDFLAGS = @LDFLAGS@ @LD_MODEL@ @LIBS@ + +RANLIB = @RANLIB@ +################################################################################ +ADA = @cf_ada_compiler@ +ADAFLAGS = @ADAFLAGS@ -I. -I$(srcdir) + +ADAMAKE = @cf_ada_make@ +ADAMAKEFLAGS = + +CARGS = -cargs $(ADAFLAGS) +LARGS = + +ALIB = @cf_ada_package@ +ABASE = $(ALIB)-curses + +LIBALIS=$(ALIB).ali \ + $(ABASE)-aux.ali \ + $(ABASE).ali \ + $(ABASE)-mouse.ali \ + $(ABASE)-panels.ali \ + $(ABASE)-menus.ali \ + $(ABASE)-forms.ali \ + $(ABASE)-forms-field_types.ali \ + $(ABASE)-forms-field_types-alpha.ali \ + $(ABASE)-forms-field_types-alphanumeric.ali \ + $(ABASE)-forms-field_types-intfield.ali \ + $(ABASE)-forms-field_types-numeric.ali \ + $(ABASE)-forms-field_types-regexp.ali \ + $(ABASE)-forms-field_types-enumeration.ali \ + $(ABASE)-forms-field_types-ipv4_address.ali \ + $(ABASE)-forms-field_types-user.ali \ + $(ABASE)-forms-field_types-user-choice.ali \ + $(ABASE)-text_io.ali \ + $(ABASE)-text_io-aux.ali + +# Ada Library files for generic packages. Since gnat 3.10 they are +# also compiled +GENALIS=$(ABASE)-menus-menu_user_data.ali \ + $(ABASE)-menus-item_user_data.ali \ + $(ABASE)-forms-form_user_data.ali \ + $(ABASE)-forms-field_user_data.ali \ + $(ABASE)-forms-field_types-enumeration-ada.ali \ + $(ABASE)-panels-user_data.ali \ + $(ABASE)-text_io-integer_io.ali \ + $(ABASE)-text_io-float_io.ali \ + $(ABASE)-text_io-fixed_io.ali \ + $(ABASE)-text_io-decimal_io.ali \ + $(ABASE)-text_io-enumeration_io.ali \ + $(ABASE)-text_io-modular_io.ali \ + $(ABASE)-text_io-complex_io.ali + +LIBOBJS=$(ALIB).o \ + $(ABASE)-aux.o \ + $(ABASE).o \ + $(ABASE)-mouse.o \ + $(ABASE)-panels.o \ + $(ABASE)-menus.o \ + $(ABASE)-forms.o \ + $(ABASE)-forms-field_types.o \ + $(ABASE)-forms-field_types-alpha.o \ + $(ABASE)-forms-field_types-alphanumeric.o \ + $(ABASE)-forms-field_types-intfield.o \ + $(ABASE)-forms-field_types-numeric.o \ + $(ABASE)-forms-field_types-regexp.o \ + $(ABASE)-forms-field_types-enumeration.o \ + $(ABASE)-forms-field_types-ipv4_address.o \ + $(ABASE)-forms-field_types-user.o \ + $(ABASE)-forms-field_types-user-choice.o \ + $(ABASE)-text_io.o \ + $(ABASE)-text_io-aux.o + +# Ada object files for generic packages. Since gnat 3.10 they are +# also compiled +GENOBJS=$(ABASE)-menus-menu_user_data.o \ + $(ABASE)-menus-item_user_data.o \ + $(ABASE)-forms-form_user_data.o \ + $(ABASE)-forms-field_user_data.o \ + $(ABASE)-forms-field_types-enumeration-ada.o \ + $(ABASE)-panels-user_data.o \ + $(ABASE)-text_io-integer_io.o \ + $(ABASE)-text_io-float_io.o \ + $(ABASE)-text_io-fixed_io.o \ + $(ABASE)-text_io-decimal_io.o \ + $(ABASE)-text_io-enumeration_io.o \ + $(ABASE)-text_io-modular_io.o \ + $(ABASE)-text_io-complex_io.o + + +all :: libAdaCurses.a + @echo done + +libAdaCurses.a :: dotouch $(LIBOBJS) @cf_generic_objects@ + $(AR) $(AR_OPTS) $@ $(LIBOBJS) @cf_generic_objects@ + +dotouch : + @sh -c 'for f in $(LIBALIS) $(GENALIS); do test -f $$f || touch $$f; done' + +sources : + @ + +libs \ +install \ +install.libs \ +uninstall \ +uninstall.libs :: + @ + +generics: $(GENALIS) + @ + +mostlyclean :: + rm -f *.o *.ali b_t*.* *.s $(PROGS) a.out core b_*_test.c *.xr[bs] *.a + +clean :: mostlyclean + rm -f $(LIBALIS) $(GENALIS) $(LIBOBJS) $(GENOBJS) + +distclean :: clean + rm -f Makefile + +realclean :: distclean + +BASEDEPS=$(ABASE).ads $(ABASE)-aux.ads $(srcdir)/$(ABASE).adb + +$(ALIB).o: $(srcdir)/$(ALIB).ads + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ALIB).ads + + +$(ABASE)-aux.o: $(srcdir)/$(ABASE)-aux.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-aux.adb + + +$(ABASE).o: $(srcdir)/$(ABASE).adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE).adb + + +$(ABASE)-mouse.o: \ + $(ABASE)-mouse.ads \ + $(srcdir)/$(ABASE)-mouse.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-mouse.adb + + +$(ABASE)-panels.o: \ + $(ABASE)-panels.ads \ + $(srcdir)/$(ABASE)-panels.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-panels.adb + + +$(ABASE)-menus.o: \ + $(ABASE)-menus.ads \ + $(srcdir)/$(ABASE)-menus.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-menus.adb + + +$(ABASE)-forms.o: \ + $(ABASE)-forms.ads \ + $(srcdir)/$(ABASE)-forms.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms.adb + +$(ABASE)-forms-field_types.o: \ + $(ABASE)-forms-field_types.ads \ + $(srcdir)/$(ABASE)-forms-field_types.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types.adb + +$(ABASE)-forms-field_types-alpha.o: \ + $(srcdir)/$(ABASE)-forms-field_types-alpha.ads \ + $(srcdir)/$(ABASE)-forms-field_types-alpha.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-alpha.adb + +$(ABASE)-forms-field_types-alphanumeric.o: \ + $(srcdir)/$(ABASE)-forms-field_types-alphanumeric.ads \ + $(srcdir)/$(ABASE)-forms-field_types-alphanumeric.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-alphanumeric.adb + +$(ABASE)-forms-field_types-intfield.o: \ + $(srcdir)/$(ABASE)-forms-field_types-intfield.ads \ + $(srcdir)/$(ABASE)-forms-field_types-intfield.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-intfield.adb + +$(ABASE)-forms-field_types-numeric.o: \ + $(srcdir)/$(ABASE)-forms-field_types-numeric.ads \ + $(srcdir)/$(ABASE)-forms-field_types-numeric.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-numeric.adb + +$(ABASE)-forms-field_types-regexp.o: \ + $(srcdir)/$(ABASE)-forms-field_types-regexp.ads \ + $(srcdir)/$(ABASE)-forms-field_types-regexp.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-regexp.adb + +$(ABASE)-forms-field_types-enumeration.o: \ + $(srcdir)/$(ABASE)-forms-field_types-enumeration.ads \ + $(srcdir)/$(ABASE)-forms-field_types-enumeration.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-enumeration.adb + +$(ABASE)-forms-field_types-ipv4_address.o: \ + $(srcdir)/$(ABASE)-forms-field_types-ipv4_address.ads \ + $(srcdir)/$(ABASE)-forms-field_types-ipv4_address.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-ipv4_address.adb + +$(ABASE)-forms-field_types-user.o: \ + $(srcdir)/$(ABASE)-forms-field_types-user.ads \ + $(srcdir)/$(ABASE)-forms-field_types-user.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-user.adb + +$(ABASE)-forms-field_types-user-choice.o: \ + $(srcdir)/$(ABASE)-forms-field_types-user-choice.ads \ + $(srcdir)/$(ABASE)-forms-field_types-user-choice.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-user-choice.adb + +$(ABASE)-text_io.o: \ + $(srcdir)/$(ABASE)-text_io.ads \ + $(srcdir)/$(ABASE)-text_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io.adb + +$(ABASE)-text_io-aux.o: \ + $(srcdir)/$(ABASE)-text_io-aux.ads \ + $(srcdir)/$(ABASE)-text_io-aux.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-aux.adb + +$(ABASE)-menus-menu_user_data.o: \ + $(ABASE)-menus-menu_user_data.ads \ + $(srcdir)/$(ABASE)-menus-menu_user_data.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-menus-menu_user_data.adb + +$(ABASE)-menus-item_user_data.o: \ + $(ABASE)-menus-item_user_data.ads \ + $(srcdir)/$(ABASE)-menus-item_user_data.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-menus-item_user_data.adb + +$(ABASE)-forms-form_user_data.o: \ + $(ABASE)-forms-form_user_data.ads \ + $(srcdir)/$(ABASE)-forms-form_user_data.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-form_user_data.adb + +$(ABASE)-forms-field_user_data.o: \ + $(ABASE)-forms-field_user_data.ads \ + $(srcdir)/$(ABASE)-forms-field_user_data.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_user_data.adb + +$(ABASE)-forms-field_types-enumeration-ada.o: \ + $(srcdir)/$(ABASE)-forms-field_types-enumeration-ada.ads \ + $(srcdir)/$(ABASE)-forms-field_types-enumeration-ada.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-forms-field_types-enumeration-ada.adb + +$(ABASE)-panels-user_data.o: \ + $(ABASE)-panels-user_data.ads \ + $(srcdir)/$(ABASE)-panels-user_data.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-panels-user_data.adb + +$(ABASE)-text_io-integer_io.o: \ + $(srcdir)/$(ABASE)-text_io-integer_io.ads \ + $(srcdir)/$(ABASE)-text_io-integer_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-integer_io.adb + +$(ABASE)-text_io-float_io.o: \ + $(srcdir)/$(ABASE)-text_io-float_io.ads \ + $(srcdir)/$(ABASE)-text_io-float_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-float_io.adb + +$(ABASE)-text_io-fixed_io.o: \ + $(srcdir)/$(ABASE)-text_io-fixed_io.ads \ + $(srcdir)/$(ABASE)-text_io-fixed_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-fixed_io.adb + +$(ABASE)-text_io-decimal_io.o: \ + $(srcdir)/$(ABASE)-text_io-decimal_io.ads \ + $(srcdir)/$(ABASE)-text_io-decimal_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-decimal_io.adb + +$(ABASE)-text_io-enumeration_io.o: \ + $(srcdir)/$(ABASE)-text_io-enumeration_io.ads \ + $(srcdir)/$(ABASE)-text_io-enumeration_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-enumeration_io.adb + +$(ABASE)-text_io-modular_io.o: \ + $(srcdir)/$(ABASE)-text_io-modular_io.ads \ + $(srcdir)/$(ABASE)-text_io-modular_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-modular_io.adb + +$(ABASE)-text_io-complex_io.o: \ + $(srcdir)/$(ABASE)-text_io-complex_io.ads \ + $(srcdir)/$(ABASE)-text_io-complex_io.adb $(BASEDEPS) + $(ADA) $(ADAFLAGS) -c -o $@ $(srcdir)/$(ABASE)-text_io-complex_io.adb diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-aux.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-aux.adb new file mode 100644 index 0000000..aa8cc76 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-aux.adb @@ -0,0 +1,116 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Aux -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package body Terminal_Interface.Curses.Aux is + -- + -- Some helpers + procedure Fill_String (Cp : in chars_ptr; + Str : out String) + is + -- Fill the string with the characters referenced by the + -- chars_ptr. + -- + Len : Natural; + begin + if Cp /= Null_Ptr then + Len := Natural (Strlen (Cp)); + if Str'Length < Len then + raise Constraint_Error; + end if; + declare + S : String (1 .. Len); + begin + S := Value (Cp); + Str (Str'First .. (Str'First + Len - 1)) := S (S'Range); + end; + else + Len := 0; + end if; + + if Len < Str'Length then + Str ((Str'First + Len) .. Str'Last) := (others => ' '); + end if; + + end Fill_String; + + function Fill_String (Cp : chars_ptr) return String + is + Len : Natural; + begin + if Cp /= Null_Ptr then + Len := Natural (Strlen (Cp)); + if Len = 0 then + return ""; + else + declare + S : String (1 .. Len); + begin + Fill_String (Cp, S); + return S; + end; + end if; + else + return ""; + end if; + end Fill_String; + + procedure Eti_Exception (Code : Eti_Error) + is + begin + case Code is + when E_Ok => null; + when E_System_Error => raise Eti_System_Error; + when E_Bad_Argument => raise Eti_Bad_Argument; + when E_Posted => raise Eti_Posted; + when E_Connected => raise Eti_Connected; + when E_Bad_State => raise Eti_Bad_State; + when E_No_Room => raise Eti_No_Room; + when E_Not_Posted => raise Eti_Not_Posted; + when E_Unknown_Command => raise Eti_Unknown_Command; + when E_No_Match => raise Eti_No_Match; + when E_Not_Selectable => raise Eti_Not_Selectable; + when E_Not_Connected => raise Eti_Not_Connected; + when E_Request_Denied => raise Eti_Request_Denied; + when E_Invalid_Field => raise Eti_Invalid_Field; + when E_Current => raise Eti_Current; + end case; + end Eti_Exception; + +end Terminal_Interface.Curses.Aux; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb new file mode 100644 index 0000000..c7a64f7 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Alpha -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.Alpha is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Alpha_Field) + is + C_Alpha_Field_Type : C_Field_Type; + pragma Import (C, C_Alpha_Field_Type, "TYPE_ALPHA"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_Alpha_Field_Type; + Arg1 : C_Int) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + Res := Set_Fld_Type (Arg1 => C_Int (Typ.Minimum_Field_Width)); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.Alpha; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads new file mode 100644 index 0000000..f869c0b --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads @@ -0,0 +1,53 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Alpha -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.Alpha is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types.Alpha); + + type Alpha_Field is new Field_Type + with record + Minimum_Field_Width : Natural := 0; + end record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Alpha_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.Alpha; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb new file mode 100644 index 0000000..3684b8a --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in AlphaNumeric_Field) + is + C_AlphaNumeric_Field_Type : C_Field_Type; + pragma Import (C, C_AlphaNumeric_Field_Type, "TYPE_ALNUM"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_AlphaNumeric_Field_Type; + Arg1 : C_Int) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + Res := Set_Fld_Type (Arg1 => C_Int (Typ.Minimum_Field_Width)); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads new file mode 100644 index 0000000..2e174d6 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads @@ -0,0 +1,54 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric is + pragma Preelaborate + (Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric); + + type AlphaNumeric_Field is new Field_Type + with record + Minimum_Field_Width : Natural := 0; + end record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in AlphaNumeric_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.AlphaNumeric; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb new file mode 100644 index 0000000..c8ffe58 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb @@ -0,0 +1,80 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Characters.Handling; use Ada.Characters.Handling; + +package body Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada is + + function Create (Set : Type_Set := Mixed_Case; + Case_Sensitive : Boolean := False; + Must_Be_Unique : Boolean := False) + return Enumeration_Field + is + I : Enumeration_Info (T'Pos (T'Last) - T'Pos (T'First) + 1); + J : Positive := 1; + begin + I.Case_Sensitive := Case_Sensitive; + I.Match_Must_Be_Unique := Must_Be_Unique; + + for E in T'Range loop + I.Names (J) := new String'(T'Image (T (E))); + -- The Image attribute defaults to upper case, so we have to handle + -- only the other ones... + if Set /= Upper_Case then + I.Names (J).all := To_Lower (I.Names (J).all); + if Set = Mixed_Case then + I.Names (J)(I.Names (J).all'First) := + To_Upper (I.Names (J)(I.Names (J).all'First)); + end if; + end if; + J := J + 1; + end loop; + + return Create (I, True); + end Create; + + function Value (Fld : Field; + Buf : Buffer_Number := Buffer_Number'First) return T + is + begin + return T'Value (Get_Buffer (Fld, Buf)); + end Value; + +end Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads new file mode 100644 index 0000000..6b01c26 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads @@ -0,0 +1,59 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type T is (<>); + +package Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada is + pragma Preelaborate + (Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada); + + function Create (Set : Type_Set := Mixed_Case; + Case_Sensitive : Boolean := False; + Must_Be_Unique : Boolean := False) + return Enumeration_Field; + + function Value (Fld : Field; + Buf : Buffer_Number := Buffer_Number'First) return T; + -- Translate the content of the fields buffer - indicated by the + -- buffer number - into an enumeration value. If the buffer is empty + -- or the content is invalid, a Constraint_Error is raises. + +end Terminal_Interface.Curses.Forms.Field_Types.Enumeration.Ada; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb new file mode 100644 index 0000000..fccb4f3 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb @@ -0,0 +1,119 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Enumeration -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Deallocation; +with Interfaces.C; use Interfaces.C; +with Interfaces.C.Strings; use Interfaces.C.Strings; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.Enumeration is + + function Create (Info : Enumeration_Info; + Auto_Release_Names : Boolean := False) + return Enumeration_Field + is + procedure Release_String is + new Ada.Unchecked_Deallocation (String, + String_Access); + E : Enumeration_Field; + L : constant size_t := 1 + size_t (Info.C); + S : String_Access; + begin + E.Case_Sensitive := Info.Case_Sensitive; + E.Match_Must_Be_Unique := Info.Match_Must_Be_Unique; + E.Arr := new chars_ptr_array (size_t (1) .. L); + for I in 1 .. Positive (L - 1) loop + if Info.Names (I) = null then + raise Form_Exception; + end if; + E.Arr (size_t (I)) := New_String (Info.Names (I).all); + if Auto_Release_Names then + S := Info.Names (I); + Release_String (S); + end if; + end loop; + E.Arr (L) := Null_Ptr; + return E; + end Create; + + procedure Release (Enum : in out Enumeration_Field) + is + I : size_t := 0; + P : chars_ptr; + begin + loop + P := Enum.Arr (I); + exit when P = Null_Ptr; + Free (P); + Enum.Arr (I) := Null_Ptr; + I := I + 1; + end loop; + Enum.Arr := null; + end Release; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Enumeration_Field) + is + C_Enum_Type : C_Field_Type; + pragma Import (C, C_Enum_Type, "TYPE_ENUM"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_Enum_Type; + Arg1 : chars_ptr_array; + Arg2 : C_Int; + Arg3 : C_Int) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + if Typ.Arr = null then + raise Form_Exception; + end if; + Res := Set_Fld_Type (Arg1 => Typ.Arr.all, + Arg2 => C_Int (Boolean'Pos (Typ.Case_Sensitive)), + Arg3 => C_Int (Boolean'Pos + (Typ.Match_Must_Be_Unique))); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ, C_Choice_Router); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.Enumeration; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads new file mode 100644 index 0000000..d3d54b8 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads @@ -0,0 +1,98 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Enumeration -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C.Strings; + +package Terminal_Interface.Curses.Forms.Field_Types.Enumeration is + pragma Preelaborate + (Terminal_Interface.Curses.Forms.Field_Types.Enumeration); + + type String_Access is access String; + + -- Type_Set is used by the child package Ada + type Type_Set is (Lower_Case, Upper_Case, Mixed_Case); + + type Enum_Array is array (Positive range <>) + of String_Access; + + type Enumeration_Info (C : Positive) is + record + Names : Enum_Array (1 .. C); + Case_Sensitive : Boolean := False; + Match_Must_Be_Unique : Boolean := False; + end record; + + type Enumeration_Field is new Field_Type with private; + + function Create (Info : Enumeration_Info; + Auto_Release_Names : Boolean := False) + return Enumeration_Field; + -- Make an fieldtype from the info. Enumerations are special, because + -- they normally don't copy the enum values into a private store, so + -- we have to care for the lifetime of the info we provide. + -- The Auto_Release_Names flag may be used to automatically releases + -- the strings in the Names array of the Enumeration_Info. + + function Make_Enumeration_Type (Info : Enumeration_Info; + Auto_Release_Names : Boolean := False) + return Enumeration_Field renames Create; + + procedure Release (Enum : in out Enumeration_Field); + -- But we may want to release the field to release the memory allocated + -- by it internally. After that the Enumeration field is no longer usable. + + -- The next type defintions are all ncurses extensions. They are typically + -- not available in other curses implementations. + + procedure Set_Field_Type (Fld : in Field; + Typ : in Enumeration_Field); + pragma Inline (Set_Field_Type); + +private + type CPA_Access is access Interfaces.C.Strings.chars_ptr_array; + + type Enumeration_Field is new Field_Type with + record + Case_Sensitive : Boolean := False; + Match_Must_Be_Unique : Boolean := False; + Arr : CPA_Access := null; + end record; + +end Terminal_Interface.Curses.Forms.Field_Types.Enumeration; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb new file mode 100644 index 0000000..4607a78 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb @@ -0,0 +1,72 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.IntField -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.IntField is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Integer_Field) + is + C_Integer_Field_Type : C_Field_Type; + pragma Import (C, C_Integer_Field_Type, "TYPE_INTEGER"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_Integer_Field_Type; + Arg1 : C_Int; + Arg2 : C_Long_Int; + Arg3 : C_Long_Int) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + Res := Set_Fld_Type (Arg1 => C_Int (Typ.Precision), + Arg2 => C_Long_Int (Typ.Lower_Limit), + Arg3 => C_Long_Int (Typ.Upper_Limit)); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.IntField; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads new file mode 100644 index 0000000..4ab7903 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.IntField -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.IntField is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types.IntField); + + type Integer_Field is new Field_Type with + record + Precision : Natural; + Lower_Limit : Integer; + Upper_Limit : Integer; + end record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Integer_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.IntField; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb new file mode 100644 index 0000000..b5ec33a --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Internet_V4_Address_Field) + is + C_IPV4_Field_Type : C_Field_Type; + pragma Import (C, C_IPV4_Field_Type, "TYPE_IPV4"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_IPV4_Field_Type) + return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + Res := Set_Fld_Type; + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads new file mode 100644 index 0000000..2f91980 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads @@ -0,0 +1,51 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address is + pragma Preelaborate + (Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address); + + type Internet_V4_Address_Field is new Field_Type with null record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Internet_V4_Address_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.IPV4_Address; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb new file mode 100644 index 0000000..4d172f1 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb @@ -0,0 +1,74 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Numeric -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.Numeric is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Numeric_Field) + is + type Double is new Interfaces.C.double; + + C_Numeric_Field_Type : C_Field_Type; + pragma Import (C, C_Numeric_Field_Type, "TYPE_NUMERIC"); + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_Numeric_Field_Type; + Arg1 : C_Int; + Arg2 : Double; + Arg3 : Double) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + begin + Res := Set_Fld_Type (Arg1 => C_Int (Typ.Precision), + Arg2 => Double (Typ.Lower_Limit), + Arg3 => Double (Typ.Upper_Limit)); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.Numeric; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads new file mode 100644 index 0000000..0bcf03c --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.Numeric -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.Numeric is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types.Numeric); + + type Numeric_Field is new Field_Type with + record + Precision : Natural; + Lower_Limit : Float; + Upper_Limit : Float; + end record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Numeric_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.Numeric; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb new file mode 100644 index 0000000..f377e95 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb @@ -0,0 +1,71 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.RegExp -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; use Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.RegExp is + + procedure Set_Field_Type (Fld : in Field; + Typ : in Regular_Expression_Field) + is + type Char_Ptr is access all Interfaces.C.char; + + C_Regexp_Field_Type : C_Field_Type; + pragma Import (C, C_Regexp_Field_Type, "TYPE_REGEXP"); + + function Set_Ftyp (F : Field := Fld; + Cft : C_Field_Type := C_Regexp_Field_Type; + Arg1 : Char_Ptr) return C_Int; + pragma Import (C, Set_Ftyp, "set_field_type"); + + Txt : char_array (0 .. Typ.Regular_Expression.all'Length); + Len : size_t; + Res : Eti_Error; + begin + To_C (Typ.Regular_Expression.all, Txt, Len); + Res := Set_Ftyp (Arg1 => Txt (Txt'First)'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Wrap_Builtin (Fld, Typ); + end Set_Field_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.RegExp; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads new file mode 100644 index 0000000..ce4c883 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.RegExp -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface.Curses.Forms.Field_Types.RegExp is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types.RegExp); + + type String_Access is access String; + + type Regular_Expression_Field is new Field_Type with + record + Regular_Expression : String_Access; + end record; + + procedure Set_Field_Type (Fld : in Field; + Typ : in Regular_Expression_Field); + pragma Inline (Set_Field_Type); + +end Terminal_Interface.Curses.Forms.Field_Types.RegExp; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb new file mode 100644 index 0000000..4f8d058 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.User.Choice -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Conversion; +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.User.Choice is + + use type Interfaces.C.int; + + function To_Argument_Access is new Ada.Unchecked_Conversion + (System.Address, Argument_Access); + + function Generic_Next (Fld : Field; + Usr : System.Address) return C_Int + is + Result : Boolean; + Udf : User_Defined_Field_Type_With_Choice_Access := + User_Defined_Field_Type_With_Choice_Access + (To_Argument_Access (Usr).Typ); + begin + Result := Next (Fld, Udf.all); + return C_Int (Boolean'Pos (Result)); + end Generic_Next; + + function Generic_Prev (Fld : Field; + Usr : System.Address) return C_Int + is + Result : Boolean; + Udf : User_Defined_Field_Type_With_Choice_Access := + User_Defined_Field_Type_With_Choice_Access + (To_Argument_Access (Usr).Typ); + begin + Result := Previous (Fld, Udf.all); + return C_Int (Boolean'Pos (Result)); + end Generic_Prev; + + -- ----------------------------------------------------------------------- + -- + function C_Generic_Choice return C_Field_Type + is + Res : Eti_Error; + T : C_Field_Type; + begin + if M_Generic_Choice = Null_Field_Type then + T := New_Fieldtype (Generic_Field_Check'Access, + Generic_Char_Check'Access); + if T = Null_Field_Type then + raise Form_Exception; + else + Res := Set_Fieldtype_Arg (T, + Make_Arg'Access, + Copy_Arg'Access, + Free_Arg'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + + Res := Set_Fieldtype_Choice (T, + Generic_Next'Access, + Generic_Prev'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + M_Generic_Choice := T; + end if; + pragma Assert (M_Generic_Choice /= Null_Field_Type); + return M_Generic_Choice; + end C_Generic_Choice; + +end Terminal_Interface.Curses.Forms.Field_Types.User.Choice; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads new file mode 100644 index 0000000..9f1ba10 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.User.Choice -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; + +package Terminal_Interface.Curses.Forms.Field_Types.User.Choice is + pragma Preelaborate + (Terminal_Interface.Curses.Forms.Field_Types.User.Choice); + + use type Interfaces.C.int; + subtype C_Int is Interfaces.C.int; + + type User_Defined_Field_Type_With_Choice is abstract new + User_Defined_Field_Type with null record; + -- This is the root of the mechanism we use to create field types in + -- Ada95 that allow the prev/next mechanism. You should your own type + -- derive from this one and implement the Field_Check, Character_Check + -- Next and Previous functions for your own type. + + type User_Defined_Field_Type_With_Choice_Access is access all + User_Defined_Field_Type_With_Choice'Class; + + function Next + (Fld : Field; + Typ : User_Defined_Field_Type_With_Choice) return Boolean + is abstract; + -- If True is returned, the function successfully generated a next + -- value into the fields buffer. + + function Previous + (Fld : Field; + Typ : User_Defined_Field_Type_With_Choice) return Boolean + is abstract; + -- If True is returned, the function successfully generated a previous + -- value into the fields buffer. + + -- +---------------------------------------------------------------------- + -- | Private Part. + -- | +private + use type Interfaces.C.int; + + function C_Generic_Choice return C_Field_Type; + + function Generic_Next (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Generic_Next); + -- This is the generic next Choice_Function for the low-level fieldtype + -- representing all the User_Defined_Field_Type derivates. It routes + -- the call to the Next implementation for the type. + + function Generic_Prev (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Generic_Prev); + -- This is the generic prev Choice_Function for the low-level fieldtype + -- representing all the User_Defined_Field_Type derivates. It routes + -- the call to the Previous implementation for the type. + +end Terminal_Interface.Curses.Forms.Field_Types.User.Choice; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.adb new file mode 100644 index 0000000..b011c5f --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.adb @@ -0,0 +1,132 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.User -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Conversion; +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Field_Types.User is + + use type Interfaces.C.int; + + procedure Set_Field_Type (Fld : in Field; + Typ : in User_Defined_Field_Type) + is + function Allocate_Arg (T : User_Defined_Field_Type'Class) + return Argument_Access; + + function Set_Fld_Type (F : Field := Fld; + Cft : C_Field_Type := C_Generic_Type; + Arg1 : Argument_Access) + return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + Res : Eti_Error; + + function Allocate_Arg (T : User_Defined_Field_Type'Class) + return Argument_Access + is + Ptr : Field_Type_Access := new User_Defined_Field_Type'Class'(T); + begin + return new Argument'(Usr => System.Null_Address, + Typ => Ptr, + Cft => Null_Field_Type); + end Allocate_Arg; + + begin + Res := Set_Fld_Type (Arg1 => Allocate_Arg (Typ)); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Field_Type; + + function To_Argument_Access is new Ada.Unchecked_Conversion + (System.Address, Argument_Access); + + function Generic_Field_Check (Fld : Field; + Usr : System.Address) return C_Int + is + Result : Boolean; + Udf : User_Defined_Field_Type_Access := + User_Defined_Field_Type_Access (To_Argument_Access (Usr).Typ); + begin + Result := Field_Check (Fld, Udf.all); + return C_Int (Boolean'Pos (Result)); + end Generic_Field_Check; + + function Generic_Char_Check (Ch : C_Int; + Usr : System.Address) return C_Int + is + Result : Boolean; + Udf : User_Defined_Field_Type_Access := + User_Defined_Field_Type_Access (To_Argument_Access (Usr).Typ); + begin + Result := Character_Check (Character'Val (Ch), Udf.all); + return C_Int (Boolean'Pos (Result)); + end Generic_Char_Check; + + -- ----------------------------------------------------------------------- + -- + function C_Generic_Type return C_Field_Type + is + Res : Eti_Error; + T : C_Field_Type; + begin + if M_Generic_Type = Null_Field_Type then + T := New_Fieldtype (Generic_Field_Check'Access, + Generic_Char_Check'Access); + if T = Null_Field_Type then + raise Form_Exception; + else + Res := Set_Fieldtype_Arg (T, + Make_Arg'Access, + Copy_Arg'Access, + Free_Arg'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + M_Generic_Type := T; + end if; + pragma Assert (M_Generic_Type /= Null_Field_Type); + return M_Generic_Type; + end C_Generic_Type; + +end Terminal_Interface.Curses.Forms.Field_Types.User; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.ads new file mode 100644 index 0000000..a138d2d --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types-user.ads @@ -0,0 +1,97 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types.User -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; + +package Terminal_Interface.Curses.Forms.Field_Types.User is + pragma Preelaborate (Terminal_Interface.Curses.Forms.Field_Types.User); + use type Interfaces.C.int; + subtype C_Int is Interfaces.C.int; + + type User_Defined_Field_Type is abstract new Field_Type with null record; + -- This is the root of the mechanism we use to create field types in + -- Ada95. You should your own type derive from this one and implement + -- the Field_Check and Character_Check functions for your own type. + + type User_Defined_Field_Type_Access is access all + User_Defined_Field_Type'Class; + + function Field_Check + (Fld : Field; + Typ : User_Defined_Field_Type) return Boolean + is abstract; + -- If True is returned, the field is considered valid, otherwise it is + -- invalid. + + function Character_Check + (Ch : Character; + Typ : User_Defined_Field_Type) return Boolean + is abstract; + -- If True is returned, the character is considered as valid for the + -- field, otherwise as invalid. + + procedure Set_Field_Type (Fld : in Field; + Typ : in User_Defined_Field_Type); + -- This should work for all types derived from User_Defined_Field_Type. + -- No need to reimplement it for your derived type. + + -- +---------------------------------------------------------------------- + -- | Private Part. + -- | Used by the Choice child package. +private + use type Interfaces.C.int; + + function C_Generic_Type return C_Field_Type; + + function Generic_Field_Check (Fld : Field; + Usr : System.Address) return C_Int; + pragma Convention (C, Generic_Field_Check); + -- This is the generic Field_Check_Function for the low-level fieldtype + -- representing all the User_Defined_Field_Type derivates. It routes + -- the call to the Field_Check implementation for the type. + + function Generic_Char_Check (Ch : C_Int; + Usr : System.Address) return C_Int; + pragma Convention (C, Generic_Char_Check); + -- This is the generic Char_Check_Function for the low-level fieldtype + -- representing all the User_Defined_Field_Type derivates. It routes + -- the call to the Character_Check implementation for the type. + +end Terminal_Interface.Curses.Forms.Field_Types.User; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types.adb new file mode 100644 index 0000000..da223c9 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_types.adb @@ -0,0 +1,296 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_Types -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; +with Ada.Unchecked_Deallocation; +with Ada.Unchecked_Conversion; +-- | +-- |===================================================================== +-- | man page form_fieldtype.3x +-- |===================================================================== +-- | +package body Terminal_Interface.Curses.Forms.Field_Types is + + use type Interfaces.C.int; + use type System.Address; + + function To_Argument_Access is new Ada.Unchecked_Conversion + (System.Address, Argument_Access); + + function Get_Fieldtype (F : Field) return C_Field_Type; + pragma Import (C, Get_Fieldtype, "field_type"); + + function Get_Arg (F : Field) return System.Address; + pragma Import (C, Get_Arg, "field_arg"); + -- | + -- |===================================================================== + -- | man page form_field_validation.3x + -- |===================================================================== + -- | + -- | + -- | + function Get_Type (Fld : in Field) return Field_Type_Access + is + Low_Level : constant C_Field_Type := Get_Fieldtype (Fld); + Arg : Argument_Access; + begin + if Low_Level = Null_Field_Type then + return null; + else + if Low_Level = M_Builtin_Router or else + Low_Level = M_Generic_Type or else + Low_Level = M_Choice_Router or else + Low_Level = M_Generic_Choice then + Arg := To_Argument_Access (Get_Arg (Fld)); + if Arg = null then + raise Form_Exception; + else + return Arg.Typ; + end if; + else + raise Form_Exception; + end if; + end if; + end Get_Type; + + function Make_Arg (Args : System.Address) return System.Address + is + -- Actually args is a double indirected pointer to the arguments + -- of a C variable argument list. In theory it is now quite + -- complicated to write portable routine that reads the arguments, + -- because one has to know the growth direction of the stack and + -- the sizes of the individual arguments. + -- Fortunately we are only interested in the first argument (#0), + -- we know its size and for the first arg we don't care about + -- into which stack direction we have to proceed. We simply + -- resolve the double indirection and thats it. + type V is access all System.Address; + function To_Access is new Ada.Unchecked_Conversion (System.Address, + V); + begin + return To_Access (To_Access (Args).all).all; + end Make_Arg; + + function Copy_Arg (Usr : System.Address) return System.Address + is + begin + return Usr; + end Copy_Arg; + + procedure Free_Arg (Usr : in System.Address) + is + procedure Free_Type is new Ada.Unchecked_Deallocation + (Field_Type'Class, Field_Type_Access); + procedure Freeargs is new Ada.Unchecked_Deallocation + (Argument, Argument_Access); + + To_Be_Free : Argument_Access := To_Argument_Access (Usr); + Low_Level : C_Field_Type; + begin + if To_Be_Free /= null then + if To_Be_Free.Usr /= System.Null_Address then + Low_Level := To_Be_Free.Cft; + if Low_Level.Freearg /= null then + Low_Level.Freearg (To_Be_Free.Usr); + end if; + end if; + if To_Be_Free.Typ /= null then + Free_Type (To_Be_Free.Typ); + end if; + Freeargs (To_Be_Free); + end if; + end Free_Arg; + + + procedure Wrap_Builtin (Fld : Field; + Typ : Field_Type'Class; + Cft : C_Field_Type := C_Builtin_Router) + is + Usr_Arg : System.Address := Get_Arg (Fld); + Low_Level : constant C_Field_Type := Get_Fieldtype (Fld); + Arg : Argument_Access; + Res : Eti_Error; + function Set_Fld_Type (F : Field := Fld; + Cf : C_Field_Type := Cft; + Arg1 : Argument_Access) return C_Int; + pragma Import (C, Set_Fld_Type, "set_field_type"); + + begin + pragma Assert (Low_Level /= Null_Field_Type); + if Cft /= C_Builtin_Router and then Cft /= C_Choice_Router then + raise Form_Exception; + else + Arg := new Argument'(Usr => System.Null_Address, + Typ => new Field_Type'Class'(Typ), + Cft => Get_Fieldtype (Fld)); + if Usr_Arg /= System.Null_Address then + if Low_Level.Copyarg /= null then + Arg.Usr := Low_Level.Copyarg (Usr_Arg); + else + Arg.Usr := Usr_Arg; + end if; + end if; + + Res := Set_Fld_Type (Arg1 => Arg); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + end Wrap_Builtin; + + function Field_Check_Router (Fld : Field; + Usr : System.Address) return C_Int + is + Arg : constant Argument_Access := To_Argument_Access (Usr); + begin + pragma Assert (Arg /= null and then Arg.Cft /= Null_Field_Type + and then Arg.Typ /= null); + if Arg.Cft.Fcheck /= null then + return Arg.Cft.Fcheck (Fld, Arg.Usr); + else + return 1; + end if; + end Field_Check_Router; + + function Char_Check_Router (Ch : C_Int; + Usr : System.Address) return C_Int + is + Arg : constant Argument_Access := To_Argument_Access (Usr); + begin + pragma Assert (Arg /= null and then Arg.Cft /= Null_Field_Type + and then Arg.Typ /= null); + if Arg.Cft.Ccheck /= null then + return Arg.Cft.Ccheck (Ch, Arg.Usr); + else + return 1; + end if; + end Char_Check_Router; + + function Next_Router (Fld : Field; + Usr : System.Address) return C_Int + is + Arg : constant Argument_Access := To_Argument_Access (Usr); + begin + pragma Assert (Arg /= null and then Arg.Cft /= Null_Field_Type + and then Arg.Typ /= null); + if Arg.Cft.Next /= null then + return Arg.Cft.Next (Fld, Arg.Usr); + else + return 1; + end if; + end Next_Router; + + function Prev_Router (Fld : Field; + Usr : System.Address) return C_Int + is + Arg : constant Argument_Access := To_Argument_Access (Usr); + begin + pragma Assert (Arg /= null and then Arg.Cft /= Null_Field_Type + and then Arg.Typ /= null); + if Arg.Cft.Prev /= null then + return Arg.Cft.Prev (Fld, Arg.Usr); + else + return 1; + end if; + end Prev_Router; + + -- ----------------------------------------------------------------------- + -- + function C_Builtin_Router return C_Field_Type + is + Res : Eti_Error; + T : C_Field_Type; + begin + if M_Builtin_Router = Null_Field_Type then + T := New_Fieldtype (Field_Check_Router'Access, + Char_Check_Router'Access); + if T = Null_Field_Type then + raise Form_Exception; + else + Res := Set_Fieldtype_Arg (T, + Make_Arg'Access, + Copy_Arg'Access, + Free_Arg'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + M_Builtin_Router := T; + end if; + pragma Assert (M_Builtin_Router /= Null_Field_Type); + return M_Builtin_Router; + end C_Builtin_Router; + + -- ----------------------------------------------------------------------- + -- + function C_Choice_Router return C_Field_Type + is + Res : Eti_Error; + T : C_Field_Type; + begin + if M_Choice_Router = Null_Field_Type then + T := New_Fieldtype (Field_Check_Router'Access, + Char_Check_Router'Access); + if T = Null_Field_Type then + raise Form_Exception; + else + Res := Set_Fieldtype_Arg (T, + Make_Arg'Access, + Copy_Arg'Access, + Free_Arg'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + + Res := Set_Fieldtype_Choice (T, + Next_Router'Access, + Prev_Router'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + M_Choice_Router := T; + end if; + pragma Assert (M_Choice_Router /= Null_Field_Type); + return M_Choice_Router; + end C_Choice_Router; + +end Terminal_Interface.Curses.Forms.Field_Types; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_user_data.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_user_data.adb new file mode 100644 index 0000000..82d8f71 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-field_user_data.adb @@ -0,0 +1,85 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Field_User_Data -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +-- | +-- |===================================================================== +-- | man page form_field_userptr.3x +-- |===================================================================== +-- | +package body Terminal_Interface.Curses.Forms.Field_User_Data is + -- | + -- | + -- | + use type Interfaces.C.int; + + procedure Set_User_Data (Fld : in Field; + Data : in User_Access) + is + function Set_Field_Userptr (Fld : Field; + Usr : User_Access) return C_Int; + pragma Import (C, Set_Field_Userptr, "set_field_userptr"); + + Res : constant Eti_Error := Set_Field_Userptr (Fld, Data); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_User_Data; + -- | + -- | + -- | + function Get_User_Data (Fld : in Field) return User_Access + is + function Field_Userptr (Fld : Field) return User_Access; + pragma Import (C, Field_Userptr, "field_userptr"); + begin + return Field_Userptr (Fld); + end Get_User_Data; + + procedure Get_User_Data (Fld : in Field; + Data : out User_Access) + is + begin + Data := Get_User_Data (Fld); + end Get_User_Data; + +end Terminal_Interface.Curses.Forms.Field_User_Data; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-form_user_data.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-form_user_data.adb new file mode 100644 index 0000000..b4c0ffc --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms-form_user_data.adb @@ -0,0 +1,86 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms.Form_User_Data -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +-- | +-- |===================================================================== +-- | man page form__userptr.3x +-- |===================================================================== +-- | +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms.Form_User_Data is + + use type Interfaces.C.int; + + -- | + -- | + -- | + procedure Set_User_Data (Frm : in Form; + Data : in User_Access) + is + function Set_Form_Userptr (Frm : Form; + Data : User_Access) return C_Int; + pragma Import (C, Set_Form_Userptr, "set_form_userptr"); + + Res : constant Eti_Error := Set_Form_Userptr (Frm, Data); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_User_Data; + -- | + -- | + -- | + function Get_User_Data (Frm : in Form) return User_Access + is + function Form_Userptr (Frm : Form) return User_Access; + pragma Import (C, Form_Userptr, "form_userptr"); + begin + return Form_Userptr (Frm); + end Get_User_Data; + + procedure Get_User_Data (Frm : in Form; + Data : out User_Access) + is + begin + Data := Get_User_Data (Frm); + end Get_User_Data; + +end Terminal_Interface.Curses.Forms.Form_User_Data; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-forms.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms.adb new file mode 100644 index 0000000..6c592d8 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-forms.adb @@ -0,0 +1,1160 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Forms -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Deallocation; +with Ada.Unchecked_Conversion; + +with Interfaces.C; use Interfaces.C; +with Interfaces.C.Strings; use Interfaces.C.Strings; +with Interfaces.C.Pointers; + +with Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Forms is + + use Terminal_Interface.Curses.Aux; + + type C_Field_Array is array (Natural range <>) of aliased Field; + package F_Array is new + Interfaces.C.Pointers (Natural, Field, C_Field_Array, Null_Field); + +------------------------------------------------------------------------------ + -- | + -- | + -- | + -- subtype chars_ptr is Interfaces.C.Strings.chars_ptr; + + function FOS_2_CInt is new + Ada.Unchecked_Conversion (Field_Option_Set, + C_Int); + + function CInt_2_FOS is new + Ada.Unchecked_Conversion (C_Int, + Field_Option_Set); + + function FrmOS_2_CInt is new + Ada.Unchecked_Conversion (Form_Option_Set, + C_Int); + + function CInt_2_FrmOS is new + Ada.Unchecked_Conversion (C_Int, + Form_Option_Set); + + procedure Request_Name (Key : in Form_Request_Code; + Name : out String) + is + function Form_Request_Name (Key : C_Int) return chars_ptr; + pragma Import (C, Form_Request_Name, "form_request_name"); + begin + Fill_String (Form_Request_Name (C_Int (Key)), Name); + end Request_Name; + + function Request_Name (Key : Form_Request_Code) return String + is + function Form_Request_Name (Key : C_Int) return chars_ptr; + pragma Import (C, Form_Request_Name, "form_request_name"); + begin + return Fill_String (Form_Request_Name (C_Int (Key))); + end Request_Name; +------------------------------------------------------------------------------ + -- | + -- | + -- | + -- | + -- |===================================================================== + -- | man page form_field_new.3x + -- |===================================================================== + -- | + -- | + -- | + function Create (Height : Line_Count; + Width : Column_Count; + Top : Line_Position; + Left : Column_Position; + Off_Screen : Natural := 0; + More_Buffers : Buffer_Number := Buffer_Number'First) + return Field + is + function Newfield (H, W, T, L, O, M : C_Int) return Field; + pragma Import (C, Newfield, "new_field"); + Fld : constant Field := Newfield (C_Int (Height), C_Int (Width), + C_Int (Top), C_Int (Left), + C_Int (Off_Screen), + C_Int (More_Buffers)); + begin + if Fld = Null_Field then + raise Form_Exception; + end if; + return Fld; + end Create; +-- | +-- | +-- | + procedure Delete (Fld : in out Field) + is + function Free_Field (Fld : Field) return C_Int; + pragma Import (C, Free_Field, "free_field"); + + Res : Eti_Error; + begin + Res := Free_Field (Fld); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Fld := Null_Field; + end Delete; + -- | + -- | + -- | + function Duplicate (Fld : Field; + Top : Line_Position; + Left : Column_Position) return Field + is + function Dup_Field (Fld : Field; + Top : C_Int; + Left : C_Int) return Field; + pragma Import (C, Dup_Field, "dup_field"); + + F : constant Field := Dup_Field (Fld, + C_Int (Top), + C_Int (Left)); + begin + if F = Null_Field then + raise Form_Exception; + end if; + return F; + end Duplicate; + -- | + -- | + -- | + function Link (Fld : Field; + Top : Line_Position; + Left : Column_Position) return Field + is + function Lnk_Field (Fld : Field; + Top : C_Int; + Left : C_Int) return Field; + pragma Import (C, Lnk_Field, "link_field"); + + F : constant Field := Lnk_Field (Fld, + C_Int (Top), + C_Int (Left)); + begin + if F = Null_Field then + raise Form_Exception; + end if; + return F; + end Link; + -- | + -- |===================================================================== + -- | man page form_field_just.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Justification (Fld : in Field; + Just : in Field_Justification := None) + is + function Set_Field_Just (Fld : Field; + Just : C_Int) return C_Int; + pragma Import (C, Set_Field_Just, "set_field_just"); + + Res : constant Eti_Error := + Set_Field_Just (Fld, + C_Int (Field_Justification'Pos (Just))); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Justification; + -- | + -- | + -- | + function Get_Justification (Fld : Field) return Field_Justification + is + function Field_Just (Fld : Field) return C_Int; + pragma Import (C, Field_Just, "field_just"); + begin + return Field_Justification'Val (Field_Just (Fld)); + end Get_Justification; + -- | + -- |===================================================================== + -- | man page form_field_buffer.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First; + Str : in String) + is + type Char_Ptr is access all Interfaces.C.char; + function Set_Fld_Buffer (Fld : Field; + Bufnum : C_Int; + S : Char_Ptr) + return C_Int; + pragma Import (C, Set_Fld_Buffer, "set_field_buffer"); + + Txt : char_array (0 .. Str'Length); + Len : size_t; + Res : Eti_Error; + begin + To_C (Str, Txt, Len); + Res := Set_Fld_Buffer (Fld, C_Int (Buffer), Txt (Txt'First)'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Buffer; + -- | + -- | + -- | + procedure Get_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First; + Str : out String) + is + function Field_Buffer (Fld : Field; + B : C_Int) return chars_ptr; + pragma Import (C, Field_Buffer, "field_buffer"); + begin + Fill_String (Field_Buffer (Fld, C_Int (Buffer)), Str); + end Get_Buffer; + + function Get_Buffer + (Fld : in Field; + Buffer : in Buffer_Number := Buffer_Number'First) return String + is + function Field_Buffer (Fld : Field; + B : C_Int) return chars_ptr; + pragma Import (C, Field_Buffer, "field_buffer"); + begin + return Fill_String (Field_Buffer (Fld, C_Int (Buffer))); + end Get_Buffer; + -- | + -- | + -- | + procedure Set_Status (Fld : in Field; + Status : in Boolean := True) + is + function Set_Fld_Status (Fld : Field; + St : C_Int) return C_Int; + pragma Import (C, Set_Fld_Status, "set_field_status"); + + Res : constant Eti_Error := Set_Fld_Status (Fld, Boolean'Pos (Status)); + begin + if Res /= E_Ok then + raise Form_Exception; + end if; + end Set_Status; + -- | + -- | + -- | + function Changed (Fld : Field) return Boolean + is + function Field_Status (Fld : Field) return C_Int; + pragma Import (C, Field_Status, "field_status"); + + Res : constant C_Int := Field_Status (Fld); + begin + if Res = Curses_False then + return False; + else + return True; + end if; + end Changed; + -- | + -- | + -- | + procedure Set_Maximum_Size (Fld : in Field; + Max : in Natural := 0) + is + function Set_Field_Max (Fld : Field; + M : C_Int) return C_Int; + pragma Import (C, Set_Field_Max, "set_max_field"); + + Res : constant Eti_Error := Set_Field_Max (Fld, C_Int (Max)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Maximum_Size; + -- | + -- |===================================================================== + -- | man page form_field_opts.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Options (Fld : in Field; + Options : in Field_Option_Set) + is + function Set_Field_Opts (Fld : Field; + Opt : C_Int) return C_Int; + pragma Import (C, Set_Field_Opts, "set_field_opts"); + + Opt : C_Int := FOS_2_CInt (Options); + Res : Eti_Error; + begin + Res := Set_Field_Opts (Fld, Opt); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Options; + -- | + -- | + -- | + procedure Switch_Options (Fld : in Field; + Options : in Field_Option_Set; + On : Boolean := True) + is + function Field_Opts_On (Fld : Field; + Opt : C_Int) return C_Int; + pragma Import (C, Field_Opts_On, "field_opts_on"); + function Field_Opts_Off (Fld : Field; + Opt : C_Int) return C_Int; + pragma Import (C, Field_Opts_Off, "field_opts_off"); + + Err : Eti_Error; + Opt : C_Int := FOS_2_CInt (Options); + begin + if On then + Err := Field_Opts_On (Fld, Opt); + else + Err := Field_Opts_Off (Fld, Opt); + end if; + if Err /= E_Ok then + Eti_Exception (Err); + end if; + end Switch_Options; + -- | + -- | + -- | + procedure Get_Options (Fld : in Field; + Options : out Field_Option_Set) + is + function Field_Opts (Fld : Field) return C_Int; + pragma Import (C, Field_Opts, "field_opts"); + + Res : C_Int := Field_Opts (Fld); + begin + Options := CInt_2_FOS (Res); + end Get_Options; + -- | + -- | + -- | + function Get_Options (Fld : Field := Null_Field) + return Field_Option_Set + is + Fos : Field_Option_Set; + begin + Get_Options (Fld, Fos); + return Fos; + end Get_Options; + -- | + -- |===================================================================== + -- | man page form_field_attributes.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Foreground + (Fld : in Field; + Fore : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Set_Field_Fore (Fld : Field; + Attr : C_Chtype) return C_Int; + pragma Import (C, Set_Field_Fore, "set_field_fore"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Color => Color, + Attr => Fore); + Res : constant Eti_Error := + Set_Field_Fore (Fld, AttrChar_To_Chtype (Ch)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Foreground; + -- | + -- | + -- | + procedure Foreground (Fld : in Field; + Fore : out Character_Attribute_Set) + is + function Field_Fore (Fld : Field) return C_Chtype; + pragma Import (C, Field_Fore, "field_fore"); + begin + Fore := Chtype_To_AttrChar (Field_Fore (Fld)).Attr; + end Foreground; + + procedure Foreground (Fld : in Field; + Fore : out Character_Attribute_Set; + Color : out Color_Pair) + is + function Field_Fore (Fld : Field) return C_Chtype; + pragma Import (C, Field_Fore, "field_fore"); + begin + Fore := Chtype_To_AttrChar (Field_Fore (Fld)).Attr; + Color := Chtype_To_AttrChar (Field_Fore (Fld)).Color; + end Foreground; + -- | + -- | + -- | + procedure Set_Background + (Fld : in Field; + Back : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Set_Field_Back (Fld : Field; + Attr : C_Chtype) return C_Int; + pragma Import (C, Set_Field_Back, "set_field_back"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Color => Color, + Attr => Back); + Res : constant Eti_Error := + Set_Field_Back (Fld, AttrChar_To_Chtype (Ch)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Background; + -- | + -- | + -- | + procedure Background (Fld : in Field; + Back : out Character_Attribute_Set) + is + function Field_Back (Fld : Field) return C_Chtype; + pragma Import (C, Field_Back, "field_back"); + begin + Back := Chtype_To_AttrChar (Field_Back (Fld)).Attr; + end Background; + + procedure Background (Fld : in Field; + Back : out Character_Attribute_Set; + Color : out Color_Pair) + is + function Field_Back (Fld : Field) return C_Chtype; + pragma Import (C, Field_Back, "field_back"); + begin + Back := Chtype_To_AttrChar (Field_Back (Fld)).Attr; + Color := Chtype_To_AttrChar (Field_Back (Fld)).Color; + end Background; + -- | + -- | + -- | + procedure Set_Pad_Character (Fld : in Field; + Pad : in Character := Space) + is + function Set_Field_Pad (Fld : Field; + Ch : C_Int) return C_Int; + pragma Import (C, Set_Field_Pad, "set_field_pad"); + + Res : constant Eti_Error := Set_Field_Pad (Fld, + C_Int (Character'Pos (Pad))); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Pad_Character; + -- | + -- | + -- | + procedure Pad_Character (Fld : in Field; + Pad : out Character) + is + function Field_Pad (Fld : Field) return C_Int; + pragma Import (C, Field_Pad, "field_pad"); + begin + Pad := Character'Val (Field_Pad (Fld)); + end Pad_Character; + -- | + -- |===================================================================== + -- | man page form_field_info.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Info (Fld : in Field; + Lines : out Line_Count; + Columns : out Column_Count; + First_Row : out Line_Position; + First_Column : out Column_Position; + Off_Screen : out Natural; + Additional_Buffers : out Buffer_Number) + is + type C_Int_Access is access all C_Int; + function Fld_Info (Fld : Field; + L, C, Fr, Fc, Os, Ab : C_Int_Access) + return C_Int; + pragma Import (C, Fld_Info, "field_info"); + + L, C, Fr, Fc, Os, Ab : aliased C_Int; + Res : constant Eti_Error := Fld_Info (Fld, + L'Access, C'Access, + Fr'Access, Fc'Access, + Os'Access, Ab'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + else + Lines := Line_Count (L); + Columns := Column_Count (C); + First_Row := Line_Position (Fr); + First_Column := Column_Position (Fc); + Off_Screen := Natural (Os); + Additional_Buffers := Buffer_Number (Ab); + end if; + end Info; +-- | +-- | +-- | + procedure Dynamic_Info (Fld : in Field; + Lines : out Line_Count; + Columns : out Column_Count; + Max : out Natural) + is + type C_Int_Access is access all C_Int; + function Dyn_Info (Fld : Field; L, C, M : C_Int_Access) return C_Int; + pragma Import (C, Dyn_Info, "dynamic_field_info"); + + L, C, M : aliased C_Int; + Res : constant Eti_Error := Dyn_Info (Fld, + L'Access, C'Access, + M'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + else + Lines := Line_Count (L); + Columns := Column_Count (C); + Max := Natural (M); + end if; + end Dynamic_Info; + -- | + -- |===================================================================== + -- | man page form_win.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Window (Frm : in Form; + Win : in Window) + is + function Set_Form_Win (Frm : Form; + Win : Window) return C_Int; + pragma Import (C, Set_Form_Win, "set_form_win"); + + Res : constant Eti_Error := Set_Form_Win (Frm, Win); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Window; + -- | + -- | + -- | + function Get_Window (Frm : Form) return Window + is + function Form_Win (Frm : Form) return Window; + pragma Import (C, Form_Win, "form_win"); + + W : constant Window := Form_Win (Frm); + begin + return W; + end Get_Window; + -- | + -- | + -- | + procedure Set_Sub_Window (Frm : in Form; + Win : in Window) + is + function Set_Form_Sub (Frm : Form; + Win : Window) return C_Int; + pragma Import (C, Set_Form_Sub, "set_form_sub"); + + Res : constant Eti_Error := Set_Form_Sub (Frm, Win); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Sub_Window; + -- | + -- | + -- | + function Get_Sub_Window (Frm : Form) return Window + is + function Form_Sub (Frm : Form) return Window; + pragma Import (C, Form_Sub, "form_sub"); + + W : constant Window := Form_Sub (Frm); + begin + return W; + end Get_Sub_Window; + -- | + -- | + -- | + procedure Scale (Frm : in Form; + Lines : out Line_Count; + Columns : out Column_Count) + is + type C_Int_Access is access all C_Int; + function M_Scale (Frm : Form; Yp, Xp : C_Int_Access) return C_Int; + pragma Import (C, M_Scale, "scale_form"); + + X, Y : aliased C_Int; + Res : constant Eti_Error := M_Scale (Frm, Y'Access, X'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Lines := Line_Count (Y); + Columns := Column_Count (X); + end Scale; + -- | + -- |===================================================================== + -- | man page menu_hook.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Field_Init_Hook (Frm : in Form; + Proc : in Form_Hook_Function) + is + function Set_Field_Init (Frm : Form; + Proc : Form_Hook_Function) return C_Int; + pragma Import (C, Set_Field_Init, "set_field_init"); + + Res : constant Eti_Error := Set_Field_Init (Frm, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Field_Init_Hook; + -- | + -- | + -- | + procedure Set_Field_Term_Hook (Frm : in Form; + Proc : in Form_Hook_Function) + is + function Set_Field_Term (Frm : Form; + Proc : Form_Hook_Function) return C_Int; + pragma Import (C, Set_Field_Term, "set_field_term"); + + Res : constant Eti_Error := Set_Field_Term (Frm, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Field_Term_Hook; + -- | + -- | + -- | + procedure Set_Form_Init_Hook (Frm : in Form; + Proc : in Form_Hook_Function) + is + function Set_Form_Init (Frm : Form; + Proc : Form_Hook_Function) return C_Int; + pragma Import (C, Set_Form_Init, "set_form_init"); + + Res : constant Eti_Error := Set_Form_Init (Frm, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Form_Init_Hook; + -- | + -- | + -- | + procedure Set_Form_Term_Hook (Frm : in Form; + Proc : in Form_Hook_Function) + is + function Set_Form_Term (Frm : Form; + Proc : Form_Hook_Function) return C_Int; + pragma Import (C, Set_Form_Term, "set_form_term"); + + Res : constant Eti_Error := Set_Form_Term (Frm, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Form_Term_Hook; + -- | + -- |===================================================================== + -- | man page form_fields.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Redefine (Frm : in Form; + Flds : in Field_Array_Access) + is + function Set_Frm_Fields (Frm : Form; + Items : System.Address) return C_Int; + pragma Import (C, Set_Frm_Fields, "set_form_fields"); + + Res : Eti_Error; + begin + pragma Assert (Flds (Flds'Last) = Null_Field); + if Flds (Flds'Last) /= Null_Field then + raise Form_Exception; + else + Res := Set_Frm_Fields (Frm, Flds (Flds'First)'Address); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + end Redefine; + -- | + -- | + -- | + function Fields (Frm : Form; + Index : Positive) return Field + is + use F_Array; + + function C_Fields (Frm : Form) return Pointer; + pragma Import (C, C_Fields, "form_fields"); + + P : Pointer := C_Fields (Frm); + begin + if P = null or else Index not in 1 .. Field_Count (Frm) then + raise Form_Exception; + else + P := P + ptrdiff_t (C_Int (Index) - 1); + return P.all; + end if; + end Fields; + -- | + -- | + -- | + function Field_Count (Frm : Form) return Natural + is + function Count (Frm : Form) return C_Int; + pragma Import (C, Count, "field_count"); + begin + return Natural (Count (Frm)); + end Field_Count; + -- | + -- | + -- | + procedure Move (Fld : in Field; + Line : in Line_Position; + Column : in Column_Position) + is + function Move (Fld : Field; L, C : C_Int) return C_Int; + pragma Import (C, Move, "move_field"); + + Res : constant Eti_Error := Move (Fld, C_Int (Line), C_Int (Column)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Move; + -- | + -- |===================================================================== + -- | man page form_new.3x + -- |===================================================================== + -- | + -- | + -- | + function Create (Fields : Field_Array_Access) return Form + is + function NewForm (Fields : System.Address) return Form; + pragma Import (C, NewForm, "new_form"); + + M : Form; + begin + pragma Assert (Fields (Fields'Last) = Null_Field); + if Fields (Fields'Last) /= Null_Field then + raise Form_Exception; + else + M := NewForm (Fields (Fields'First)'Address); + if M = Null_Form then + raise Form_Exception; + end if; + return M; + end if; + end Create; + -- | + -- | + -- | + procedure Delete (Frm : in out Form) + is + function Free (Frm : Form) return C_Int; + pragma Import (C, Free, "free_form"); + + Res : constant Eti_Error := Free (Frm); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Frm := Null_Form; + end Delete; + -- | + -- |===================================================================== + -- | man page form_opts.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Options (Frm : in Form; + Options : in Form_Option_Set) + is + function Set_Form_Opts (Frm : Form; + Opt : C_Int) return C_Int; + pragma Import (C, Set_Form_Opts, "set_form_opts"); + + Opt : C_Int := FrmOS_2_CInt (Options); + Res : Eti_Error; + begin + Res := Set_Form_Opts (Frm, Opt); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Options; + -- | + -- | + -- | + procedure Switch_Options (Frm : in Form; + Options : in Form_Option_Set; + On : Boolean := True) + is + function Form_Opts_On (Frm : Form; + Opt : C_Int) return C_Int; + pragma Import (C, Form_Opts_On, "form_opts_on"); + function Form_Opts_Off (Frm : Form; + Opt : C_Int) return C_Int; + pragma Import (C, Form_Opts_Off, "form_opts_off"); + + Err : Eti_Error; + Opt : C_Int := FrmOS_2_CInt (Options); + begin + if On then + Err := Form_Opts_On (Frm, Opt); + else + Err := Form_Opts_Off (Frm, Opt); + end if; + if Err /= E_Ok then + Eti_Exception (Err); + end if; + end Switch_Options; + -- | + -- | + -- | + procedure Get_Options (Frm : in Form; + Options : out Form_Option_Set) + is + function Form_Opts (Frm : Form) return C_Int; + pragma Import (C, Form_Opts, "form_opts"); + + Res : C_Int := Form_Opts (Frm); + begin + Options := CInt_2_FrmOS (Res); + end Get_Options; + -- | + -- | + -- | + function Get_Options (Frm : Form := Null_Form) return Form_Option_Set + is + Fos : Form_Option_Set; + begin + Get_Options (Frm, Fos); + return Fos; + end Get_Options; + -- | + -- |===================================================================== + -- | man page form_post.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Post (Frm : in Form; + Post : in Boolean := True) + is + function M_Post (Frm : Form) return C_Int; + pragma Import (C, M_Post, "post_form"); + function M_Unpost (Frm : Form) return C_Int; + pragma Import (C, M_Unpost, "unpost_form"); + + Res : Eti_Error; + begin + if Post then + Res := M_Post (Frm); + else + Res := M_Unpost (Frm); + end if; + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Post; + -- | + -- |===================================================================== + -- | man page form_cursor.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Position_Cursor (Frm : Form) + is + function Pos_Form_Cursor (Frm : Form) return C_Int; + pragma Import (C, Pos_Form_Cursor, "pos_form_cursor"); + + Res : constant Eti_Error := Pos_Form_Cursor (Frm); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Position_Cursor; + -- | + -- |===================================================================== + -- | man page form_data.3x + -- |===================================================================== + -- | + -- | + -- | + function Data_Ahead (Frm : Form) return Boolean + is + function Ahead (Frm : Form) return C_Int; + pragma Import (C, Ahead, "data_ahead"); + + Res : constant C_Int := Ahead (Frm); + begin + if Res = Curses_False then + return False; + else + return True; + end if; + end Data_Ahead; + -- | + -- | + -- | + function Data_Behind (Frm : Form) return Boolean + is + function Behind (Frm : Form) return C_Int; + pragma Import (C, Behind, "data_behind"); + + Res : constant C_Int := Behind (Frm); + begin + if Res = Curses_False then + return False; + else + return True; + end if; + end Data_Behind; + -- | + -- |===================================================================== + -- | man page form_driver.3x + -- |===================================================================== + -- | + -- | + -- | + function Driver (Frm : Form; + Key : Key_Code) return Driver_Result + is + function Frm_Driver (Frm : Form; Key : C_Int) return C_Int; + pragma Import (C, Frm_Driver, "form_driver"); + + R : Eti_Error := Frm_Driver (Frm, C_Int (Key)); + begin + if R /= E_Ok then + if R = E_Unknown_Command then + return Unknown_Request; + elsif R = E_Invalid_Field then + return Invalid_Field; + elsif R = E_Request_Denied then + return Request_Denied; + else + Eti_Exception (R); + return Form_Ok; + end if; + else + return Form_Ok; + end if; + end Driver; + -- | + -- |===================================================================== + -- | man page form_page.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_Current (Frm : in Form; + Fld : in Field) + is + function Set_Current_Fld (Frm : Form; Fld : Field) return C_Int; + pragma Import (C, Set_Current_Fld, "set_current_field"); + + Res : constant Eti_Error := Set_Current_Fld (Frm, Fld); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Current; + -- | + -- | + -- | + function Current (Frm : in Form) return Field + is + function Current_Fld (Frm : Form) return Field; + pragma Import (C, Current_Fld, "current_field"); + + Fld : constant Field := Current_Fld (Frm); + begin + if Fld = Null_Field then + raise Form_Exception; + end if; + return Fld; + end Current; + -- | + -- | + -- | + procedure Set_Page (Frm : in Form; + Page : in Page_Number := Page_Number'First) + is + function Set_Frm_Page (Frm : Form; Pg : C_Int) return C_Int; + pragma Import (C, Set_Frm_Page, "set_form_page"); + + Res : constant Eti_Error := Set_Frm_Page (Frm, C_Int (Page)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Page; + -- | + -- | + -- | + function Page (Frm : Form) return Page_Number + is + function Get_Page (Frm : Form) return C_Int; + pragma Import (C, Get_Page, "form_page"); + + P : constant C_Int := Get_Page (Frm); + begin + if P < 0 then + raise Form_Exception; + else + return Page_Number (P); + end if; + end Page; + + function Get_Index (Fld : Field) return Positive + is + function Get_Fieldindex (Fld : Field) return C_Int; + pragma Import (C, Get_Fieldindex, "field_index"); + + Res : constant C_Int := Get_Fieldindex (Fld); + begin + if Res = Curses_Err then + raise Form_Exception; + end if; + return Positive (Natural (Res) + Positive'First); + end Get_Index; + + -- | + -- |===================================================================== + -- | man page form_new_page.3x + -- |===================================================================== + -- | + -- | + -- | + procedure Set_New_Page (Fld : in Field; + New_Page : in Boolean := True) + is + function Set_Page (Fld : Field; Flg : C_Int) return C_Int; + pragma Import (C, Set_Page, "set_new_page"); + + Res : constant Eti_Error := Set_Page (Fld, Boolean'Pos (New_Page)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_New_Page; + -- | + -- | + -- | + function Is_New_Page (Fld : Field) return Boolean + is + function Is_New (Fld : Field) return C_Int; + pragma Import (C, Is_New, "new_page"); + + Res : constant C_Int := Is_New (Fld); + begin + if Res = Curses_False then + return False; + else + return True; + end if; + end Is_New_Page; + + procedure Free (FA : in out Field_Array_Access; + Free_Fields : in Boolean := False) + is + procedure Release is new Ada.Unchecked_Deallocation + (Field_Array, Field_Array_Access); + begin + if FA /= null and then Free_Fields then + for I in FA'First .. (FA'Last - 1) loop + if (FA (I) /= Null_Field) then + Delete (FA (I)); + end if; + end loop; + end if; + Release (FA); + end Free; + + -- |===================================================================== + + function Default_Field_Options return Field_Option_Set + is + begin + return Get_Options (Null_Field); + end Default_Field_Options; + + function Default_Form_Options return Form_Option_Set + is + begin + return Get_Options (Null_Form); + end Default_Form_Options; + +end Terminal_Interface.Curses.Forms; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-item_user_data.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-item_user_data.adb new file mode 100644 index 0000000..3facadd --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-item_user_data.adb @@ -0,0 +1,77 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menus.Item_User_Data -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Menus.Item_User_Data is + + use type Interfaces.C.int; + + procedure Set_User_Data (Itm : in Item; + Data : in User_Access) + is + function Set_Item_Userptr (Itm : Item; + Addr : User_Access) return C_Int; + pragma Import (C, Set_Item_Userptr, "set_item_userptr"); + + Res : constant Eti_Error := Set_Item_Userptr (Itm, Data); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_User_Data; + + function Get_User_Data (Itm : in Item) return User_Access + is + function Item_Userptr (Itm : Item) return User_Access; + pragma Import (C, Item_Userptr, "item_userptr"); + begin + return Item_Userptr (Itm); + end Get_User_Data; + + procedure Get_User_Data (Itm : in Item; + Data : out User_Access) + is + begin + Data := Get_User_Data (Itm); + end Get_User_Data; + +end Terminal_Interface.Curses.Menus.Item_User_Data; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-menu_user_data.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-menu_user_data.adb new file mode 100644 index 0000000..87ea22b --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus-menu_user_data.adb @@ -0,0 +1,76 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menus.Menu_User_Data -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +package body Terminal_Interface.Curses.Menus.Menu_User_Data is + + use type Interfaces.C.int; + + procedure Set_User_Data (Men : in Menu; + Data : in User_Access) + is + function Set_Menu_Userptr (Men : Menu; + Data : User_Access) return C_Int; + pragma Import (C, Set_Menu_Userptr, "set_menu_userptr"); + + Res : constant Eti_Error := Set_Menu_Userptr (Men, Data); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_User_Data; + + function Get_User_Data (Men : in Menu) return User_Access + is + function Menu_Userptr (Men : Menu) return User_Access; + pragma Import (C, Menu_Userptr, "menu_userptr"); + begin + return Menu_Userptr (Men); + end Get_User_Data; + + procedure Get_User_Data (Men : in Menu; + Data : out User_Access) + is + begin + Data := Get_User_Data (Men); + end Get_User_Data; + +end Terminal_Interface.Curses.Menus.Menu_User_Data; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-menus.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus.adb new file mode 100644 index 0000000..3d70de3 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-menus.adb @@ -0,0 +1,1021 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Menus -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Unchecked_Deallocation; +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; + +with Interfaces.C; use Interfaces.C; +with Interfaces.C.Strings; use Interfaces.C.Strings; +with Interfaces.C.Pointers; + +with Ada.Unchecked_Conversion; + +package body Terminal_Interface.Curses.Menus is + + type C_Item_Array is array (Natural range <>) of aliased Item; + package I_Array is new + Interfaces.C.Pointers (Natural, Item, C_Item_Array, Null_Item); + + use type System.Bit_Order; + subtype chars_ptr is Interfaces.C.Strings.chars_ptr; + + function MOS_2_CInt is new + Ada.Unchecked_Conversion (Menu_Option_Set, + C_Int); + + function CInt_2_MOS is new + Ada.Unchecked_Conversion (C_Int, + Menu_Option_Set); + + function IOS_2_CInt is new + Ada.Unchecked_Conversion (Item_Option_Set, + C_Int); + + function CInt_2_IOS is new + Ada.Unchecked_Conversion (C_Int, + Item_Option_Set); + +------------------------------------------------------------------------------ + procedure Request_Name (Key : in Menu_Request_Code; + Name : out String) + is + function Request_Name (Key : C_Int) return chars_ptr; + pragma Import (C, Request_Name, "menu_request_name"); + begin + Fill_String (Request_Name (C_Int (Key)), Name); + end Request_Name; + + function Request_Name (Key : Menu_Request_Code) return String + is + function Request_Name (Key : C_Int) return chars_ptr; + pragma Import (C, Request_Name, "menu_request_name"); + begin + return Fill_String (Request_Name (C_Int (Key))); + end Request_Name; + + function Create (Name : String; + Description : String := "") return Item + is + type Char_Ptr is access all Interfaces.C.char; + function Newitem (Name, Desc : Char_Ptr) return Item; + pragma Import (C, Newitem, "new_item"); + + type Name_String is new char_array (0 .. Name'Length); + type Name_String_Ptr is access Name_String; + pragma Controlled (Name_String_Ptr); + + type Desc_String is new char_array (0 .. Description'Length); + type Desc_String_Ptr is access Desc_String; + pragma Controlled (Desc_String_Ptr); + + Name_Str : Name_String_Ptr := new Name_String; + Desc_Str : Desc_String_Ptr := new Desc_String; + Name_Len, Desc_Len : size_t; + Result : Item; + begin + To_C (Name, Name_Str.all, Name_Len); + To_C (Description, Desc_Str.all, Desc_Len); + Result := Newitem (Name_Str.all (Name_Str.all'First)'Access, + Desc_Str.all (Desc_Str.all'First)'Access); + if Result = Null_Item then + raise Eti_System_Error; + end if; + return Result; + end Create; + + procedure Delete (Itm : in out Item) + is + function Descname (Itm : Item) return chars_ptr; + pragma Import (C, Descname, "item_description"); + function Itemname (Itm : Item) return chars_ptr; + pragma Import (C, Itemname, "item_name"); + + function Freeitem (Itm : Item) return C_Int; + pragma Import (C, Freeitem, "free_item"); + + Res : Eti_Error; + Ptr : chars_ptr; + begin + Ptr := Descname (Itm); + if Ptr /= Null_Ptr then + Interfaces.C.Strings.Free (Ptr); + end if; + Ptr := Itemname (Itm); + if Ptr /= Null_Ptr then + Interfaces.C.Strings.Free (Ptr); + end if; + Res := Freeitem (Itm); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Itm := Null_Item; + end Delete; +------------------------------------------------------------------------------- + procedure Set_Value (Itm : in Item; + Value : in Boolean := True) + is + function Set_Item_Val (Itm : Item; + Val : C_Int) return C_Int; + pragma Import (C, Set_Item_Val, "set_item_value"); + + Res : constant Eti_Error := Set_Item_Val (Itm, Boolean'Pos (Value)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Value; + + function Value (Itm : Item) return Boolean + is + function Item_Val (Itm : Item) return C_Int; + pragma Import (C, Item_Val, "item_value"); + begin + if Item_Val (Itm) = Curses_False then + return False; + else + return True; + end if; + end Value; + +------------------------------------------------------------------------------- + function Visible (Itm : Item) return Boolean + is + function Item_Vis (Itm : Item) return C_Int; + pragma Import (C, Item_Vis, "item_visible"); + begin + if Item_Vis (Itm) = Curses_False then + return False; + else + return True; + end if; + end Visible; +------------------------------------------------------------------------------- + procedure Set_Options (Itm : in Item; + Options : in Item_Option_Set) + is + function Set_Item_Opts (Itm : Item; + Opt : C_Int) return C_Int; + pragma Import (C, Set_Item_Opts, "set_item_opts"); + + Opt : C_Int := IOS_2_CInt (Options); + Res : Eti_Error; + begin + Res := Set_Item_Opts (Itm, Opt); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Options; + + procedure Switch_Options (Itm : in Item; + Options : in Item_Option_Set; + On : Boolean := True) + is + function Item_Opts_On (Itm : Item; + Opt : C_Int) return C_Int; + pragma Import (C, Item_Opts_On, "item_opts_on"); + function Item_Opts_Off (Itm : Item; + Opt : C_Int) return C_Int; + pragma Import (C, Item_Opts_Off, "item_opts_off"); + + Opt : C_Int := IOS_2_CInt (Options); + Err : Eti_Error; + begin + if On then + Err := Item_Opts_On (Itm, Opt); + else + Err := Item_Opts_Off (Itm, Opt); + end if; + if Err /= E_Ok then + Eti_Exception (Err); + end if; + end Switch_Options; + + procedure Get_Options (Itm : in Item; + Options : out Item_Option_Set) + is + function Item_Opts (Itm : Item) return C_Int; + pragma Import (C, Item_Opts, "item_opts"); + + Res : C_Int := Item_Opts (Itm); + begin + Options := CInt_2_IOS (Res); + end Get_Options; + + function Get_Options (Itm : Item := Null_Item) return Item_Option_Set + is + Ios : Item_Option_Set; + begin + Get_Options (Itm, Ios); + return Ios; + end Get_Options; +------------------------------------------------------------------------------- + procedure Name (Itm : in Item; + Name : out String) + is + function Itemname (Itm : Item) return chars_ptr; + pragma Import (C, Itemname, "item_name"); + begin + Fill_String (Itemname (Itm), Name); + end Name; + + function Name (Itm : in Item) return String + is + function Itemname (Itm : Item) return chars_ptr; + pragma Import (C, Itemname, "item_name"); + begin + return Fill_String (Itemname (Itm)); + end Name; + + procedure Description (Itm : in Item; + Description : out String) + is + function Descname (Itm : Item) return chars_ptr; + pragma Import (C, Descname, "item_description"); + begin + Fill_String (Descname (Itm), Description); + end Description; + + function Description (Itm : in Item) return String + is + function Descname (Itm : Item) return chars_ptr; + pragma Import (C, Descname, "item_description"); + begin + return Fill_String (Descname (Itm)); + end Description; +------------------------------------------------------------------------------- + procedure Set_Current (Men : in Menu; + Itm : in Item) + is + function Set_Curr_Item (Men : Menu; + Itm : Item) return C_Int; + pragma Import (C, Set_Curr_Item, "set_current_item"); + + Res : constant Eti_Error := Set_Curr_Item (Men, Itm); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Current; + + function Current (Men : Menu) return Item + is + function Curr_Item (Men : Menu) return Item; + pragma Import (C, Curr_Item, "current_item"); + + Res : constant Item := Curr_Item (Men); + begin + if Res = Null_Item then + raise Menu_Exception; + end if; + return Res; + end Current; + + procedure Set_Top_Row (Men : in Menu; + Line : in Line_Position) + is + function Set_Toprow (Men : Menu; + Line : C_Int) return C_Int; + pragma Import (C, Set_Toprow, "set_top_row"); + + Res : constant Eti_Error := Set_Toprow (Men, C_Int (Line)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Top_Row; + + function Top_Row (Men : Menu) return Line_Position + is + function Toprow (Men : Menu) return C_Int; + pragma Import (C, Toprow, "top_row"); + + Res : constant C_Int := Toprow (Men); + begin + if Res = Curses_Err then + raise Menu_Exception; + end if; + return Line_Position (Res); + end Top_Row; + + function Get_Index (Itm : Item) return Positive + is + function Get_Itemindex (Itm : Item) return C_Int; + pragma Import (C, Get_Itemindex, "item_index"); + + Res : constant C_Int := Get_Itemindex (Itm); + begin + if Res = Curses_Err then + raise Menu_Exception; + end if; + return Positive (Natural (Res) + Positive'First); + end Get_Index; +------------------------------------------------------------------------------- + procedure Post (Men : in Menu; + Post : in Boolean := True) + is + function M_Post (Men : Menu) return C_Int; + pragma Import (C, M_Post, "post_menu"); + function M_Unpost (Men : Menu) return C_Int; + pragma Import (C, M_Unpost, "unpost_menu"); + + Res : Eti_Error; + begin + if Post then + Res := M_Post (Men); + else + Res := M_Unpost (Men); + end if; + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Post; +------------------------------------------------------------------------------- + procedure Set_Options (Men : in Menu; + Options : in Menu_Option_Set) + is + function Set_Menu_Opts (Men : Menu; + Opt : C_Int) return C_Int; + pragma Import (C, Set_Menu_Opts, "set_menu_opts"); + + Opt : C_Int := MOS_2_CInt (Options); + Res : Eti_Error; + begin + Res := Set_Menu_Opts (Men, Opt); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Options; + + procedure Switch_Options (Men : in Menu; + Options : in Menu_Option_Set; + On : in Boolean := True) + is + function Menu_Opts_On (Men : Menu; + Opt : C_Int) return C_Int; + pragma Import (C, Menu_Opts_On, "menu_opts_on"); + function Menu_Opts_Off (Men : Menu; + Opt : C_Int) return C_Int; + pragma Import (C, Menu_Opts_Off, "menu_opts_off"); + + Opt : C_Int := MOS_2_CInt (Options); + Err : Eti_Error; + begin + if On then + Err := Menu_Opts_On (Men, Opt); + else + Err := Menu_Opts_Off (Men, Opt); + end if; + if Err /= E_Ok then + Eti_Exception (Err); + end if; + end Switch_Options; + + procedure Get_Options (Men : in Menu; + Options : out Menu_Option_Set) + is + function Menu_Opts (Men : Menu) return C_Int; + pragma Import (C, Menu_Opts, "menu_opts"); + + Res : C_Int := Menu_Opts (Men); + begin + Options := CInt_2_MOS (Res); + end Get_Options; + + function Get_Options (Men : Menu := Null_Menu) return Menu_Option_Set + is + Mos : Menu_Option_Set; + begin + Get_Options (Men, Mos); + return Mos; + end Get_Options; +------------------------------------------------------------------------------- + procedure Set_Window (Men : in Menu; + Win : in Window) + is + function Set_Menu_Win (Men : Menu; + Win : Window) return C_Int; + pragma Import (C, Set_Menu_Win, "set_menu_win"); + + Res : constant Eti_Error := Set_Menu_Win (Men, Win); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Window; + + function Get_Window (Men : Menu) return Window + is + function Menu_Win (Men : Menu) return Window; + pragma Import (C, Menu_Win, "menu_win"); + + W : constant Window := Menu_Win (Men); + begin + return W; + end Get_Window; + + procedure Set_Sub_Window (Men : in Menu; + Win : in Window) + is + function Set_Menu_Sub (Men : Menu; + Win : Window) return C_Int; + pragma Import (C, Set_Menu_Sub, "set_menu_sub"); + + Res : constant Eti_Error := Set_Menu_Sub (Men, Win); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Sub_Window; + + function Get_Sub_Window (Men : Menu) return Window + is + function Menu_Sub (Men : Menu) return Window; + pragma Import (C, Menu_Sub, "menu_sub"); + + W : constant Window := Menu_Sub (Men); + begin + return W; + end Get_Sub_Window; + + procedure Scale (Men : in Menu; + Lines : out Line_Count; + Columns : out Column_Count) + is + type C_Int_Access is access all C_Int; + function M_Scale (Men : Menu; + Yp, Xp : C_Int_Access) return C_Int; + pragma Import (C, M_Scale, "scale_menu"); + + X, Y : aliased C_Int; + Res : constant Eti_Error := M_Scale (Men, Y'Access, X'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Lines := Line_Count (Y); + Columns := Column_Count (X); + end Scale; +------------------------------------------------------------------------------- + procedure Position_Cursor (Men : Menu) + is + function Pos_Menu_Cursor (Men : Menu) return C_Int; + pragma Import (C, Pos_Menu_Cursor, "pos_menu_cursor"); + + Res : constant Eti_Error := Pos_Menu_Cursor (Men); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Position_Cursor; + +------------------------------------------------------------------------------- + procedure Set_Mark (Men : in Menu; + Mark : in String) + is + type Char_Ptr is access all Interfaces.C.char; + function Set_Mark (Men : Menu; + Mark : Char_Ptr) return C_Int; + pragma Import (C, Set_Mark, "set_menu_mark"); + + Txt : char_array (0 .. Mark'Length); + Len : size_t; + Res : Eti_Error; + begin + To_C (Mark, Txt, Len); + Res := Set_Mark (Men, Txt (Txt'First)'Access); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Mark; + + procedure Mark (Men : in Menu; + Mark : out String) + is + function Get_Menu_Mark (Men : Menu) return chars_ptr; + pragma Import (C, Get_Menu_Mark, "menu_mark"); + begin + Fill_String (Get_Menu_Mark (Men), Mark); + end Mark; + + function Mark (Men : Menu) return String + is + function Get_Menu_Mark (Men : Menu) return chars_ptr; + pragma Import (C, Get_Menu_Mark, "menu_mark"); + begin + return Fill_String (Get_Menu_Mark (Men)); + end Mark; + +------------------------------------------------------------------------------- + procedure Set_Foreground + (Men : in Menu; + Fore : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Set_Menu_Fore (Men : Menu; + Attr : C_Chtype) return C_Int; + pragma Import (C, Set_Menu_Fore, "set_menu_fore"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Color => Color, + Attr => Fore); + Res : constant Eti_Error := Set_Menu_Fore (Men, AttrChar_To_Chtype (Ch)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Foreground; + + procedure Foreground (Men : in Menu; + Fore : out Character_Attribute_Set) + is + function Menu_Fore (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Fore, "menu_fore"); + begin + Fore := Chtype_To_AttrChar (Menu_Fore (Men)).Attr; + end Foreground; + + procedure Foreground (Men : in Menu; + Fore : out Character_Attribute_Set; + Color : out Color_Pair) + is + function Menu_Fore (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Fore, "menu_fore"); + begin + Fore := Chtype_To_AttrChar (Menu_Fore (Men)).Attr; + Color := Chtype_To_AttrChar (Menu_Fore (Men)).Color; + end Foreground; + + procedure Set_Background + (Men : in Menu; + Back : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Set_Menu_Back (Men : Menu; + Attr : C_Chtype) return C_Int; + pragma Import (C, Set_Menu_Back, "set_menu_back"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Color => Color, + Attr => Back); + Res : constant Eti_Error := Set_Menu_Back (Men, AttrChar_To_Chtype (Ch)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Background; + + procedure Background (Men : in Menu; + Back : out Character_Attribute_Set) + is + function Menu_Back (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Back, "menu_back"); + begin + Back := Chtype_To_AttrChar (Menu_Back (Men)).Attr; + end Background; + + procedure Background (Men : in Menu; + Back : out Character_Attribute_Set; + Color : out Color_Pair) + is + function Menu_Back (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Back, "menu_back"); + begin + Back := Chtype_To_AttrChar (Menu_Back (Men)).Attr; + Color := Chtype_To_AttrChar (Menu_Back (Men)).Color; + end Background; + + procedure Set_Grey (Men : in Menu; + Grey : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Set_Menu_Grey (Men : Menu; + Attr : C_Chtype) return C_Int; + pragma Import (C, Set_Menu_Grey, "set_menu_grey"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Color => Color, + Attr => Grey); + + Res : constant Eti_Error := Set_Menu_Grey (Men, AttrChar_To_Chtype (Ch)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Grey; + + procedure Grey (Men : in Menu; + Grey : out Character_Attribute_Set) + is + function Menu_Grey (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Grey, "menu_grey"); + begin + Grey := Chtype_To_AttrChar (Menu_Grey (Men)).Attr; + end Grey; + + procedure Grey (Men : in Menu; + Grey : out Character_Attribute_Set; + Color : out Color_Pair) + is + function Menu_Grey (Men : Menu) return C_Chtype; + pragma Import (C, Menu_Grey, "menu_grey"); + begin + Grey := Chtype_To_AttrChar (Menu_Grey (Men)).Attr; + Color := Chtype_To_AttrChar (Menu_Grey (Men)).Color; + end Grey; + + procedure Set_Pad_Character (Men : in Menu; + Pad : in Character := Space) + is + function Set_Menu_Pad (Men : Menu; + Ch : C_Int) return C_Int; + pragma Import (C, Set_Menu_Pad, "set_menu_pad"); + + Res : constant Eti_Error := Set_Menu_Pad (Men, + C_Int (Character'Pos (Pad))); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Pad_Character; + + procedure Pad_Character (Men : in Menu; + Pad : out Character) + is + function Menu_Pad (Men : Menu) return C_Int; + pragma Import (C, Menu_Pad, "menu_pad"); + begin + Pad := Character'Val (Menu_Pad (Men)); + end Pad_Character; +------------------------------------------------------------------------------- + procedure Set_Spacing (Men : in Menu; + Descr : in Column_Position := 0; + Row : in Line_Position := 0; + Col : in Column_Position := 0) + is + function Set_Spacing (Men : Menu; + D, R, C : C_Int) return C_Int; + pragma Import (C, Set_Spacing, "set_menu_spacing"); + + Res : constant Eti_Error := Set_Spacing (Men, + C_Int (Descr), + C_Int (Row), + C_Int (Col)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Spacing; + + procedure Spacing (Men : in Menu; + Descr : out Column_Position; + Row : out Line_Position; + Col : out Column_Position) + is + type C_Int_Access is access all C_Int; + function Get_Spacing (Men : Menu; + D, R, C : C_Int_Access) return C_Int; + pragma Import (C, Get_Spacing, "menu_spacing"); + + D, R, C : aliased C_Int; + Res : constant Eti_Error := Get_Spacing (Men, + D'Access, + R'Access, + C'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + else + Descr := Column_Position (D); + Row := Line_Position (R); + Col := Column_Position (C); + end if; + end Spacing; +------------------------------------------------------------------------------- + function Set_Pattern (Men : Menu; + Text : String) return Boolean + is + type Char_Ptr is access all Interfaces.C.char; + function Set_Pattern (Men : Menu; + Pattern : Char_Ptr) return C_Int; + pragma Import (C, Set_Pattern, "set_menu_pattern"); + + S : char_array (0 .. Text'Length); + L : size_t; + Res : Eti_Error; + begin + To_C (Text, S, L); + Res := Set_Pattern (Men, S (S'First)'Access); + case Res is + when E_No_Match => return False; + when E_Ok => return True; + when others => + Eti_Exception (Res); + return False; + end case; + end Set_Pattern; + + procedure Pattern (Men : in Menu; + Text : out String) + is + function Get_Pattern (Men : Menu) return chars_ptr; + pragma Import (C, Get_Pattern, "menu_pattern"); + begin + Fill_String (Get_Pattern (Men), Text); + end Pattern; +------------------------------------------------------------------------------- + procedure Set_Format (Men : in Menu; + Lines : in Line_Count; + Columns : in Column_Count) + is + function Set_Menu_Fmt (Men : Menu; + Lin : C_Int; + Col : C_Int) return C_Int; + pragma Import (C, Set_Menu_Fmt, "set_menu_format"); + + Res : constant Eti_Error := Set_Menu_Fmt (Men, + C_Int (Lines), + C_Int (Columns)); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Format; + + procedure Format (Men : in Menu; + Lines : out Line_Count; + Columns : out Column_Count) + is + type C_Int_Access is access all C_Int; + function Menu_Fmt (Men : Menu; + Y, X : C_Int_Access) return C_Int; + pragma Import (C, Menu_Fmt, "menu_format"); + + L, C : aliased C_Int; + Res : constant Eti_Error := Menu_Fmt (Men, L'Access, C'Access); + begin + if Res /= E_Ok then + Eti_Exception (Res); + else + Lines := Line_Count (L); + Columns := Column_Count (C); + end if; + end Format; +------------------------------------------------------------------------------- + procedure Set_Item_Init_Hook (Men : in Menu; + Proc : in Menu_Hook_Function) + is + function Set_Item_Init (Men : Menu; + Proc : Menu_Hook_Function) return C_Int; + pragma Import (C, Set_Item_Init, "set_item_init"); + + Res : constant Eti_Error := Set_Item_Init (Men, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Item_Init_Hook; + + procedure Set_Item_Term_Hook (Men : in Menu; + Proc : in Menu_Hook_Function) + is + function Set_Item_Term (Men : Menu; + Proc : Menu_Hook_Function) return C_Int; + pragma Import (C, Set_Item_Term, "set_item_term"); + + Res : constant Eti_Error := Set_Item_Term (Men, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Item_Term_Hook; + + procedure Set_Menu_Init_Hook (Men : in Menu; + Proc : in Menu_Hook_Function) + is + function Set_Menu_Init (Men : Menu; + Proc : Menu_Hook_Function) return C_Int; + pragma Import (C, Set_Menu_Init, "set_menu_init"); + + Res : constant Eti_Error := Set_Menu_Init (Men, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Menu_Init_Hook; + + procedure Set_Menu_Term_Hook (Men : in Menu; + Proc : in Menu_Hook_Function) + is + function Set_Menu_Term (Men : Menu; + Proc : Menu_Hook_Function) return C_Int; + pragma Import (C, Set_Menu_Term, "set_menu_term"); + + Res : constant Eti_Error := Set_Menu_Term (Men, Proc); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end Set_Menu_Term_Hook; + + function Get_Item_Init_Hook (Men : Menu) return Menu_Hook_Function + is + function Item_Init (Men : Menu) return Menu_Hook_Function; + pragma Import (C, Item_Init, "item_init"); + begin + return Item_Init (Men); + end Get_Item_Init_Hook; + + function Get_Item_Term_Hook (Men : Menu) return Menu_Hook_Function + is + function Item_Term (Men : Menu) return Menu_Hook_Function; + pragma Import (C, Item_Term, "item_term"); + begin + return Item_Term (Men); + end Get_Item_Term_Hook; + + function Get_Menu_Init_Hook (Men : Menu) return Menu_Hook_Function + is + function Menu_Init (Men : Menu) return Menu_Hook_Function; + pragma Import (C, Menu_Init, "menu_init"); + begin + return Menu_Init (Men); + end Get_Menu_Init_Hook; + + function Get_Menu_Term_Hook (Men : Menu) return Menu_Hook_Function + is + function Menu_Term (Men : Menu) return Menu_Hook_Function; + pragma Import (C, Menu_Term, "menu_term"); + begin + return Menu_Term (Men); + end Get_Menu_Term_Hook; +------------------------------------------------------------------------------- + procedure Redefine (Men : in Menu; + Items : in Item_Array_Access) + is + function Set_Items (Men : Menu; + Items : System.Address) return C_Int; + pragma Import (C, Set_Items, "set_menu_items"); + + Res : Eti_Error; + begin + pragma Assert (Items (Items'Last) = Null_Item); + if Items (Items'Last) /= Null_Item then + raise Menu_Exception; + else + Res := Set_Items (Men, Items.all'Address); + if Res /= E_Ok then + Eti_Exception (Res); + end if; + end if; + end Redefine; + + function Item_Count (Men : Menu) return Natural + is + function Count (Men : Menu) return C_Int; + pragma Import (C, Count, "item_count"); + begin + return Natural (Count (Men)); + end Item_Count; + + function Items (Men : Menu; + Index : Positive) return Item + is + use I_Array; + + function C_Mitems (Men : Menu) return Pointer; + pragma Import (C, C_Mitems, "menu_items"); + + P : Pointer := C_Mitems (Men); + begin + if P = null or else Index not in 1 .. Item_Count (Men) then + raise Menu_Exception; + else + P := P + ptrdiff_t (C_Int (Index) - 1); + return P.all; + end if; + end Items; + +------------------------------------------------------------------------------- + function Create (Items : Item_Array_Access) return Menu + is + function Newmenu (Items : System.Address) return Menu; + pragma Import (C, Newmenu, "new_menu"); + + M : Menu; + begin + pragma Assert (Items (Items'Last) = Null_Item); + if Items (Items'Last) /= Null_Item then + raise Menu_Exception; + else + M := Newmenu (Items.all'Address); + if M = Null_Menu then + raise Menu_Exception; + end if; + return M; + end if; + end Create; + + procedure Delete (Men : in out Menu) + is + function Free (Men : Menu) return C_Int; + pragma Import (C, Free, "free_menu"); + + Res : constant Eti_Error := Free (Men); + begin + if Res /= E_Ok then + Eti_Exception (Res); + end if; + Men := Null_Menu; + end Delete; + +------------------------------------------------------------------------------ + function Driver (Men : Menu; + Key : Key_Code) return Driver_Result + is + function Driver (Men : Menu; + Key : C_Int) return C_Int; + pragma Import (C, Driver, "menu_driver"); + + R : Eti_Error := Driver (Men, C_Int (Key)); + begin + if R /= E_Ok then + case R is + when E_Unknown_Command => return Unknown_Request; + when E_No_Match => return No_Match; + when E_Request_Denied | + E_Not_Selectable => return Request_Denied; + when others => + Eti_Exception (R); + end case; + end if; + return Menu_Ok; + end Driver; + + procedure Free (IA : in out Item_Array_Access; + Free_Items : in Boolean := False) + is + procedure Release is new Ada.Unchecked_Deallocation + (Item_Array, Item_Array_Access); + begin + if IA /= null and then Free_Items then + for I in IA'First .. (IA'Last - 1) loop + if (IA (I) /= Null_Item) then + Delete (IA (I)); + end if; + end loop; + end if; + Release (IA); + end Free; + +------------------------------------------------------------------------------- + function Default_Menu_Options return Menu_Option_Set + is + begin + return Get_Options (Null_Menu); + end Default_Menu_Options; + + function Default_Item_Options return Item_Option_Set + is + begin + return Get_Options (Null_Item); + end Default_Item_Options; +------------------------------------------------------------------------------- + +end Terminal_Interface.Curses.Menus; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-mouse.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-mouse.adb new file mode 100644 index 0000000..0cf3c55 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-mouse.adb @@ -0,0 +1,214 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Mouse -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with System; + +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; +with Interfaces.C; use Interfaces.C; +use Interfaces; + +package body Terminal_Interface.Curses.Mouse is + + use type System.Bit_Order; + use type Interfaces.C.int; + + function Has_Mouse return Boolean + is + function Mouse_Avail return C_Int; + pragma Import (C, Mouse_Avail, "_nc_has_mouse"); + begin + if Has_Key (Key_Mouse) or else Mouse_Avail /= 0 then + return True; + else + return False; + end if; + end Has_Mouse; + + function Get_Mouse return Mouse_Event + is + type Event_Access is access all Mouse_Event; + + function Getmouse (Ev : Event_Access) return C_Int; + pragma Import (C, Getmouse, "getmouse"); + + Event : aliased Mouse_Event; + begin + if Getmouse (Event'Access) = Curses_Err then + raise Curses_Exception; + end if; + return Event; + end Get_Mouse; + + procedure Register_Reportable_Event (Button : in Mouse_Button; + State : in Button_State; + Mask : in out Event_Mask) + is + Button_Nr : constant Natural := Mouse_Button'Pos (Button); + State_Nr : constant Natural := Button_State'Pos (State); + begin + if Button in Modifier_Keys and then State /= Pressed then + raise Curses_Exception; + else + if Button in Real_Buttons then + Mask := Mask or ((2 ** (6 * Button_Nr)) ** State_Nr); + else + Mask := Mask or (BUTTON_CTRL ** (Button_Nr - 4)); + end if; + end if; + end Register_Reportable_Event; + + procedure Register_Reportable_Events (Button : in Mouse_Button; + State : in Button_States; + Mask : in out Event_Mask) + is + begin + for S in Button_States'Range loop + if State (S) then + Register_Reportable_Event (Button, S, Mask); + end if; + end loop; + end Register_Reportable_Events; + + function Start_Mouse (Mask : Event_Mask := All_Events) + return Event_Mask + is + function MMask (M : Event_Mask; + O : access Event_Mask) return Event_Mask; + pragma Import (C, MMask, "mousemask"); + R : Event_Mask; + Old : aliased Event_Mask; + begin + R := MMask (Mask, Old'Access); + return Old; + end Start_Mouse; + + procedure End_Mouse (Mask : in Event_Mask := No_Events) + is + begin + null; + end End_Mouse; + + procedure Dispatch_Event (Mask : in Event_Mask; + Button : out Mouse_Button; + State : out Button_State); + + procedure Dispatch_Event (Mask : in Event_Mask; + Button : out Mouse_Button; + State : out Button_State) is + L : Event_Mask; + begin + Button := Alt; -- preset to non real button; + if (Mask and BUTTON1_EVENTS) /= 0 then + Button := Left; + elsif (Mask and BUTTON2_EVENTS) /= 0 then + Button := Middle; + elsif (Mask and BUTTON3_EVENTS) /= 0 then + Button := Right; + elsif (Mask and BUTTON4_EVENTS) /= 0 then + Button := Button4; + end if; + if Button in Real_Buttons then + L := 2 ** (6 * Mouse_Button'Pos (Button)); + for I in Button_State'Range loop + if (Mask and L) /= 0 then + State := I; + exit; + end if; + L := 2 * L; + end loop; + else + State := Pressed; + if (Mask and BUTTON_CTRL) /= 0 then + Button := Control; + elsif (Mask and BUTTON_SHIFT) /= 0 then + Button := Shift; + elsif (Mask and BUTTON_ALT) /= 0 then + Button := Alt; + end if; + end if; + end Dispatch_Event; + + procedure Get_Event (Event : in Mouse_Event; + Y : out Line_Position; + X : out Column_Position; + Button : out Mouse_Button; + State : out Button_State) + is + Mask : constant Event_Mask := Event.Bstate; + begin + X := Column_Position (Event.X); + Y := Line_Position (Event.Y); + Dispatch_Event (Mask, Button, State); + end Get_Event; + + procedure Unget_Mouse (Event : in Mouse_Event) + is + function Ungetmouse (Ev : Mouse_Event) return C_Int; + pragma Import (C, Ungetmouse, "ungetmouse"); + begin + if Ungetmouse (Event) = Curses_Err then + raise Curses_Exception; + end if; + end Unget_Mouse; + + function Enclosed_In_Window (Win : Window := Standard_Window; + Event : Mouse_Event) return Boolean + is + function Wenclose (Win : Window; Y : C_Int; X : C_Int) + return Curses_Bool; + pragma Import (C, Wenclose, "wenclose"); + begin + if Wenclose (Win, C_Int (Event.Y), C_Int (Event.X)) + = Curses_Bool_False then + return False; + else + return True; + end if; + end Enclosed_In_Window; + + function Mouse_Interval (Msec : Natural := 200) return Natural + is + function Mouseinterval (Msec : C_Int) return C_Int; + pragma Import (C, Mouseinterval, "mouseinterval"); + begin + return Natural (Mouseinterval (C_Int (Msec))); + end Mouse_Interval; + +end Terminal_Interface.Curses.Mouse; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-panels-user_data.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-panels-user_data.adb new file mode 100644 index 0000000..1e18a0d --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-panels-user_data.adb @@ -0,0 +1,78 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Panels.User_Data -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Interfaces.C; +with Terminal_Interface.Curses.Aux; +use Terminal_Interface.Curses.Aux; +with Terminal_Interface.Curses.Panels; +use Terminal_Interface.Curses.Panels; + +package body Terminal_Interface.Curses.Panels.User_Data is + + use type Interfaces.C.int; + + procedure Set_User_Data (Pan : in Panel; + Data : in User_Access) + is + function Set_Panel_Userptr (Pan : Panel; + Addr : User_Access) return C_Int; + pragma Import (C, Set_Panel_Userptr, "set_panel_userptr"); + begin + if Set_Panel_Userptr (Pan, Data) = Curses_Err then + raise Panel_Exception; + end if; + end Set_User_Data; + + function Get_User_Data (Pan : in Panel) return User_Access + is + function Panel_Userptr (Pan : Panel) return User_Access; + pragma Import (C, Panel_Userptr, "panel_userptr"); + begin + return Panel_Userptr (Pan); + end Get_User_Data; + + procedure Get_User_Data (Pan : in Panel; + Data : out User_Access) + is + begin + Data := Get_User_Data (Pan); + end Get_User_Data; + +end Terminal_Interface.Curses.Panels.User_Data; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-panels.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-panels.adb new file mode 100644 index 0000000..ebbaf2a --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-panels.adb @@ -0,0 +1,164 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Panels -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Aux; use Terminal_Interface.Curses.Aux; +with Interfaces.C; + +package body Terminal_Interface.Curses.Panels is + + use type Interfaces.C.int; + + function Create (Win : Window) return Panel + is + function Newpanel (Win : Window) return Panel; + pragma Import (C, Newpanel, "new_panel"); + + Pan : Panel; + begin + Pan := Newpanel (Win); + if Pan = Null_Panel then + raise Panel_Exception; + end if; + return Pan; + end Create; + + procedure Bottom (Pan : in Panel) + is + function Bottompanel (Pan : Panel) return C_Int; + pragma Import (C, Bottompanel, "bottom_panel"); + begin + if Bottompanel (Pan) = Curses_Err then + raise Panel_Exception; + end if; + end Bottom; + + procedure Top (Pan : in Panel) + is + function Toppanel (Pan : Panel) return C_Int; + pragma Import (C, Toppanel, "top_panel"); + begin + if Toppanel (Pan) = Curses_Err then + raise Panel_Exception; + end if; + end Top; + + procedure Show (Pan : in Panel) + is + function Showpanel (Pan : Panel) return C_Int; + pragma Import (C, Showpanel, "show_panel"); + begin + if Showpanel (Pan) = Curses_Err then + raise Panel_Exception; + end if; + end Show; + + procedure Hide (Pan : in Panel) + is + function Hidepanel (Pan : Panel) return C_Int; + pragma Import (C, Hidepanel, "hide_panel"); + begin + if Hidepanel (Pan) = Curses_Err then + raise Panel_Exception; + end if; + end Hide; + + function Get_Window (Pan : Panel) return Window + is + function Panel_Win (Pan : Panel) return Window; + pragma Import (C, Panel_Win, "panel_window"); + + Win : Window := Panel_Win (Pan); + begin + if Win = Null_Window then + raise Panel_Exception; + end if; + return Win; + end Get_Window; + + procedure Replace (Pan : in Panel; + Win : in Window) + is + function Replace_Pan (Pan : Panel; + Win : Window) return C_Int; + pragma Import (C, Replace_Pan, "replace_panel"); + begin + if Replace_Pan (Pan, Win) = Curses_Err then + raise Panel_Exception; + end if; + end Replace; + + procedure Move (Pan : in Panel; + Line : in Line_Position; + Column : in Column_Position) + is + function Move (Pan : Panel; + Line : C_Int; + Column : C_Int) return C_Int; + pragma Import (C, Move, "move_panel"); + begin + if Move (Pan, C_Int (Line), C_Int (Column)) = Curses_Err then + raise Panel_Exception; + end if; + end Move; + + function Is_Hidden (Pan : Panel) return Boolean + is + function Panel_Hidden (Pan : Panel) return C_Int; + pragma Import (C, Panel_Hidden, "panel_hidden"); + begin + if Panel_Hidden (Pan) = Curses_False then + return False; + else + return True; + end if; + end Is_Hidden; + + procedure Delete (Pan : in out Panel) + is + function Del_Panel (Pan : Panel) return C_Int; + pragma Import (C, Del_Panel, "del_panel"); + begin + if Del_Panel (Pan) = Curses_Err then + raise Panel_Exception; + end if; + Pan := Null_Panel; + end Delete; + +end Terminal_Interface.Curses.Panels; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.adb new file mode 100644 index 0000000..20b7609 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.adb @@ -0,0 +1,128 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Aux -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package body Terminal_Interface.Curses.Text_IO.Aux is + + procedure Put_Buf + (Win : in Window; + Buf : in String; + Width : in Field; + Signal : in Boolean := True; + Ljust : in Boolean := False) + is + L : Field; + Len : Field; + W : Field := Width; + LC : Line_Count; + CC : Column_Count; + Y : Line_Position; + X : Column_Position; + + procedure Output (From, To : Field); + + procedure Output (From, To : Field) + is + begin + if Len > 0 then + if W = 0 then + W := Len; + end if; + if Len > W then + -- LRM A10.6 (7) says this + W := Len; + end if; + + pragma Assert (Len <= W); + Get_Size (Win, LC, CC); + if Column_Count (Len) > CC then + if Signal then + raise Layout_Error; + else + return; + end if; + else + if Len < W and then not Ljust then + declare + Filler : constant String (1 .. (W - Len)) + := (others => ' '); + begin + Put (Win, Filler); + end; + end if; + Get_Cursor_Position (Win, Y, X); + if (X + Column_Position (Len)) > CC then + New_Line (Win); + end if; + Put (Win, Buf (From .. To)); + if Len < W and then Ljust then + declare + Filler : constant String (1 .. (W - Len)) + := (others => ' '); + begin + Put (Win, Filler); + end; + end if; + end if; + end if; + end Output; + + begin + pragma Assert (Win /= Null_Window); + if Ljust then + L := 1; + for I in 1 .. Buf'Length loop + exit when Buf (L) = ' '; + L := L + 1; + end loop; + Len := L - 1; + Output (1, Len); + else -- input buffer is not left justified + L := Buf'Length; + for I in 1 .. Buf'Length loop + exit when Buf (L) = ' '; + L := L - 1; + end loop; + Len := Buf'Length - L; + Output (L + 1, Buf'Length); + end if; + end Put_Buf; + +end Terminal_Interface.Curses.Text_IO.Aux; + diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.ads new file mode 100644 index 0000000..0148053 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-aux.ads @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Aux -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +private package Terminal_Interface.Curses.Text_IO.Aux is + -- pragma Preelaborate (Aux); + + -- This routine is called from the Text_IO output routines for numeric + -- and enumeration types. + -- + procedure Put_Buf + (Win : in Window; -- The output window + Buf : in String; -- The buffer containing the text + Width : in Field; -- The width of the output field + Signal : in Boolean := True; -- If true, we raise Layout_Error + Ljust : in Boolean := False); -- The Buf is left justified + +end Terminal_Interface.Curses.Text_IO.Aux; + diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.adb new file mode 100644 index 0000000..2ed8b56 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.adb @@ -0,0 +1,73 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Complex_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Terminal_Interface.Curses.Text_IO.Float_IO; + +package body Terminal_Interface.Curses.Text_IO.Complex_IO is + + package FIO is new + Terminal_Interface.Curses.Text_IO.Float_IO (Complex_Types.Real'Base); + + procedure Put + (Win : in Window; + Item : in Complex; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + begin + Put (Win, '('); + FIO.Put (Win, Item.Re, Fore, Aft, Exp); + Put (Win, ','); + FIO.Put (Win, Item.Im, Fore, Aft, Exp); + Put (Win, ')'); + end Put; + + procedure Put + (Item : in Complex; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + begin + Put (Get_Window, Item, Fore, Aft, Exp); + end Put; + +end Terminal_Interface.Curses.Text_IO.Complex_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.ads new file mode 100644 index 0000000..c83a005 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-complex_io.ads @@ -0,0 +1,70 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Complex_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Numerics.Generic_Complex_Types; + +generic + with package Complex_Types is new Ada.Numerics.Generic_Complex_Types (<>); + +package Terminal_Interface.Curses.Text_IO.Complex_IO is + + use Complex_Types; + + Default_Fore : Field := 2; + Default_Aft : Field := Real'Digits - 1; + Default_Exp : Field := 3; + + procedure Put + (Win : in Window; + Item : in Complex; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + + procedure Put + (Item : in Complex; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Complex_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.adb new file mode 100644 index 0000000..a9cbbce --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.adb @@ -0,0 +1,75 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Decimal_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Decimal_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package DIO is new Ada.Text_IO.Decimal_IO (Num); + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + Buf : String (1 .. Field'Last); + Len : Field := Fore + 1 + Aft; + begin + if Exp > 0 then + Len := Len + 1 + Exp; + end if; + DIO.Put (Buf, Item, Aft, Exp); + Aux.Put_Buf (Win, Buf, Len, False); + end Put; + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) is + begin + Put (Get_Window, Item, Fore, Aft, Exp); + end Put; + +end Terminal_Interface.Curses.Text_IO.Decimal_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.ads new file mode 100644 index 0000000..73d243e --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-decimal_io.ads @@ -0,0 +1,66 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Decimal_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Num is delta <> digits <>; + +package Terminal_Interface.Curses.Text_IO.Decimal_IO is + + Default_Fore : Field := Num'Fore; + Default_Aft : Field := Num'Aft; + Default_Exp : Field := 0; + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Decimal_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb new file mode 100644 index 0000000..5bf1332 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb @@ -0,0 +1,80 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Enumeration_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Ada.Characters.Handling; use Ada.Characters.Handling; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Enumeration_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package EIO is new Ada.Text_IO.Enumeration_IO (Enum); + + procedure Put + (Win : in Window; + Item : in Enum; + Width : in Field := Default_Width; + Set : in Type_Set := Default_Setting) + is + Buf : String (1 .. Field'Last); + Tset : Ada.Text_IO.Type_Set; + begin + if Set /= Mixed_Case then + Tset := Ada.Text_IO.Type_Set'Val (Type_Set'Pos (Set)); + else + Tset := Ada.Text_IO.Lower_Case; + end if; + EIO.Put (Buf, Item, Tset); + if Set = Mixed_Case then + Buf (Buf'First) := To_Upper (Buf (Buf'First)); + end if; + Aux.Put_Buf (Win, Buf, Width, True, True); + end Put; + + procedure Put + (Item : in Enum; + Width : in Field := Default_Width; + Set : in Type_Set := Default_Setting) + is + begin + Put (Get_Window, Item, Width, Set); + end Put; + +end Terminal_Interface.Curses.Text_IO.Enumeration_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads new file mode 100644 index 0000000..86f2173 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads @@ -0,0 +1,63 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Enumeration_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Enum is (<>); + +package Terminal_Interface.Curses.Text_IO.Enumeration_IO is + + Default_Width : Field := 0; + Default_Setting : Type_Set := Mixed_Case; + + procedure Put + (Win : in Window; + Item : in Enum; + Width : in Field := Default_Width; + Set : in Type_Set := Default_Setting); + + procedure Put + (Item : in Enum; + Width : in Field := Default_Width; + Set : in Type_Set := Default_Setting); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Enumeration_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.adb new file mode 100644 index 0000000..0bd26fa --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.adb @@ -0,0 +1,75 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Fixed_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Fixed_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package FIXIO is new Ada.Text_IO.Fixed_IO (Num); + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + Buf : String (1 .. Field'Last); + Len : Field := Fore + 1 + Aft; + begin + if Exp > 0 then + Len := Len + 1 + Exp; + end if; + FIXIO.Put (Buf, Item, Aft, Exp); + Aux.Put_Buf (Win, Buf, Len, False); + end Put; + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) is + begin + Put (Get_Window, Item, Fore, Aft, Exp); + end Put; + +end Terminal_Interface.Curses.Text_IO.Fixed_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.ads new file mode 100644 index 0000000..83c5a16 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-fixed_io.ads @@ -0,0 +1,66 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Fixed_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Num is delta <>; + +package Terminal_Interface.Curses.Text_IO.Fixed_IO is + + Default_Fore : Field := Num'Fore; + Default_Aft : Field := Num'Aft; + Default_Exp : Field := 0; + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Fixed_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.adb new file mode 100644 index 0000000..9b24daa --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.adb @@ -0,0 +1,76 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Float_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Float_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package FIO is new Ada.Text_IO.Float_IO (Num); + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + Buf : String (1 .. Field'Last); + Len : Field := Fore + 1 + Aft; + begin + if Exp > 0 then + Len := Len + 1 + Exp; + end if; + FIO.Put (Buf, Item, Aft, Exp); + Aux.Put_Buf (Win, Buf, Len, False); + end Put; + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp) + is + begin + Put (Get_Window, Item, Fore, Aft, Exp); + end Put; + +end Terminal_Interface.Curses.Text_IO.Float_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.ads new file mode 100644 index 0000000..01fa996 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-float_io.ads @@ -0,0 +1,66 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Float_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Num is digits <>; + +package Terminal_Interface.Curses.Text_IO.Float_IO is + + Default_Fore : Field := 2; + Default_Aft : Field := Num'Digits - 1; + Default_Exp : Field := 3; + + procedure Put + (Win : in Window; + Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + + procedure Put + (Item : in Num; + Fore : in Field := Default_Fore; + Aft : in Field := Default_Aft; + Exp : in Field := Default_Exp); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Float_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.adb new file mode 100644 index 0000000..b7bd495 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.adb @@ -0,0 +1,70 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Integer_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Integer_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package IIO is new Ada.Text_IO.Integer_IO (Num); + + procedure Put + (Win : in Window; + Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base) + is + Buf : String (1 .. Field'Last); + begin + IIO.Put (Buf, Item, Base); + Aux.Put_Buf (Win, Buf, Width); + end Put; + + procedure Put + (Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base) + is + begin + Put (Get_Window, Item, Width, Base); + end Put; + +end Terminal_Interface.Curses.Text_IO.Integer_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.ads new file mode 100644 index 0000000..a4e430e --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-integer_io.ads @@ -0,0 +1,63 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Integer_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Num is range <>; + +package Terminal_Interface.Curses.Text_IO.Integer_IO is + + Default_Width : Field := Num'Width; + Default_Base : Number_Base := 10; + + procedure Put + (Win : in Window; + Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base); + + procedure Put + (Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Integer_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.adb new file mode 100644 index 0000000..aff0666 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.adb @@ -0,0 +1,70 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Modular_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Terminal_Interface.Curses.Text_IO.Aux; + +package body Terminal_Interface.Curses.Text_IO.Modular_IO is + + package Aux renames Terminal_Interface.Curses.Text_IO.Aux; + package MIO is new Ada.Text_IO.Modular_IO (Num); + + procedure Put + (Win : in Window; + Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base) + is + Buf : String (1 .. Field'Last); + begin + MIO.Put (Buf, Item, Base); + Aux.Put_Buf (Win, Buf, Width); + end Put; + + procedure Put + (Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base) + is + begin + Put (Get_Window, Item, Width, Base); + end Put; + +end Terminal_Interface.Curses.Text_IO.Modular_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.ads new file mode 100644 index 0000000..9033f7f --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io-modular_io.ads @@ -0,0 +1,63 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO.Modular_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +generic + type Num is mod <>; + +package Terminal_Interface.Curses.Text_IO.Modular_IO is + + Default_Width : Field := Num'Width; + Default_Base : Number_Base := 10; + + procedure Put + (Win : in Window; + Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base); + + procedure Put + (Item : in Num; + Width : in Field := Default_Width; + Base : in Number_Base := Default_Base); + +private + pragma Inline (Put); + +end Terminal_Interface.Curses.Text_IO.Modular_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.adb new file mode 100644 index 0000000..ed7a4c8 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.adb @@ -0,0 +1,336 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package body Terminal_Interface.Curses.Text_IO is + + Default_Window : Window := Null_Window; + + procedure Set_Window (Win : in Window) + is + begin + Default_Window := Win; + end Set_Window; + + function Get_Window return Window + is + begin + if Default_Window = Null_Window then + return Standard_Window; + else + return Default_Window; + end if; + end Get_Window; + pragma Inline (Get_Window); + + procedure Flush (Win : in Window) + is + begin + Refresh (Win); + end Flush; + + procedure Flush + is + begin + Flush (Get_Window); + end Flush; + + -------------------------------------------- + -- Specification of line and page lengths -- + -------------------------------------------- + + -- There are no set routines in this package. I assume, that you allocate + -- the window with an appropriate size. + -- A scroll-window is interpreted as an page with unbounded page length, + -- i.e. it returns the conventional 0 as page length. + + function Line_Length (Win : in Window) return Count + is + N_Lines : Line_Count; + N_Cols : Column_Count; + begin + Get_Size (Win, N_Lines, N_Cols); + if Natural (N_Cols) > Natural (Count'Last) then + raise Layout_Error; + end if; + return Count (N_Cols); + end Line_Length; + + function Line_Length return Count + is + begin + return Line_Length (Get_Window); + end Line_Length; + + function Page_Length (Win : in Window) return Count + is + N_Lines : Line_Count; + N_Cols : Column_Count; + begin + if Scrolling_Allowed (Win) then + return 0; + else + Get_Size (Win, N_Lines, N_Cols); + if Natural (N_Lines) > Natural (Count'Last) then + raise Layout_Error; + end if; + return Count (N_Lines); + end if; + end Page_Length; + + function Page_Length return Count + is + begin + return Page_Length (Get_Window); + end Page_Length; + + ------------------------------------ + -- Column, Line, and Page Control -- + ------------------------------------ + procedure New_Line (Win : in Window; Spacing : in Positive_Count := 1) + is + P_Size : constant Count := Page_Length (Win); + begin + if Spacing not in Positive_Count then + raise Constraint_Error; + end if; + + for I in 1 .. Spacing loop + if P_Size > 0 and then Line (Win) >= P_Size then + New_Page (Win); + else + Add (Win, ASCII.LF); + end if; + end loop; + end New_Line; + + procedure New_Line (Spacing : in Positive_Count := 1) + is + begin + New_Line (Get_Window, Spacing); + end New_Line; + + procedure New_Page (Win : in Window) + is + begin + Clear (Win); + end New_Page; + + procedure New_Page + is + begin + New_Page (Get_Window); + end New_Page; + + procedure Set_Col (Win : in Window; To : in Positive_Count) + is + Y : Line_Position; + X1 : Column_Position; + X2 : Column_Position; + N : Natural; + begin + if To not in Positive_Count then + raise Constraint_Error; + end if; + + Get_Cursor_Position (Win, Y, X1); + N := Natural (To); N := N - 1; + X2 := Column_Position (N); + if X1 > X2 then + New_Line (Win, 1); + X1 := 0; + end if; + if X1 < X2 then + declare + Filler : constant String (Integer (X1) .. (Integer (X2) - 1)) + := (others => ' '); + begin + Put (Win, Filler); + end; + end if; + end Set_Col; + + procedure Set_Col (To : in Positive_Count) + is + begin + Set_Col (Get_Window, To); + end Set_Col; + + procedure Set_Line (Win : in Window; To : in Positive_Count) + is + Y1 : Line_Position; + Y2 : Line_Position; + X : Column_Position; + N : Natural; + begin + if To not in Positive_Count then + raise Constraint_Error; + end if; + + Get_Cursor_Position (Win, Y1, X); + N := Natural (To); N := N - 1; + Y2 := Line_Position (N); + if Y2 < Y1 then + New_Page (Win); + Y1 := 0; + end if; + if Y1 < Y2 then + New_Line (Win, Positive_Count (Y2 - Y1)); + end if; + end Set_Line; + + procedure Set_Line (To : in Positive_Count) + is + begin + Set_Line (Get_Window, To); + end Set_Line; + + function Col (Win : in Window) return Positive_Count + is + Y : Line_Position; + X : Column_Position; + N : Natural; + begin + Get_Cursor_Position (Win, Y, X); + N := Natural (X); N := N + 1; + if N > Natural (Count'Last) then + raise Layout_Error; + end if; + return Positive_Count (N); + end Col; + + function Col return Positive_Count + is + begin + return Col (Get_Window); + end Col; + + function Line (Win : in Window) return Positive_Count + is + Y : Line_Position; + X : Column_Position; + N : Natural; + begin + Get_Cursor_Position (Win, Y, X); + N := Natural (Y); N := N + 1; + if N > Natural (Count'Last) then + raise Layout_Error; + end if; + return Positive_Count (N); + end Line; + + function Line return Positive_Count + is + begin + return Line (Get_Window); + end Line; + + ----------------------- + -- Characters Output -- + ----------------------- + + procedure Put (Win : in Window; Item : in Character) + is + P_Size : constant Count := Page_Length (Win); + Y : Line_Position; + X : Column_Position; + L : Line_Count; + C : Column_Count; + begin + if P_Size > 0 then + Get_Cursor_Position (Win, Y, X); + Get_Size (Win, L, C); + if (Y + 1) = L and then (X + 1) = C then + New_Page (Win); + end if; + end if; + Add (Win, Item); + end Put; + + procedure Put (Item : in Character) + is + begin + Put (Get_Window, Item); + end Put; + + -------------------- + -- Strings-Output -- + -------------------- + + procedure Put (Win : in Window; Item : in String) + is + P_Size : constant Count := Page_Length (Win); + Y : Line_Position; + X : Column_Position; + L : Line_Count; + C : Column_Count; + begin + if P_Size > 0 then + Get_Cursor_Position (Win, Y, X); + Get_Size (Win, L, C); + if (Y + 1) = L and then (X + 1 + Item'Length) >= C then + New_Page (Win); + end if; + end if; + Add (Win, Item); + end Put; + + procedure Put (Item : in String) + is + begin + Put (Get_Window, Item); + end Put; + + procedure Put_Line + (Win : in Window; + Item : in String) + is + begin + Put (Win, Item); + New_Line (Win, 1); + end Put_Line; + + procedure Put_Line + (Item : in String) + is + begin + Put_Line (Get_Window, Item); + end Put_Line; + +end Terminal_Interface.Curses.Text_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.ads b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.ads new file mode 100644 index 0000000..fa659a8 --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses-text_io.ads @@ -0,0 +1,136 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses.Text_IO -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with Ada.Text_IO; +with Ada.IO_Exceptions; + +package Terminal_Interface.Curses.Text_IO is + + use type Ada.Text_IO.Count; + subtype Count is Ada.Text_IO.Count; + subtype Positive_Count is Count range 1 .. Count'Last; + + subtype Field is Ada.Text_IO.Field; + subtype Number_Base is Integer range 2 .. 16; + + type Type_Set is (Lower_Case, Upper_Case, Mixed_Case); + + -- For most of the routines you will see a version without a Window + -- type parameter. They will operate on a default window, which can + -- be set by the user. It is initially equal to Standard_Window. + + procedure Set_Window (Win : in Window); + -- Set Win as the default window + + function Get_Window return Window; + -- Get the current default window + + procedure Flush (Win : in Window); + procedure Flush; + + -------------------------------------------- + -- Specification of line and page lengths -- + -------------------------------------------- + + -- There are no set routines in this package. I assume, that you allocate + -- the window with an appropriate size. + -- A scroll-window is interpreted as an page with unbounded page length, + -- i.e. it returns the conventional 0 as page length. + + function Line_Length (Win : in Window) return Count; + function Line_Length return Count; + + function Page_Length (Win : in Window) return Count; + function Page_Length return Count; + + ------------------------------------ + -- Column, Line, and Page Control -- + ------------------------------------ + procedure New_Line (Win : in Window; Spacing : in Positive_Count := 1); + procedure New_Line (Spacing : in Positive_Count := 1); + + procedure New_Page (Win : in Window); + procedure New_Page; + + procedure Set_Col (Win : in Window; To : in Positive_Count); + procedure Set_Col (To : in Positive_Count); + + procedure Set_Line (Win : in Window; To : in Positive_Count); + procedure Set_Line (To : in Positive_Count); + + function Col (Win : in Window) return Positive_Count; + function Col return Positive_Count; + + function Line (Win : in Window) return Positive_Count; + function Line return Positive_Count; + + ----------------------- + -- Characters-Output -- + ----------------------- + + procedure Put (Win : in Window; Item : in Character); + procedure Put (Item : in Character); + + -------------------- + -- Strings-Output -- + -------------------- + + procedure Put (Win : in Window; Item : in String); + procedure Put (Item : in String); + + procedure Put_Line + (Win : in Window; + Item : in String); + + procedure Put_Line + (Item : in String); + + -- Exceptions + + Status_Error : exception renames Ada.IO_Exceptions.Status_Error; + Mode_Error : exception renames Ada.IO_Exceptions.Mode_Error; + Name_Error : exception renames Ada.IO_Exceptions.Name_Error; + Use_Error : exception renames Ada.IO_Exceptions.Use_Error; + Device_Error : exception renames Ada.IO_Exceptions.Device_Error; + End_Error : exception renames Ada.IO_Exceptions.End_Error; + Data_Error : exception renames Ada.IO_Exceptions.Data_Error; + Layout_Error : exception renames Ada.IO_Exceptions.Layout_Error; + +end Terminal_Interface.Curses.Text_IO; diff --git a/ncurses-5.2/Ada95/src/terminal_interface-curses.adb b/ncurses-5.2/Ada95/src/terminal_interface-curses.adb new file mode 100644 index 0000000..0ca29ea --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface-curses.adb @@ -0,0 +1,2414 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface.Curses -- +-- -- +-- B O D Y -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +with System; + +with Terminal_Interface.Curses.Aux; +with Interfaces.C; use Interfaces.C; +with Interfaces.C.Strings; use Interfaces.C.Strings; +with Interfaces.C.Pointers; +with Ada.Characters.Handling; use Ada.Characters.Handling; +with Ada.Strings.Fixed; +with Ada.Unchecked_Conversion; + +package body Terminal_Interface.Curses is + + use Aux; + use type System.Bit_Order; + + package ASF renames Ada.Strings.Fixed; + + type chtype_array is array (size_t range <>) + of aliased Attributed_Character; + pragma Convention (C, chtype_array); + +------------------------------------------------------------------------------ + generic + type Element is (<>); + function W_Get_Element (Win : in Window; + Offset : in Natural) return Element; + + function W_Get_Element (Win : in Window; + Offset : in Natural) return Element is + type E_Array is array (Natural range <>) of aliased Element; + package C_E_Array is new + Interfaces.C.Pointers (Natural, Element, E_Array, Element'Val (0)); + use C_E_Array; + + function To_Pointer is new + Ada.Unchecked_Conversion (Window, Pointer); + + P : Pointer := To_Pointer (Win); + begin + if Win = Null_Window then + raise Curses_Exception; + else + P := P + ptrdiff_t (Offset); + return P.all; + end if; + end W_Get_Element; + + function W_Get_Int is new W_Get_Element (C_Int); + function W_Get_Short is new W_Get_Element (C_Short); + function W_Get_Byte is new W_Get_Element (Interfaces.C.unsigned_char); + +------------------------------------------------------------------------------ + function Key_Name (Key : in Real_Key_Code) return String + is + function Keyname (K : C_Int) return chars_ptr; + pragma Import (C, Keyname, "keyname"); + + Ch : Character; + begin + if Key <= Character'Pos (Character'Last) then + Ch := Character'Val (Key); + if Is_Control (Ch) then + return Un_Control (Attributed_Character'(Ch => Ch, + Color => Color_Pair'First, + Attr => Normal_Video)); + elsif Is_Graphic (Ch) then + declare + S : String (1 .. 1); + begin + S (1) := Ch; + return S; + end; + else + return ""; + end if; + else + return Fill_String (Keyname (C_Int (Key))); + end if; + end Key_Name; + + procedure Key_Name (Key : in Real_Key_Code; + Name : out String) + is + begin + ASF.Move (Key_Name (Key), Name); + end Key_Name; + +------------------------------------------------------------------------------ + procedure Init_Screen + is + function Initscr return Window; + pragma Import (C, Initscr, "initscr"); + + W : Window; + begin + W := Initscr; + if W = Null_Window then + raise Curses_Exception; + end if; + end Init_Screen; + + procedure End_Windows + is + function Endwin return C_Int; + pragma Import (C, Endwin, "endwin"); + begin + if Endwin = Curses_Err then + raise Curses_Exception; + end if; + end End_Windows; + + function Is_End_Window return Boolean + is + function Isendwin return Curses_Bool; + pragma Import (C, Isendwin, "isendwin"); + begin + if Isendwin = Curses_Bool_False then + return False; + else + return True; + end if; + end Is_End_Window; +------------------------------------------------------------------------------ + procedure Move_Cursor (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position) + is + function Wmove (Win : Window; + Line : C_Int; + Column : C_Int + ) return C_Int; + pragma Import (C, Wmove, "wmove"); + begin + if Wmove (Win, C_Int (Line), C_Int (Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Move_Cursor; +------------------------------------------------------------------------------ + procedure Add (Win : in Window := Standard_Window; + Ch : in Attributed_Character) + is + function Waddch (W : Window; + Ch : C_Chtype) return C_Int; + pragma Import (C, Waddch, "waddch"); + begin + if Waddch (Win, AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Add; + + procedure Add (Win : in Window := Standard_Window; + Ch : in Character) + is + begin + Add (Win, + Attributed_Character'(Ch => Ch, + Color => Color_Pair'First, + Attr => Normal_Video)); + end Add; + + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Attributed_Character) + is + function mvwaddch (W : Window; + Y : C_Int; + X : C_Int; + Ch : C_Chtype) return C_Int; + pragma Import (C, mvwaddch, "mvwaddch"); + begin + if mvwaddch (Win, C_Int (Line), + C_Int (Column), + AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Add; + + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Character) + is + begin + Add (Win, + Line, + Column, + Attributed_Character'(Ch => Ch, + Color => Color_Pair'First, + Attr => Normal_Video)); + end Add; + + procedure Add_With_Immediate_Echo + (Win : in Window := Standard_Window; + Ch : in Attributed_Character) + is + function Wechochar (W : Window; + Ch : C_Chtype) return C_Int; + pragma Import (C, Wechochar, "wechochar"); + begin + if Wechochar (Win, AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Add_With_Immediate_Echo; + + procedure Add_With_Immediate_Echo + (Win : in Window := Standard_Window; + Ch : in Character) + is + begin + Add_With_Immediate_Echo + (Win, + Attributed_Character'(Ch => Ch, + Color => Color_Pair'First, + Attr => Normal_Video)); + end Add_With_Immediate_Echo; +------------------------------------------------------------------------------ + function Create (Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window + is + function Newwin (Number_Of_Lines : C_Int; + Number_Of_Columns : C_Int; + First_Line_Position : C_Int; + First_Column_Position : C_Int) return Window; + pragma Import (C, Newwin, "newwin"); + + W : Window; + begin + W := Newwin (C_Int (Number_Of_Lines), + C_Int (Number_Of_Columns), + C_Int (First_Line_Position), + C_Int (First_Column_Position)); + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end Create; + + procedure Delete (Win : in out Window) + is + function Wdelwin (W : Window) return C_Int; + pragma Import (C, Wdelwin, "delwin"); + begin + if Wdelwin (Win) = Curses_Err then + raise Curses_Exception; + end if; + Win := Null_Window; + end Delete; + + function Sub_Window + (Win : Window := Standard_Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window + is + function Subwin + (Win : Window; + Number_Of_Lines : C_Int; + Number_Of_Columns : C_Int; + First_Line_Position : C_Int; + First_Column_Position : C_Int) return Window; + pragma Import (C, Subwin, "subwin"); + + W : Window; + begin + W := Subwin (Win, + C_Int (Number_Of_Lines), + C_Int (Number_Of_Columns), + C_Int (First_Line_Position), + C_Int (First_Column_Position)); + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end Sub_Window; + + function Derived_Window + (Win : Window := Standard_Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window + is + function Derwin + (Win : Window; + Number_Of_Lines : C_Int; + Number_Of_Columns : C_Int; + First_Line_Position : C_Int; + First_Column_Position : C_Int) return Window; + pragma Import (C, Derwin, "derwin"); + + W : Window; + begin + W := Derwin (Win, + C_Int (Number_Of_Lines), + C_Int (Number_Of_Columns), + C_Int (First_Line_Position), + C_Int (First_Column_Position)); + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end Derived_Window; + + function Duplicate (Win : Window) return Window + is + function Dupwin (Win : Window) return Window; + pragma Import (C, Dupwin, "dupwin"); + + W : Window := Dupwin (Win); + begin + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end Duplicate; + + procedure Move_Window (Win : in Window; + Line : in Line_Position; + Column : in Column_Position) + is + function Mvwin (Win : Window; + Line : C_Int; + Column : C_Int) return C_Int; + pragma Import (C, Mvwin, "mvwin"); + begin + if Mvwin (Win, C_Int (Line), C_Int (Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Move_Window; + + procedure Move_Derived_Window (Win : in Window; + Line : in Line_Position; + Column : in Column_Position) + is + function Mvderwin (Win : Window; + Line : C_Int; + Column : C_Int) return C_Int; + pragma Import (C, Mvderwin, "mvderwin"); + begin + if Mvderwin (Win, C_Int (Line), C_Int (Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Move_Derived_Window; + + procedure Set_Synch_Mode (Win : in Window := Standard_Window; + Mode : in Boolean := False) + is + function Syncok (Win : Window; + Mode : Curses_Bool) return C_Int; + pragma Import (C, Syncok, "syncok"); + begin + if Syncok (Win, Curses_Bool (Boolean'Pos (Mode))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Synch_Mode; +------------------------------------------------------------------------------ + procedure Add (Win : in Window := Standard_Window; + Str : in String; + Len : in Integer := -1) + is + type Char_Ptr is access all Interfaces.C.char; + function Waddnstr (Win : Window; + Str : Char_Ptr; + Len : C_Int := -1) return C_Int; + pragma Import (C, Waddnstr, "waddnstr"); + + Txt : char_array (0 .. Str'Length); + Length : size_t; + begin + To_C (Str, Txt, Length); + if Waddnstr (Win, Txt (Txt'First)'Access, C_Int (Len)) = Curses_Err then + raise Curses_Exception; + end if; + end Add; + + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in String; + Len : in Integer := -1) + is + begin + Move_Cursor (Win, Line, Column); + Add (Win, Str, Len); + end Add; +------------------------------------------------------------------------------ + procedure Add + (Win : in Window := Standard_Window; + Str : in Attributed_String; + Len : in Integer := -1) + is + type Chtype_Ptr is access all Attributed_Character; + function Waddchnstr (Win : Window; + Str : Chtype_Ptr; + Len : C_Int := -1) return C_Int; + pragma Import (C, Waddchnstr, "waddchnstr"); + + Txt : chtype_array (0 .. Str'Length); + begin + for Length in 1 .. size_t (Str'Length) loop + Txt (Length - 1) := Str (Natural (Length)); + end loop; + Txt (Str'Length) := Default_Character; + if Waddchnstr (Win, + Txt (Txt'First)'Access, + C_Int (Len)) = Curses_Err then + raise Curses_Exception; + end if; + end Add; + + procedure Add + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in Attributed_String; + Len : in Integer := -1) + is + begin + Move_Cursor (Win, Line, Column); + Add (Win, Str, Len); + end Add; +------------------------------------------------------------------------------ + procedure Border + (Win : in Window := Standard_Window; + Left_Side_Symbol : in Attributed_Character := Default_Character; + Right_Side_Symbol : in Attributed_Character := Default_Character; + Top_Side_Symbol : in Attributed_Character := Default_Character; + Bottom_Side_Symbol : in Attributed_Character := Default_Character; + Upper_Left_Corner_Symbol : in Attributed_Character := Default_Character; + Upper_Right_Corner_Symbol : in Attributed_Character := Default_Character; + Lower_Left_Corner_Symbol : in Attributed_Character := Default_Character; + Lower_Right_Corner_Symbol : in Attributed_Character := Default_Character) + is + function Wborder (W : Window; + LS : C_Chtype; + RS : C_Chtype; + TS : C_Chtype; + BS : C_Chtype; + ULC : C_Chtype; + URC : C_Chtype; + LLC : C_Chtype; + LRC : C_Chtype) return C_Int; + pragma Import (C, Wborder, "wborder"); + begin + if Wborder (Win, + AttrChar_To_Chtype (Left_Side_Symbol), + AttrChar_To_Chtype (Right_Side_Symbol), + AttrChar_To_Chtype (Top_Side_Symbol), + AttrChar_To_Chtype (Bottom_Side_Symbol), + AttrChar_To_Chtype (Upper_Left_Corner_Symbol), + AttrChar_To_Chtype (Upper_Right_Corner_Symbol), + AttrChar_To_Chtype (Lower_Left_Corner_Symbol), + AttrChar_To_Chtype (Lower_Right_Corner_Symbol) + ) = Curses_Err + then + raise Curses_Exception; + end if; + end Border; + + procedure Box + (Win : in Window := Standard_Window; + Vertical_Symbol : in Attributed_Character := Default_Character; + Horizontal_Symbol : in Attributed_Character := Default_Character) + is + begin + Border (Win, + Vertical_Symbol, Vertical_Symbol, + Horizontal_Symbol, Horizontal_Symbol); + end Box; + + procedure Horizontal_Line + (Win : in Window := Standard_Window; + Line_Size : in Natural; + Line_Symbol : in Attributed_Character := Default_Character) + is + function Whline (W : Window; + Ch : C_Chtype; + Len : C_Int) return C_Int; + pragma Import (C, Whline, "whline"); + begin + if Whline (Win, + AttrChar_To_Chtype (Line_Symbol), + C_Int (Line_Size)) = Curses_Err then + raise Curses_Exception; + end if; + end Horizontal_Line; + + procedure Vertical_Line + (Win : in Window := Standard_Window; + Line_Size : in Natural; + Line_Symbol : in Attributed_Character := Default_Character) + is + function Wvline (W : Window; + Ch : C_Chtype; + Len : C_Int) return C_Int; + pragma Import (C, Wvline, "wvline"); + begin + if Wvline (Win, + AttrChar_To_Chtype (Line_Symbol), + C_Int (Line_Size)) = Curses_Err then + raise Curses_Exception; + end if; + end Vertical_Line; + +------------------------------------------------------------------------------ + function Get_Keystroke (Win : Window := Standard_Window) + return Real_Key_Code + is + function Wgetch (W : Window) return C_Int; + pragma Import (C, Wgetch, "wgetch"); + + C : constant C_Int := Wgetch (Win); + begin + if C = Curses_Err then + return Key_None; + else + return Real_Key_Code (C); + end if; + end Get_Keystroke; + + procedure Undo_Keystroke (Key : in Real_Key_Code) + is + function Ungetch (Ch : C_Int) return C_Int; + pragma Import (C, Ungetch, "ungetch"); + begin + if Ungetch (C_Int (Key)) = Curses_Err then + raise Curses_Exception; + end if; + end Undo_Keystroke; + + function Has_Key (Key : Special_Key_Code) return Boolean + is + function Haskey (Key : C_Int) return C_Int; + pragma Import (C, Haskey, "has_key"); + begin + if Haskey (C_Int (Key)) = Curses_False then + return False; + else + return True; + end if; + end Has_Key; + + function Is_Function_Key (Key : Special_Key_Code) return Boolean + is + L : constant Special_Key_Code := Special_Key_Code (Natural (Key_F0) + + Natural (Function_Key_Number'Last)); + begin + if (Key >= Key_F0) and then (Key <= L) then + return True; + else + return False; + end if; + end Is_Function_Key; + + function Function_Key (Key : Real_Key_Code) + return Function_Key_Number + is + begin + if Is_Function_Key (Key) then + return Function_Key_Number (Key - Key_F0); + else + raise Constraint_Error; + end if; + end Function_Key; + + function Function_Key_Code (Key : Function_Key_Number) return Real_Key_Code + is + begin + return Real_Key_Code (Natural (Key_F0) + Natural (Key)); + end Function_Key_Code; +------------------------------------------------------------------------------ + procedure Switch_Character_Attribute + (Win : in Window := Standard_Window; + Attr : in Character_Attribute_Set := Normal_Video; + On : in Boolean := True) + is + function Wattron (Win : Window; + C_Attr : C_AttrType) return C_Int; + pragma Import (C, Wattron, "wattr_on"); + function Wattroff (Win : Window; + C_Attr : C_AttrType) return C_Int; + pragma Import (C, Wattroff, "wattr_off"); + -- In Ada we use the On Boolean to control whether or not we want to + -- switch on or off the attributes in the set. + Err : C_Int; + AC : constant Attributed_Character := (Ch => Character'First, + Color => Color_Pair'First, + Attr => Attr); + begin + if On then + Err := Wattron (Win, AttrChar_To_AttrType (AC)); + else + Err := Wattroff (Win, AttrChar_To_AttrType (AC)); + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Switch_Character_Attribute; + + procedure Set_Character_Attributes + (Win : in Window := Standard_Window; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Wattrset (Win : Window; + C_Attr : C_AttrType) return C_Int; + pragma Import (C, Wattrset, "wattrset"); -- ??? wattr_set + begin + if Wattrset (Win, + AttrChar_To_AttrType (Attributed_Character' + (Ch => Character'First, + Color => Color, + Attr => Attr))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Character_Attributes; + + function Get_Character_Attribute (Win : Window := Standard_Window) + return Character_Attribute_Set + is + function Wattrget (Win : Window; + Atr : access C_AttrType; + Col : access C_Short; + Opt : System.Address) return C_Int; + pragma Import (C, Wattrget, "wattr_get"); + + Attr : aliased C_AttrType; + Col : aliased C_Short; + Res : constant C_Int := Wattrget (Win, Attr'Access, Col'Access, + System.Null_Address); + Ch : Attributed_Character; + begin + if Res = Curses_Ok then + Ch := AttrType_To_AttrChar (Attr); + return Ch.Attr; + else + raise Curses_Exception; + end if; + end Get_Character_Attribute; + + function Get_Character_Attribute (Win : Window := Standard_Window) + return Color_Pair + is + function Wattrget (Win : Window; + Atr : access C_AttrType; + Col : access C_Short; + Opt : System.Address) return C_Int; + pragma Import (C, Wattrget, "wattr_get"); + + Attr : aliased C_AttrType; + Col : aliased C_Short; + Res : constant C_Int := Wattrget (Win, Attr'Access, Col'Access, + System.Null_Address); + Ch : Attributed_Character; + begin + if Res = Curses_Ok then + Ch := AttrType_To_AttrChar (Attr); + return Ch.Color; + else + raise Curses_Exception; + end if; + end Get_Character_Attribute; + + procedure Set_Color (Win : in Window := Standard_Window; + Pair : in Color_Pair) + is + function Wset_Color (Win : Window; + Color : C_Short; + Opts : C_Void_Ptr) return C_Int; + pragma Import (C, Wset_Color, "wcolor_set"); + begin + if Wset_Color (Win, + C_Short (Pair), + C_Void_Ptr (System.Null_Address)) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Color; + + procedure Change_Attributes + (Win : in Window := Standard_Window; + Count : in Integer := -1; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Wchgat (Win : Window; + Cnt : C_Int; + Attr : C_AttrType; + Color : C_Short; + Opts : System.Address := System.Null_Address) + return C_Int; + pragma Import (C, Wchgat, "wchgat"); + + Ch : constant Attributed_Character := + (Ch => Character'First, Color => Color_Pair'First, Attr => Attr); + begin + if Wchgat (Win, C_Int (Count), AttrChar_To_AttrType (Ch), + C_Short (Color)) = Curses_Err then + raise Curses_Exception; + end if; + end Change_Attributes; + + procedure Change_Attributes + (Win : in Window := Standard_Window; + Line : in Line_Position := Line_Position'First; + Column : in Column_Position := Column_Position'First; + Count : in Integer := -1; + Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + begin + Move_Cursor (Win, Line, Column); + Change_Attributes (Win, Count, Attr, Color); + end Change_Attributes; +------------------------------------------------------------------------------ + procedure Beep + is + function Beeper return C_Int; + pragma Import (C, Beeper, "beep"); + begin + if Beeper = Curses_Err then + raise Curses_Exception; + end if; + end Beep; + + procedure Flash_Screen + is + function Flash return C_Int; + pragma Import (C, Flash, "flash"); + begin + if Flash = Curses_Err then + raise Curses_Exception; + end if; + end Flash_Screen; +------------------------------------------------------------------------------ + procedure Set_Cbreak_Mode (SwitchOn : in Boolean := True) + is + function Cbreak return C_Int; + pragma Import (C, Cbreak, "cbreak"); + function NoCbreak return C_Int; + pragma Import (C, NoCbreak, "nocbreak"); + + Err : C_Int; + begin + if SwitchOn then + Err := Cbreak; + else + Err := NoCbreak; + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Set_Cbreak_Mode; + + procedure Set_Raw_Mode (SwitchOn : in Boolean := True) + is + function Raw return C_Int; + pragma Import (C, Raw, "raw"); + function NoRaw return C_Int; + pragma Import (C, NoRaw, "noraw"); + + Err : C_Int; + begin + if SwitchOn then + Err := Raw; + else + Err := NoRaw; + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Set_Raw_Mode; + + procedure Set_Echo_Mode (SwitchOn : in Boolean := True) + is + function Echo return C_Int; + pragma Import (C, Echo, "echo"); + function NoEcho return C_Int; + pragma Import (C, NoEcho, "noecho"); + + Err : C_Int; + begin + if SwitchOn then + Err := Echo; + else + Err := NoEcho; + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Set_Echo_Mode; + + procedure Set_Meta_Mode (Win : in Window := Standard_Window; + SwitchOn : in Boolean := True) + is + function Meta (W : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Meta, "meta"); + begin + if Meta (Win, Curses_Bool (Boolean'Pos (SwitchOn))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Meta_Mode; + + procedure Set_KeyPad_Mode (Win : in Window := Standard_Window; + SwitchOn : in Boolean := True) + is + function Keypad (W : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Keypad, "keypad"); + begin + if Keypad (Win, Curses_Bool (Boolean'Pos (SwitchOn))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_KeyPad_Mode; + + procedure Half_Delay (Amount : in Half_Delay_Amount) + is + function Halfdelay (Amount : C_Int) return C_Int; + pragma Import (C, Halfdelay, "halfdelay"); + begin + if Halfdelay (C_Int (Amount)) = Curses_Err then + raise Curses_Exception; + end if; + end Half_Delay; + + procedure Set_Flush_On_Interrupt_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := True) + is + function Intrflush (Win : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Intrflush, "intrflush"); + begin + if Intrflush (Win, Curses_Bool (Boolean'Pos (Mode))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Flush_On_Interrupt_Mode; + + procedure Set_Queue_Interrupt_Mode + (Win : in Window := Standard_Window; + Flush : in Boolean := True) + is + procedure Qiflush; + pragma Import (C, Qiflush, "qiflush"); + procedure No_Qiflush; + pragma Import (C, No_Qiflush, "noqiflush"); + begin + if Flush then + Qiflush; + else + No_Qiflush; + end if; + end Set_Queue_Interrupt_Mode; + + procedure Set_NoDelay_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := False) + is + function Nodelay (Win : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Nodelay, "nodelay"); + begin + if Nodelay (Win, Curses_Bool (Boolean'Pos (Mode))) = Curses_Err then + raise Curses_Exception; + end if; + end Set_NoDelay_Mode; + + procedure Set_Timeout_Mode (Win : in Window := Standard_Window; + Mode : in Timeout_Mode; + Amount : in Natural) + is + function Wtimeout (Win : Window; Amount : C_Int) return C_Int; + pragma Import (C, Wtimeout, "wtimeout"); + + Time : C_Int; + begin + case Mode is + when Blocking => Time := -1; + when Non_Blocking => Time := 0; + when Delayed => + if Amount = 0 then + raise Constraint_Error; + end if; + Time := C_Int (Amount); + end case; + if Wtimeout (Win, Time) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Timeout_Mode; + + procedure Set_Escape_Timer_Mode + (Win : in Window := Standard_Window; + Timer_Off : in Boolean := False) + is + function Notimeout (Win : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Notimeout, "notimeout"); + begin + if Notimeout (Win, Curses_Bool (Boolean'Pos (Timer_Off))) + = Curses_Err then + raise Curses_Exception; + end if; + end Set_Escape_Timer_Mode; + +------------------------------------------------------------------------------ + procedure Set_NL_Mode (SwitchOn : in Boolean := True) + is + function NL return C_Int; + pragma Import (C, NL, "nl"); + function NoNL return C_Int; + pragma Import (C, NoNL, "nonl"); + + Err : C_Int; + begin + if SwitchOn then + Err := NL; + else + Err := NoNL; + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Set_NL_Mode; + + procedure Clear_On_Next_Update + (Win : in Window := Standard_Window; + Do_Clear : in Boolean := True) + is + function Clear_Ok (W : Window; Flag : Curses_Bool) return C_Int; + pragma Import (C, Clear_Ok, "clearok"); + begin + if Clear_Ok (Win, Curses_Bool (Boolean'Pos (Do_Clear))) = Curses_Err then + raise Curses_Exception; + end if; + end Clear_On_Next_Update; + + procedure Use_Insert_Delete_Line + (Win : in Window := Standard_Window; + Do_Idl : in Boolean := True) + is + function IDL_Ok (W : Window; Flag : Curses_Bool) return C_Int; + pragma Import (C, IDL_Ok, "idlok"); + begin + if IDL_Ok (Win, Curses_Bool (Boolean'Pos (Do_Idl))) = Curses_Err then + raise Curses_Exception; + end if; + end Use_Insert_Delete_Line; + + procedure Use_Insert_Delete_Character + (Win : in Window := Standard_Window; + Do_Idc : in Boolean := True) + is + function IDC_Ok (W : Window; Flag : Curses_Bool) return C_Int; + pragma Import (C, IDC_Ok, "idcok"); + begin + if IDC_Ok (Win, Curses_Bool (Boolean'Pos (Do_Idc))) = Curses_Err then + raise Curses_Exception; + end if; + end Use_Insert_Delete_Character; + + procedure Leave_Cursor_After_Update + (Win : in Window := Standard_Window; + Do_Leave : in Boolean := True) + is + function Leave_Ok (W : Window; Flag : Curses_Bool) return C_Int; + pragma Import (C, Leave_Ok, "leaveok"); + begin + if Leave_Ok (Win, Curses_Bool (Boolean'Pos (Do_Leave))) = Curses_Err then + raise Curses_Exception; + end if; + end Leave_Cursor_After_Update; + + procedure Immediate_Update_Mode + (Win : in Window := Standard_Window; + Mode : in Boolean := False) + is + function Immedok (Win : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Immedok, "immedok"); + begin + if Immedok (Win, Curses_Bool (Boolean'Pos (Mode))) = Curses_Err then + raise Curses_Exception; + end if; + end Immediate_Update_Mode; + + procedure Allow_Scrolling + (Win : in Window := Standard_Window; + Mode : in Boolean := False) + is + function Scrollok (Win : Window; Mode : Curses_Bool) return C_Int; + pragma Import (C, Scrollok, "scrollok"); + begin + if Scrollok (Win, Curses_Bool (Boolean'Pos (Mode))) = Curses_Err then + raise Curses_Exception; + end if; + end Allow_Scrolling; + + function Scrolling_Allowed (Win : Window := Standard_Window) return Boolean + is + Res : C_Int; + begin + case Sizeof_bool is + when 1 => Res := C_Int (W_Get_Byte (Win, Offset_scroll)); + when 2 => Res := C_Int (W_Get_Short (Win, Offset_scroll)); + when 4 => Res := C_Int (W_Get_Int (Win, Offset_scroll)); + when others => raise Curses_Exception; + end case; + + case Res is + when 0 => return False; + when others => return True; + end case; + end Scrolling_Allowed; + + procedure Set_Scroll_Region + (Win : in Window := Standard_Window; + Top_Line : in Line_Position; + Bottom_Line : in Line_Position) + is + function Wsetscrreg (Win : Window; + Lin : C_Int; + Col : C_Int) return C_Int; + pragma Import (C, Wsetscrreg, "wsetscrreg"); + begin + if Wsetscrreg (Win, C_Int (Top_Line), C_Int (Bottom_Line)) + = Curses_Err then + raise Curses_Exception; + end if; + end Set_Scroll_Region; +------------------------------------------------------------------------------ + procedure Update_Screen + is + function Do_Update return C_Int; + pragma Import (C, Do_Update, "doupdate"); + begin + if Do_Update = Curses_Err then + raise Curses_Exception; + end if; + end Update_Screen; + + procedure Refresh (Win : in Window := Standard_Window) + is + function Wrefresh (W : Window) return C_Int; + pragma Import (C, Wrefresh, "wrefresh"); + begin + if Wrefresh (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Refresh; + + procedure Refresh_Without_Update + (Win : in Window := Standard_Window) + is + function Wnoutrefresh (W : Window) return C_Int; + pragma Import (C, Wnoutrefresh, "wnoutrefresh"); + begin + if Wnoutrefresh (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Refresh_Without_Update; + + procedure Redraw (Win : in Window := Standard_Window) + is + function Redrawwin (Win : Window) return C_Int; + pragma Import (C, Redrawwin, "redrawwin"); + begin + if Redrawwin (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Redraw; + + procedure Redraw + (Win : in Window := Standard_Window; + Begin_Line : in Line_Position; + Line_Count : in Positive) + is + function Wredrawln (Win : Window; First : C_Int; Cnt : C_Int) + return C_Int; + pragma Import (C, Wredrawln, "wredrawln"); + begin + if Wredrawln (Win, + C_Int (Begin_Line), + C_Int (Line_Count)) = Curses_Err then + raise Curses_Exception; + end if; + end Redraw; + +------------------------------------------------------------------------------ + procedure Erase (Win : in Window := Standard_Window) + is + function Werase (W : Window) return C_Int; + pragma Import (C, Werase, "werase"); + begin + if Werase (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Erase; + + procedure Clear (Win : in Window := Standard_Window) + is + function Wclear (W : Window) return C_Int; + pragma Import (C, Wclear, "wclear"); + begin + if Wclear (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Clear; + + procedure Clear_To_End_Of_Screen (Win : in Window := Standard_Window) + is + function Wclearbot (W : Window) return C_Int; + pragma Import (C, Wclearbot, "wclrtobot"); + begin + if Wclearbot (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Clear_To_End_Of_Screen; + + procedure Clear_To_End_Of_Line (Win : in Window := Standard_Window) + is + function Wcleareol (W : Window) return C_Int; + pragma Import (C, Wcleareol, "wclrtoeol"); + begin + if Wcleareol (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Clear_To_End_Of_Line; +------------------------------------------------------------------------------ + procedure Set_Background + (Win : in Window := Standard_Window; + Ch : in Attributed_Character) + is + procedure WBackground (W : in Window; Ch : in C_Chtype); + pragma Import (C, WBackground, "wbkgdset"); + begin + WBackground (Win, AttrChar_To_Chtype (Ch)); + end Set_Background; + + procedure Change_Background + (Win : in Window := Standard_Window; + Ch : in Attributed_Character) + is + function WChangeBkgd (W : Window; Ch : C_Chtype) return C_Int; + pragma Import (C, WChangeBkgd, "wbkgd"); + begin + if WChangeBkgd (Win, AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Change_Background; + + function Get_Background (Win : Window := Standard_Window) + return Attributed_Character + is + function Wgetbkgd (Win : Window) return C_Chtype; + pragma Import (C, Wgetbkgd, "getbkgd"); + begin + return Chtype_To_AttrChar (Wgetbkgd (Win)); + end Get_Background; +------------------------------------------------------------------------------ + procedure Change_Lines_Status (Win : in Window := Standard_Window; + Start : in Line_Position; + Count : in Positive; + State : in Boolean) + is + function Wtouchln (Win : Window; + Sta : C_Int; + Cnt : C_Int; + Chg : C_Int) return C_Int; + pragma Import (C, Wtouchln, "wtouchln"); + begin + if Wtouchln (Win, C_Int (Start), C_Int (Count), + C_Int (Boolean'Pos (State))) = Curses_Err then + raise Curses_Exception; + end if; + end Change_Lines_Status; + + procedure Touch (Win : in Window := Standard_Window) + is + Y : Line_Position; + X : Column_Position; + begin + Get_Size (Win, Y, X); + Change_Lines_Status (Win, 0, Positive (Y), True); + end Touch; + + procedure Untouch (Win : in Window := Standard_Window) + is + Y : Line_Position; + X : Column_Position; + begin + Get_Size (Win, Y, X); + Change_Lines_Status (Win, 0, Positive (Y), False); + end Untouch; + + procedure Touch (Win : in Window := Standard_Window; + Start : in Line_Position; + Count : in Positive) + is + begin + Change_Lines_Status (Win, Start, Count, True); + end Touch; + + function Is_Touched + (Win : Window := Standard_Window; + Line : Line_Position) return Boolean + is + function WLineTouched (W : Window; L : C_Int) return Curses_Bool; + pragma Import (C, WLineTouched, "is_linetouched"); + begin + if WLineTouched (Win, C_Int (Line)) = Curses_Bool_False then + return False; + else + return True; + end if; + end Is_Touched; + + function Is_Touched + (Win : Window := Standard_Window) return Boolean + is + function WWinTouched (W : Window) return Curses_Bool; + pragma Import (C, WWinTouched, "is_wintouched"); + begin + if WWinTouched (Win) = Curses_Bool_False then + return False; + else + return True; + end if; + end Is_Touched; +------------------------------------------------------------------------------ + procedure Copy + (Source_Window : in Window; + Destination_Window : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position; + Non_Destructive_Mode : in Boolean := True) + is + function Copywin (Src : Window; + Dst : Window; + Str : C_Int; + Slc : C_Int; + Dtr : C_Int; + Dlc : C_Int; + Dbr : C_Int; + Drc : C_Int; + Ndm : C_Int) return C_Int; + pragma Import (C, Copywin, "copywin"); + begin + if Copywin (Source_Window, + Destination_Window, + C_Int (Source_Top_Row), + C_Int (Source_Left_Column), + C_Int (Destination_Top_Row), + C_Int (Destination_Left_Column), + C_Int (Destination_Bottom_Row), + C_Int (Destination_Right_Column), + Boolean'Pos (Non_Destructive_Mode) + ) = Curses_Err then + raise Curses_Exception; + end if; + end Copy; + + procedure Overwrite + (Source_Window : in Window; + Destination_Window : in Window) + is + function Overwrite (Src : Window; Dst : Window) return C_Int; + pragma Import (C, Overwrite, "overwrite"); + begin + if Overwrite (Source_Window, Destination_Window) = Curses_Err then + raise Curses_Exception; + end if; + end Overwrite; + + procedure Overlay + (Source_Window : in Window; + Destination_Window : in Window) + is + function Overlay (Src : Window; Dst : Window) return C_Int; + pragma Import (C, Overlay, "overlay"); + begin + if Overlay (Source_Window, Destination_Window) = Curses_Err then + raise Curses_Exception; + end if; + end Overlay; + +------------------------------------------------------------------------------ + procedure Insert_Delete_Lines + (Win : in Window := Standard_Window; + Lines : in Integer := 1) -- default is to insert one line above + is + function Winsdelln (W : Window; N : C_Int) return C_Int; + pragma Import (C, Winsdelln, "winsdelln"); + begin + if Winsdelln (Win, C_Int (Lines)) = Curses_Err then + raise Curses_Exception; + end if; + end Insert_Delete_Lines; + + procedure Delete_Line (Win : in Window := Standard_Window) + is + begin + Insert_Delete_Lines (Win, -1); + end Delete_Line; + + procedure Insert_Line (Win : in Window := Standard_Window) + is + begin + Insert_Delete_Lines (Win, 1); + end Insert_Line; +------------------------------------------------------------------------------ + + + procedure Get_Size + (Win : in Window := Standard_Window; + Number_Of_Lines : out Line_Count; + Number_Of_Columns : out Column_Count) + is + -- Please note: in ncurses they are one off. + -- This might be different in other implementations of curses + Y : C_Int := C_Int (W_Get_Short (Win, Offset_maxy)) + C_Int (Offset_XY); + X : C_Int := C_Int (W_Get_Short (Win, Offset_maxx)) + C_Int (Offset_XY); + begin + Number_Of_Lines := Line_Count (Y); + Number_Of_Columns := Column_Count (X); + end Get_Size; + + procedure Get_Window_Position + (Win : in Window := Standard_Window; + Top_Left_Line : out Line_Position; + Top_Left_Column : out Column_Position) + is + Y : C_Short := W_Get_Short (Win, Offset_begy); + X : C_Short := W_Get_Short (Win, Offset_begx); + begin + Top_Left_Line := Line_Position (Y); + Top_Left_Column := Column_Position (X); + end Get_Window_Position; + + procedure Get_Cursor_Position + (Win : in Window := Standard_Window; + Line : out Line_Position; + Column : out Column_Position) + is + Y : C_Short := W_Get_Short (Win, Offset_cury); + X : C_Short := W_Get_Short (Win, Offset_curx); + begin + Line := Line_Position (Y); + Column := Column_Position (X); + end Get_Cursor_Position; + + procedure Get_Origin_Relative_To_Parent + (Win : in Window; + Top_Left_Line : out Line_Position; + Top_Left_Column : out Column_Position; + Is_Not_A_Subwindow : out Boolean) + is + Y : C_Int := W_Get_Int (Win, Offset_pary); + X : C_Int := W_Get_Int (Win, Offset_parx); + begin + if Y = -1 then + Top_Left_Line := Line_Position'Last; + Top_Left_Column := Column_Position'Last; + Is_Not_A_Subwindow := True; + else + Top_Left_Line := Line_Position (Y); + Top_Left_Column := Column_Position (X); + Is_Not_A_Subwindow := False; + end if; + end Get_Origin_Relative_To_Parent; +------------------------------------------------------------------------------ + function New_Pad (Lines : Line_Count; + Columns : Column_Count) return Window + is + function Newpad (Lines : C_Int; Columns : C_Int) return Window; + pragma Import (C, Newpad, "newpad"); + + W : Window; + begin + W := Newpad (C_Int (Lines), C_Int (Columns)); + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end New_Pad; + + function Sub_Pad + (Pad : Window; + Number_Of_Lines : Line_Count; + Number_Of_Columns : Column_Count; + First_Line_Position : Line_Position; + First_Column_Position : Column_Position) return Window + is + function Subpad + (Pad : Window; + Number_Of_Lines : C_Int; + Number_Of_Columns : C_Int; + First_Line_Position : C_Int; + First_Column_Position : C_Int) return Window; + pragma Import (C, Subpad, "subpad"); + + W : Window; + begin + W := Subpad (Pad, + C_Int (Number_Of_Lines), + C_Int (Number_Of_Columns), + C_Int (First_Line_Position), + C_Int (First_Column_Position)); + if W = Null_Window then + raise Curses_Exception; + end if; + return W; + end Sub_Pad; + + procedure Refresh + (Pad : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position) + is + function Prefresh + (Pad : Window; + Source_Top_Row : C_Int; + Source_Left_Column : C_Int; + Destination_Top_Row : C_Int; + Destination_Left_Column : C_Int; + Destination_Bottom_Row : C_Int; + Destination_Right_Column : C_Int) return C_Int; + pragma Import (C, Prefresh, "prefresh"); + begin + if Prefresh (Pad, + C_Int (Source_Top_Row), + C_Int (Source_Left_Column), + C_Int (Destination_Top_Row), + C_Int (Destination_Left_Column), + C_Int (Destination_Bottom_Row), + C_Int (Destination_Right_Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Refresh; + + procedure Refresh_Without_Update + (Pad : in Window; + Source_Top_Row : in Line_Position; + Source_Left_Column : in Column_Position; + Destination_Top_Row : in Line_Position; + Destination_Left_Column : in Column_Position; + Destination_Bottom_Row : in Line_Position; + Destination_Right_Column : in Column_Position) + is + function Pnoutrefresh + (Pad : Window; + Source_Top_Row : C_Int; + Source_Left_Column : C_Int; + Destination_Top_Row : C_Int; + Destination_Left_Column : C_Int; + Destination_Bottom_Row : C_Int; + Destination_Right_Column : C_Int) return C_Int; + pragma Import (C, Pnoutrefresh, "pnoutrefresh"); + begin + if Pnoutrefresh (Pad, + C_Int (Source_Top_Row), + C_Int (Source_Left_Column), + C_Int (Destination_Top_Row), + C_Int (Destination_Left_Column), + C_Int (Destination_Bottom_Row), + C_Int (Destination_Right_Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Refresh_Without_Update; + + procedure Add_Character_To_Pad_And_Echo_It + (Pad : in Window; + Ch : in Attributed_Character) + is + function Pechochar (Pad : Window; Ch : C_Chtype) + return C_Int; + pragma Import (C, Pechochar, "pechochar"); + begin + if Pechochar (Pad, AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Add_Character_To_Pad_And_Echo_It; + + procedure Add_Character_To_Pad_And_Echo_It + (Pad : in Window; + Ch : in Character) + is + begin + Add_Character_To_Pad_And_Echo_It + (Pad, + Attributed_Character'(Ch => Ch, + Color => Color_Pair'First, + Attr => Normal_Video)); + end Add_Character_To_Pad_And_Echo_It; +------------------------------------------------------------------------------ + procedure Scroll (Win : in Window := Standard_Window; + Amount : in Integer := 1) + is + function Wscrl (Win : Window; N : C_Int) return C_Int; + pragma Import (C, Wscrl, "wscrl"); + + begin + if Wscrl (Win, C_Int (Amount)) = Curses_Err then + raise Curses_Exception; + end if; + end Scroll; + +------------------------------------------------------------------------------ + procedure Delete_Character (Win : in Window := Standard_Window) + is + function Wdelch (Win : Window) return C_Int; + pragma Import (C, Wdelch, "wdelch"); + begin + if Wdelch (Win) = Curses_Err then + raise Curses_Exception; + end if; + end Delete_Character; + + procedure Delete_Character + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position) + is + function Mvwdelch (Win : Window; + Lin : C_Int; + Col : C_Int) return C_Int; + pragma Import (C, Mvwdelch, "mvwdelch"); + begin + if Mvwdelch (Win, C_Int (Line), C_Int (Column)) = Curses_Err then + raise Curses_Exception; + end if; + end Delete_Character; +------------------------------------------------------------------------------ + function Peek (Win : Window := Standard_Window) + return Attributed_Character + is + function Winch (Win : Window) return C_Chtype; + pragma Import (C, Winch, "winch"); + begin + return Chtype_To_AttrChar (Winch (Win)); + end Peek; + + function Peek + (Win : Window := Standard_Window; + Line : Line_Position; + Column : Column_Position) return Attributed_Character + is + function Mvwinch (Win : Window; + Lin : C_Int; + Col : C_Int) return C_Chtype; + pragma Import (C, Mvwinch, "mvwinch"); + begin + return Chtype_To_AttrChar (Mvwinch (Win, C_Int (Line), C_Int (Column))); + end Peek; +------------------------------------------------------------------------------ + procedure Insert (Win : in Window := Standard_Window; + Ch : in Attributed_Character) + is + function Winsch (Win : Window; Ch : C_Chtype) return C_Int; + pragma Import (C, Winsch, "winsch"); + begin + if Winsch (Win, AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Insert; + + procedure Insert + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Ch : in Attributed_Character) + is + function Mvwinsch (Win : Window; + Lin : C_Int; + Col : C_Int; + Ch : C_Chtype) return C_Int; + pragma Import (C, Mvwinsch, "mvwinsch"); + begin + if Mvwinsch (Win, + C_Int (Line), + C_Int (Column), + AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Insert; +------------------------------------------------------------------------------ + procedure Insert (Win : in Window := Standard_Window; + Str : in String; + Len : in Integer := -1) + is + type Char_Ptr is access all Interfaces.C.char; + function Winsnstr (Win : Window; + Str : Char_Ptr; + Len : Integer := -1) return C_Int; + pragma Import (C, Winsnstr, "winsnstr"); + + Txt : char_array (0 .. Str'Length); + Length : size_t; + begin + To_C (Str, Txt, Length); + if Winsnstr (Win, Txt (Txt'First)'Access, Len) = Curses_Err then + raise Curses_Exception; + end if; + end Insert; + + procedure Insert + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : in String; + Len : in Integer := -1) + is + type Char_Ptr is access all Interfaces.C.char; + function Mvwinsnstr (Win : Window; + Line : C_Int; + Column : C_Int; + Str : Char_Ptr; + Len : C_Int) return C_Int; + pragma Import (C, Mvwinsnstr, "mvwinsnstr"); + + Txt : char_array (0 .. Str'Length); + Length : size_t; + begin + To_C (Str, Txt, Length); + if Mvwinsnstr (Win, C_Int (Line), C_Int (Column), + Txt (Txt'First)'Access, C_Int (Len)) + = Curses_Err then + raise Curses_Exception; + end if; + end Insert; +------------------------------------------------------------------------------ + procedure Peek (Win : in Window := Standard_Window; + Str : out String; + Len : in Integer := -1) + is + function Winnstr (Win : Window; + Str : char_array; + Len : C_Int) return C_Int; + pragma Import (C, Winnstr, "winnstr"); + + N : Integer := Len; + Txt : char_array (0 .. Str'Length); + Cnt : Natural; + begin + if N < 0 then + N := Str'Length; + end if; + if N > Str'Length then + raise Constraint_Error; + end if; + Txt (0) := Interfaces.C.char'First; + if Winnstr (Win, Txt, C_Int (N)) = Curses_Err then + raise Curses_Exception; + end if; + To_Ada (Txt, Str, Cnt, True); + if Cnt < Str'Length then + Str ((Str'First + Cnt) .. Str'Last) := (others => ' '); + end if; + end Peek; + + procedure Peek + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out String; + Len : in Integer := -1) + is + begin + Move_Cursor (Win, Line, Column); + Peek (Win, Str, Len); + end Peek; +------------------------------------------------------------------------------ + procedure Peek + (Win : in Window := Standard_Window; + Str : out Attributed_String; + Len : in Integer := -1) + is + type Chtype_Ptr is access all Attributed_Character; + function Winchnstr (Win : Window; + Str : Chtype_Ptr; + Len : C_Int) return C_Int; + pragma Import (C, Winchnstr, "winchnstr"); + + N : Integer := Len; + Txt : chtype_array (0 .. Str'Length); + Cnt : Natural := 0; + begin + if N < 0 then + N := Str'Length; + end if; + if N > Str'Length then + raise Constraint_Error; + end if; + if Winchnstr (Win, Txt (Txt'First)'Access, C_Int (N)) = Curses_Err then + raise Curses_Exception; + end if; + for To in Str'Range loop + exit when Txt (size_t (Cnt)) = Default_Character; + Str (To) := Txt (size_t (Cnt)); + Cnt := Cnt + 1; + end loop; + if Cnt < Str'Length then + Str ((Str'First + Cnt) .. Str'Last) := + (others => (Ch => ' ', + Color => Color_Pair'First, + Attr => Normal_Video)); + end if; + end Peek; + + procedure Peek + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out Attributed_String; + Len : in Integer := -1) + is + begin + Move_Cursor (Win, Line, Column); + Peek (Win, Str, Len); + end Peek; +------------------------------------------------------------------------------ + procedure Get (Win : in Window := Standard_Window; + Str : out String; + Len : in Integer := -1) + is + function Wgetnstr (Win : Window; + Str : char_array; + Len : C_Int) return C_Int; + pragma Import (C, Wgetnstr, "wgetnstr"); + + N : Integer := Len; + Txt : char_array (0 .. Str'Length); + Cnt : Natural; + begin + if N < 0 then + N := Str'Length; + end if; + if N > Str'Length then + raise Constraint_Error; + end if; + Txt (0) := Interfaces.C.char'First; + if Wgetnstr (Win, Txt, C_Int (N)) = Curses_Err then + raise Curses_Exception; + end if; + To_Ada (Txt, Str, Cnt, True); + if Cnt < Str'Length then + Str ((Str'First + Cnt) .. Str'Last) := (others => ' '); + end if; + end Get; + + procedure Get + (Win : in Window := Standard_Window; + Line : in Line_Position; + Column : in Column_Position; + Str : out String; + Len : in Integer := -1) + is + begin + Move_Cursor (Win, Line, Column); + Get (Win, Str, Len); + end Get; +------------------------------------------------------------------------------ + procedure Init_Soft_Label_Keys + (Format : in Soft_Label_Key_Format := Three_Two_Three) + is + function Slk_Init (Fmt : C_Int) return C_Int; + pragma Import (C, Slk_Init, "slk_init"); + begin + if Slk_Init (Soft_Label_Key_Format'Pos (Format)) = Curses_Err then + raise Curses_Exception; + end if; + end Init_Soft_Label_Keys; + + procedure Set_Soft_Label_Key (Label : in Label_Number; + Text : in String; + Fmt : in Label_Justification := Left) + is + type Char_Ptr is access all Interfaces.C.char; + function Slk_Set (Label : C_Int; + Txt : Char_Ptr; + Fmt : C_Int) return C_Int; + pragma Import (C, Slk_Set, "slk_set"); + + Txt : char_array (0 .. Text'Length); + Len : size_t; + begin + To_C (Text, Txt, Len); + if Slk_Set (C_Int (Label), + Txt (Txt'First)'Access, + C_Int (Label_Justification'Pos (Fmt))) + = Curses_Err then + raise Curses_Exception; + end if; + end Set_Soft_Label_Key; + + procedure Refresh_Soft_Label_Keys + is + function Slk_Refresh return C_Int; + pragma Import (C, Slk_Refresh, "slk_refresh"); + begin + if Slk_Refresh = Curses_Err then + raise Curses_Exception; + end if; + end Refresh_Soft_Label_Keys; + + procedure Refresh_Soft_Label_Keys_Without_Update + is + function Slk_Noutrefresh return C_Int; + pragma Import (C, Slk_Noutrefresh, "slk_noutrefresh"); + begin + if Slk_Noutrefresh = Curses_Err then + raise Curses_Exception; + end if; + end Refresh_Soft_Label_Keys_Without_Update; + + procedure Get_Soft_Label_Key (Label : in Label_Number; + Text : out String) + is + function Slk_Label (Label : C_Int) return chars_ptr; + pragma Import (C, Slk_Label, "slk_label"); + begin + Fill_String (Slk_Label (C_Int (Label)), Text); + end Get_Soft_Label_Key; + + function Get_Soft_Label_Key (Label : in Label_Number) return String + is + function Slk_Label (Label : C_Int) return chars_ptr; + pragma Import (C, Slk_Label, "slk_label"); + begin + return Fill_String (Slk_Label (C_Int (Label))); + end Get_Soft_Label_Key; + + procedure Clear_Soft_Label_Keys + is + function Slk_Clear return C_Int; + pragma Import (C, Slk_Clear, "slk_clear"); + begin + if Slk_Clear = Curses_Err then + raise Curses_Exception; + end if; + end Clear_Soft_Label_Keys; + + procedure Restore_Soft_Label_Keys + is + function Slk_Restore return C_Int; + pragma Import (C, Slk_Restore, "slk_restore"); + begin + if Slk_Restore = Curses_Err then + raise Curses_Exception; + end if; + end Restore_Soft_Label_Keys; + + procedure Touch_Soft_Label_Keys + is + function Slk_Touch return C_Int; + pragma Import (C, Slk_Touch, "slk_touch"); + begin + if Slk_Touch = Curses_Err then + raise Curses_Exception; + end if; + end Touch_Soft_Label_Keys; + + procedure Switch_Soft_Label_Key_Attributes + (Attr : in Character_Attribute_Set; + On : in Boolean := True) + is + function Slk_Attron (Ch : C_Chtype) return C_Int; + pragma Import (C, Slk_Attron, "slk_attron"); + function Slk_Attroff (Ch : C_Chtype) return C_Int; + pragma Import (C, Slk_Attroff, "slk_attroff"); + + Err : C_Int; + Ch : constant Attributed_Character := (Ch => Character'First, + Attr => Attr, + Color => Color_Pair'First); + begin + if On then + Err := Slk_Attron (AttrChar_To_Chtype (Ch)); + else + Err := Slk_Attroff (AttrChar_To_Chtype (Ch)); + end if; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Switch_Soft_Label_Key_Attributes; + + procedure Set_Soft_Label_Key_Attributes + (Attr : in Character_Attribute_Set := Normal_Video; + Color : in Color_Pair := Color_Pair'First) + is + function Slk_Attrset (Ch : C_Chtype) return C_Int; + pragma Import (C, Slk_Attrset, "slk_attrset"); + + Ch : constant Attributed_Character := (Ch => Character'First, + Attr => Attr, + Color => Color); + begin + if Slk_Attrset (AttrChar_To_Chtype (Ch)) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Soft_Label_Key_Attributes; + + function Get_Soft_Label_Key_Attributes return Character_Attribute_Set + is + function Slk_Attr return C_Chtype; + pragma Import (C, Slk_Attr, "slk_attr"); + + Attr : constant C_Chtype := Slk_Attr; + begin + return Chtype_To_AttrChar (Attr).Attr; + end Get_Soft_Label_Key_Attributes; + + function Get_Soft_Label_Key_Attributes return Color_Pair + is + function Slk_Attr return C_Chtype; + pragma Import (C, Slk_Attr, "slk_attr"); + + Attr : constant C_Chtype := Slk_Attr; + begin + return Chtype_To_AttrChar (Attr).Color; + end Get_Soft_Label_Key_Attributes; + + procedure Set_Soft_Label_Key_Color (Pair : in Color_Pair) + is + function Slk_Color (Color : in C_Short) return C_Int; + pragma Import (C, Slk_Color, "slk_color"); + begin + if Slk_Color (C_Short (Pair)) = Curses_Err then + raise Curses_Exception; + end if; + end Set_Soft_Label_Key_Color; + +------------------------------------------------------------------------------ + procedure Enable_Key (Key : in Special_Key_Code; + Enable : in Boolean := True) + is + function Keyok (Keycode : C_Int; + On_Off : Curses_Bool) return C_Int; + pragma Import (C, Keyok, "keyok"); + begin + if Keyok (C_Int (Key), Curses_Bool (Boolean'Pos (Enable))) + = Curses_Err then + raise Curses_Exception; + end if; + end Enable_Key; +------------------------------------------------------------------------------ + procedure Define_Key (Definition : in String; + Key : in Special_Key_Code) + is + type Char_Ptr is access all Interfaces.C.char; + function Defkey (Def : Char_Ptr; + Key : C_Int) return C_Int; + pragma Import (C, Defkey, "define_key"); + + Txt : char_array (0 .. Definition'Length); + Length : size_t; + begin + To_C (Definition, Txt, Length); + if Defkey (Txt (Txt'First)'Access, C_Int (Key)) = Curses_Err then + raise Curses_Exception; + end if; + end Define_Key; +------------------------------------------------------------------------------ + procedure Un_Control (Ch : in Attributed_Character; + Str : out String) + is + function Unctrl (Ch : C_Chtype) return chars_ptr; + pragma Import (C, Unctrl, "unctrl"); + begin + Fill_String (Unctrl (AttrChar_To_Chtype (Ch)), Str); + end Un_Control; + + function Un_Control (Ch : in Attributed_Character) return String + is + function Unctrl (Ch : C_Chtype) return chars_ptr; + pragma Import (C, Unctrl, "unctrl"); + begin + return Fill_String (Unctrl (AttrChar_To_Chtype (Ch))); + end Un_Control; + + procedure Delay_Output (Msecs : in Natural) + is + function Delayoutput (Msecs : C_Int) return C_Int; + pragma Import (C, Delayoutput, "delay_output"); + begin + if Delayoutput (C_Int (Msecs)) = Curses_Err then + raise Curses_Exception; + end if; + end Delay_Output; + + procedure Flush_Input + is + function Flushinp return C_Int; + pragma Import (C, Flushinp, "flushinp"); + begin + if Flushinp = Curses_Err then -- docu says that never happens, but... + raise Curses_Exception; + end if; + end Flush_Input; +------------------------------------------------------------------------------ + function Baudrate return Natural + is + function Baud return C_Int; + pragma Import (C, Baud, "baudrate"); + begin + return Natural (Baud); + end Baudrate; + + function Erase_Character return Character + is + function Erasechar return C_Int; + pragma Import (C, Erasechar, "erasechar"); + begin + return Character'Val (Erasechar); + end Erase_Character; + + function Kill_Character return Character + is + function Killchar return C_Int; + pragma Import (C, Killchar, "killchar"); + begin + return Character'Val (Killchar); + end Kill_Character; + + function Has_Insert_Character return Boolean + is + function Has_Ic return Curses_Bool; + pragma Import (C, Has_Ic, "has_ic"); + begin + if Has_Ic = Curses_Bool_False then + return False; + else + return True; + end if; + end Has_Insert_Character; + + function Has_Insert_Line return Boolean + is + function Has_Il return Curses_Bool; + pragma Import (C, Has_Il, "has_il"); + begin + if Has_Il = Curses_Bool_False then + return False; + else + return True; + end if; + end Has_Insert_Line; + + function Supported_Attributes return Character_Attribute_Set + is + function Termattrs return C_Chtype; + pragma Import (C, Termattrs, "termattrs"); + + Ch : constant Attributed_Character := Chtype_To_AttrChar (Termattrs); + begin + return Ch.Attr; + end Supported_Attributes; + + procedure Long_Name (Name : out String) + is + function Longname return chars_ptr; + pragma Import (C, Longname, "longname"); + begin + Fill_String (Longname, Name); + end Long_Name; + + function Long_Name return String + is + function Longname return chars_ptr; + pragma Import (C, Longname, "longname"); + begin + return Fill_String (Longname); + end Long_Name; + + procedure Terminal_Name (Name : out String) + is + function Termname return chars_ptr; + pragma Import (C, Termname, "termname"); + begin + Fill_String (Termname, Name); + end Terminal_Name; + + function Terminal_Name return String + is + function Termname return chars_ptr; + pragma Import (C, Termname, "termname"); + begin + return Fill_String (Termname); + end Terminal_Name; +------------------------------------------------------------------------------ + procedure Init_Pair (Pair : in Redefinable_Color_Pair; + Fore : in Color_Number; + Back : in Color_Number) + is + function Initpair (Pair : C_Short; + Fore : C_Short; + Back : C_Short) return C_Int; + pragma Import (C, Initpair, "init_pair"); + begin + if Integer (Pair) >= Number_Of_Color_Pairs then + raise Constraint_Error; + end if; + if Integer (Fore) >= Number_Of_Colors or else + Integer (Back) >= Number_Of_Colors then raise Constraint_Error; + end if; + if Initpair (C_Short (Pair), C_Short (Fore), C_Short (Back)) + = Curses_Err then + raise Curses_Exception; + end if; + end Init_Pair; + + procedure Pair_Content (Pair : in Color_Pair; + Fore : out Color_Number; + Back : out Color_Number) + is + type C_Short_Access is access all C_Short; + function Paircontent (Pair : C_Short; + Fp : C_Short_Access; + Bp : C_Short_Access) return C_Int; + pragma Import (C, Paircontent, "pair_content"); + + F, B : aliased C_Short; + begin + if Paircontent (C_Short (Pair), F'Access, B'Access) = Curses_Err then + raise Curses_Exception; + else + Fore := Color_Number (F); + Back := Color_Number (B); + end if; + end Pair_Content; + + function Has_Colors return Boolean + is + function Hascolors return Curses_Bool; + pragma Import (C, Hascolors, "has_colors"); + begin + if Hascolors = Curses_Bool_False then + return False; + else + return True; + end if; + end Has_Colors; + + procedure Init_Color (Color : in Color_Number; + Red : in RGB_Value; + Green : in RGB_Value; + Blue : in RGB_Value) + is + function Initcolor (Col : C_Short; + Red : C_Short; + Green : C_Short; + Blue : C_Short) return C_Int; + pragma Import (C, Initcolor, "init_color"); + begin + if Initcolor (C_Short (Color), C_Short (Red), C_Short (Green), + C_Short (Blue)) = Curses_Err then + raise Curses_Exception; + end if; + end Init_Color; + + function Can_Change_Color return Boolean + is + function Canchangecolor return Curses_Bool; + pragma Import (C, Canchangecolor, "can_change_color"); + begin + if Canchangecolor = Curses_Bool_False then + return False; + else + return True; + end if; + end Can_Change_Color; + + procedure Color_Content (Color : in Color_Number; + Red : out RGB_Value; + Green : out RGB_Value; + Blue : out RGB_Value) + is + type C_Short_Access is access all C_Short; + + function Colorcontent (Color : C_Short; R, G, B : C_Short_Access) + return C_Int; + pragma Import (C, Colorcontent, "color_content"); + + R, G, B : aliased C_Short; + begin + if Colorcontent (C_Short (Color), R'Access, G'Access, B'Access) = + Curses_Err then + raise Curses_Exception; + else + Red := RGB_Value (R); + Green := RGB_Value (G); + Blue := RGB_Value (B); + end if; + end Color_Content; + +------------------------------------------------------------------------------ + procedure Save_Curses_Mode (Mode : in Curses_Mode) + is + function Def_Prog_Mode return C_Int; + pragma Import (C, Def_Prog_Mode, "def_prog_mode"); + function Def_Shell_Mode return C_Int; + pragma Import (C, Def_Shell_Mode, "def_shell_mode"); + + Err : C_Int; + begin + case Mode is + when Curses => Err := Def_Prog_Mode; + when Shell => Err := Def_Shell_Mode; + end case; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Save_Curses_Mode; + + procedure Reset_Curses_Mode (Mode : in Curses_Mode) + is + function Reset_Prog_Mode return C_Int; + pragma Import (C, Reset_Prog_Mode, "reset_prog_mode"); + function Reset_Shell_Mode return C_Int; + pragma Import (C, Reset_Shell_Mode, "reset_shell_mode"); + + Err : C_Int; + begin + case Mode is + when Curses => Err := Reset_Prog_Mode; + when Shell => Err := Reset_Shell_Mode; + end case; + if Err = Curses_Err then + raise Curses_Exception; + end if; + end Reset_Curses_Mode; + + procedure Save_Terminal_State + is + function Savetty return C_Int; + pragma Import (C, Savetty, "savetty"); + begin + if Savetty = Curses_Err then + raise Curses_Exception; + end if; + end Save_Terminal_State; + + procedure Reset_Terminal_State + is + function Resetty return C_Int; + pragma Import (C, Resetty, "resetty"); + begin + if Resetty = Curses_Err then + raise Curses_Exception; + end if; + end Reset_Terminal_State; + + procedure Rip_Off_Lines (Lines : in Integer; + Proc : in Stdscr_Init_Proc) + is + function Ripoffline (Lines : C_Int; + Proc : Stdscr_Init_Proc) return C_Int; + pragma Import (C, Ripoffline, "_nc_ripoffline"); + begin + if Ripoffline (C_Int (Lines), Proc) = Curses_Err then + raise Curses_Exception; + end if; + end Rip_Off_Lines; + + procedure Set_Cursor_Visibility (Visibility : in out Cursor_Visibility) + is + function Curs_Set (Curs : C_Int) return C_Int; + pragma Import (C, Curs_Set, "curs_set"); + + Res : C_Int; + begin + Res := Curs_Set (Cursor_Visibility'Pos (Visibility)); + if Res /= Curses_Err then + Visibility := Cursor_Visibility'Val (Res); + end if; + end Set_Cursor_Visibility; + + procedure Nap_Milli_Seconds (Ms : in Natural) + is + function Napms (Ms : C_Int) return C_Int; + pragma Import (C, Napms, "napms"); + begin + if Napms (C_Int (Ms)) = Curses_Err then + raise Curses_Exception; + end if; + end Nap_Milli_Seconds; +------------------------------------------------------------------------------ + + function Standard_Window return Window + is + Stdscr : Window; + pragma Import (C, Stdscr, "stdscr"); + begin + return Stdscr; + end Standard_Window; + + function Lines return Line_Count + is + C_Lines : C_Int; + pragma Import (C, C_Lines, "LINES"); + begin + return Line_Count (C_Lines); + end Lines; + + function Columns return Column_Count + is + C_Columns : C_Int; + pragma Import (C, C_Columns, "COLS"); + begin + return Column_Count (C_Columns); + end Columns; + + function Tab_Size return Natural + is + C_Tab_Size : C_Int; + pragma Import (C, C_Tab_Size, "TABSIZE"); + begin + return Natural (C_Tab_Size); + end Tab_Size; + + function Number_Of_Colors return Natural + is + C_Number_Of_Colors : C_Int; + pragma Import (C, C_Number_Of_Colors, "COLORS"); + begin + return Natural (C_Number_Of_Colors); + end Number_Of_Colors; + + function Number_Of_Color_Pairs return Natural + is + C_Number_Of_Color_Pairs : C_Int; + pragma Import (C, C_Number_Of_Color_Pairs, "COLOR_PAIRS"); + begin + return Natural (C_Number_Of_Color_Pairs); + end Number_Of_Color_Pairs; +------------------------------------------------------------------------------ + procedure Transform_Coordinates + (W : in Window := Standard_Window; + Line : in out Line_Position; + Column : in out Column_Position; + Dir : in Transform_Direction := From_Screen) + is + type Int_Access is access all C_Int; + function Transform (W : Window; + Y, X : Int_Access; + Dir : Curses_Bool) return C_Int; + pragma Import (C, Transform, "wmouse_trafo"); + + X : aliased C_Int := C_Int (Column); + Y : aliased C_Int := C_Int (Line); + D : Curses_Bool := Curses_Bool_False; + R : C_Int; + begin + if Dir = To_Screen then + D := 1; + end if; + R := Transform (W, Y'Access, X'Access, D); + if R = Curses_False then + raise Curses_Exception; + else + Line := Line_Position (Y); + Column := Column_Position (X); + end if; + end Transform_Coordinates; + +end Terminal_Interface.Curses; diff --git a/ncurses-5.2/Ada95/src/terminal_interface.ads b/ncurses-5.2/Ada95/src/terminal_interface.ads new file mode 100644 index 0000000..d49747b --- /dev/null +++ b/ncurses-5.2/Ada95/src/terminal_interface.ads @@ -0,0 +1,48 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT ncurses Binding -- +-- -- +-- Terminal_Interface -- +-- -- +-- S P E C -- +-- -- +------------------------------------------------------------------------------ +-- Copyright (c) 1998 Free Software Foundation, Inc. -- +-- -- +-- Permission is hereby granted, free of charge, to any person obtaining a -- +-- copy of this software and associated documentation files (the -- +-- "Software"), to deal in the Software without restriction, including -- +-- without limitation the rights to use, copy, modify, merge, publish, -- +-- distribute, distribute with modifications, sublicense, and/or sell -- +-- copies of the Software, and to permit persons to whom the Software is -- +-- furnished to do so, subject to the following conditions: -- +-- -- +-- The above copyright notice and this permission notice shall be included -- +-- in all copies or substantial portions of the Software. -- +-- -- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -- +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -- +-- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- +-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -- +-- THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- +-- -- +-- Except as contained in this notice, the name(s) of the above copyright -- +-- holders shall not be used in advertising or otherwise to promote the -- +-- sale, use or other dealings in this Software without prior written -- +-- authorization. -- +------------------------------------------------------------------------------ +-- Author: Juergen Pfeifer 1996 +-- Version Control: +-- $Revision$ +-- Binding Version 01.00 +------------------------------------------------------------------------------ +package Terminal_Interface is + pragma Pure (Terminal_Interface); +-- +-- Everything is in the child units +-- +end Terminal_Interface; + + diff --git a/ncurses-5.2/INSTALL b/ncurses-5.2/INSTALL new file mode 100644 index 0000000..9fc742f --- /dev/null +++ b/ncurses-5.2/INSTALL @@ -0,0 +1,1059 @@ +-- $Id$ +--------------------------------------------------------------------- + How to install Ncurses/Terminfo on your system +--------------------------------------------------------------------- + + ************************************************************ + * READ ALL OF THIS FILE BEFORE YOU TRY TO INSTALL NCURSES. * + ************************************************************ + +You should be reading the file INSTALL in a directory called ncurses-d.d, where +d.d is the current version number. There should be several subdirectories, +including `c++', `form', `man', `menu', 'misc', `ncurses', `panel', `progs', +and `test'. See the README file for a roadmap to the package. + +If you are a Linux or FreeBSD or NetBSD distribution integrator or packager, +please read and act on the section titled IF YOU ARE A SYSTEM INTEGRATOR +below. + +If you are converting from BSD curses and do not have root access, be sure +to read the BSD CONVERSION NOTES section below. + +If you are using a version of XFree86 xterm older than 3.1.2F, see the section +on RECENT XTERM VERSIONS below. + +If you are trying to build GNU Emacs using ncurses for terminal support, +read the USING NCURSES WITH EMACS section below. + +If you are trying to build applications using gpm with ncurses, +read the USING NCURSES WITH GPM section below. + +If you are running over the Andrew File System see the note below on +USING NCURSES WITH AFS. + +If you are cross-compiling, see the note below on BUILDING NCURSES WITH A +CROSS-COMPILER. + +If you want to build the Ada95 binding, go to the Ada95 directory and +follow the instructions there. The Ada95 binding is not covered below. + +If you are using anything but (a) Linux, or (b) one of the 4.4BSD-based +i386 Unixes, go read the Portability section in the TO-DO file before you +do anything else. + + +REQUIREMENTS: +------------ + +You will need the following in order to build and install ncurses under UNIX: + + * ANSI C compiler (gcc is recommended) + * sh (bash will do) + * awk (mawk or gawk will do) + * sed + * BSD or System V style install (a script is enclosed) + +Ncurses has been also built in the OS/2 EMX environment. + + +INSTALLATION PROCEDURE: +---------------------- + +1. First, decide whether you want ncurses to replace your existing library (in + which case you'll need super-user privileges) or be installed in parallel + with it. + + The --prefix option to configure changes the root directory for installing + ncurses. The default is in subdirectories of /usr/local. Use + --prefix=/usr to replace your default curses distribution. This is the + default for Linux and BSD/OS users. + + The package gets installed beneath the --prefix directory as follows: + + In $(prefix)/bin: tic, infocmp, captoinfo, tset, + reset, clear, tput, toe + In $(prefix)/lib: libncurses*.* libcurses.a + In $(prefix)/share/terminfo: compiled terminal descriptions + In $(prefix)/include: C header files + Under $(prefix)/man: the manual pages + + Note however that the configure script attempts to locate previous + installation of ncurses, and will set the default prefix according to where + it finds the ncurses headers. + +2. Type `./configure' in the top-level directory of the distribution to + configure ncurses for your operating system and create the Makefiles. + Besides --prefix, various configuration options are available to customize + the installation; use `./configure --help' to list the available options. + + If your operating system is not supported, read the PORTABILITY section in + the file ncurses/README for information on how to create a configuration + file for your system. + + The `configure' script generates makefile rules for one or more object + models and their associated libraries: + + libncurses.a (normal) + + libcurses.a (normal, a link to libncurses.a) + This gets left out if you configure with --disable-overwrite. + + libncurses.so (shared) + + libncurses_g.a (debug) + + libncurses_p.a (profile) + + libncurses.la (libtool) + + If you do not specify any models, the normal and debug libraries will be + configured. Typing `configure' with no arguments is equivalent to: + + ./configure --with-normal --with-debug --enable-overwrite + + Typing + + ./configure --with-shared + + makes the shared libraries the default, resulting in + + ./configure --with-shared --with-normal --with-debug --enable-overwrite + + If you want only shared libraries, type + + ./configure --with-shared --without-normal --without-debug + + Rules for generating shared libraries are highly dependent upon the choice + of host system and compiler. We've been testing shared libraries on Linux + and SunOS with gcc, but more work needs to be done to make shared libraries + work on other systems. + + If you have libtool installed, you can type + + ./configure --with-libtool + + to generate the appropriate static and/or shared libraries for your + platform using libtool. + + You can make curses and terminfo fall back to an existing file of termcap + definitions by configuring with --enable-termcap. If you do this, the + library will search /etc/termcap before the terminfo database, and will + also interpret the contents of the TERM environment variable. See the + section BSD CONVERSION NOTES below. + +3. Type `make'. Ignore any warnings, no error messages should be produced. + This should compile the ncurses library, the terminfo compiler tic(1), + captoinfo(1), infocmp(1), toe(1), clear(1) tset(1), reset(1), and tput(1) + programs (see the manual pages for explanation of what they do), some test + programs, and the panels, menus, and forms libraries. + +4. Run ncurses and several other test programs in the test directory to + verify that ncurses functions correctly before doing an install that + may overwrite system files. Read the file test/README for details on + the test programs. + + NOTE: You must have installed the terminfo database, or set the + environment variable $TERMINFO to point to a SVr4-compatible terminfo + database before running the test programs. Not all vendors' terminfo + databases are SVr4-compatible, but most seem to be. Exceptions include + DEC's Digital Unix (formerly known as OSF/1). + + The ncurses program is designed specifically to test the ncurses library. + You can use it to verify that the screen highlights work correctly, that + cursor addressing and window scrolling works OK, etc. + +5. Once you've tested, you can type `make install' to install libraries, + the programs, the terminfo database and the manual pages. Alternately, you + can type `make install' in each directory you want to install. In the + top-level directory, you can do a partial install using these commands: + + 'make install.progs' installs tic, infocmp, etc... + 'make install.includes' installs the headers. + 'make install.libs' installs the libraries (and the headers). + 'make install.data' installs the terminfo data. (Note: `tic' must + be installed before the terminfo data can be + compiled). + 'make install.man' installs the manual pages. + + ############################################################################ + # CAVEAT EMPTOR: `install.data' run as root will NUKE any existing # + # terminfo database. If you have any custom or unusual entries SAVE them # + # before you install ncurses. I have a file called terminfo.custom for # + # this purpose. Don't forget to run tic on the file once you're done. # + ############################################################################ + + The terminfo(5) manual page must be preprocessed with tbl(1) before + being formatted by nroff(1). Modern man(1) implementations tend to do + this by default, but you may want to look at your version's manual page + to be sure. You may also install the manual pages after preprocessing + with tbl(1) by specifying the configure option --with-manpage-tbl. + + If the system already has a curses library that you need to keep using + for some bizarre binary-compatibility reason, you'll need to distinguish + between it and ncurses. If ncurses is installed outside the standard + directories (/usr/include and /usr/lib) then all your users will need + to use the -I option to compile programs and -L to link them. + + If you have BSD curses installed in your system and you accidentally + compile using its curses.h you'll end up with a large number of + undefined symbols at link time. _waddbytes is one of them. + + IF YOU DO NOT HAVE ROOT: Change directory to the `progs' subdirectory + and run the `capconvert' script. This script will deduce various things + about your environment and use them to build you a private terminfo tree, + so you can use ncurses applications. + + If more than one user at your site does this, the space for the duplicate + trees is wasted. Try to get your site administrators to install a system- + wide terminfo tree instead. + + See the BSD CONVERSION NOTES section below for a few more details. + +6. The c++ directory has C++ classes that are built on top of ncurses and + panels. You must have c++ (and its libraries) installed before you can + compile and run the demo. + + Use --without-cxx-binding to tell configure to not build the C++ bindings + and demo. + + If you do not have C++, you must use the --without-cxx option to tell + the configure script to not attempt to determine the type of 'bool' + which may be supported by C++. IF YOU USE THIS OPTION, BE ADVISED THAT + YOU MAY NOT BE ABLE TO COMPILE (OR RUN) NCURSES APPLICATIONS WITH C++. + +7. If you're running an older Linux, you must either (a) tell Linux that the + console terminal type is `linux' or (b) make a link to or copy of the + linux entry in the appropriate place under your terminfo directory, named + `console'. All 1.3 and many 1.2 distributions (including Yggdrasil and + Red Hat) already have the console type set to `linux'. + + The way to change the wired-in console type depends on the configuration + of your system. This may involve editing /etc/inittab, /etc/ttytype, + /etc/profile and other such files. + + Warning: this is not for the fainthearted, if you mess up your console + getty entries you can make your system unusable! However, if you are + a distribution maker, this is the right thing to do (see the note for + integrators near the end of this file). + + The easier way is to link or copy l/linux to c/console under your terminfo + directory. Note: this will go away next time you do `make install.data' + and you'll have to redo it. There is no need to have entries for all + possible screen sizes, ncurses will figure out the size automatically. + + +SUMMARY OF CONFIGURE OPTIONS: +---------------------------- + + The configure script provides a short list of its options when you type + + ./configure --help + + The --help and several options are common to all configure scripts that are + generated with autoconf. Those are all listed before the line + + --enable and --with options recognized: + + The other options are specific to this package. We list them in alphabetic + order. + + --disable-assumed-color + With ncurses 5.1, we introduced a new function, assume_default_colors() + which allows applications to specify what the default foreground and + background color are assumed to be. Most color applications use + full-screen color; but a few do not color the background. While the + assumed values can be overridden by invoking assume_default_colors(), + you may find it useful to set the assumed values to the pre-5.1 + convention, using this configure option. + + --disable-big-core + Assume machine has little memory. The configure script attempts to + determine if your machine has enough memory (about 6Mb) to compile the + terminfo database without writing portions to disk. Some allocators + return deceptive results, so you may have to override the configure + script. Or you may be building tic for a smaller machine. + + --disable-database + Use only built-in data. The ncurses libraries normally read terminfo + and termcap data from disk. You can configure ncurses to have a + built-in database, aka "fallback" entries. Embedded applications may + have no need for an external database. + + --disable-ext-funcs + Disable function-extensions. Configure ncurses without the functions + that are not specified by XSI. See ncurses/modules for the exact + list of library modules that would be suppressed. + + --disable-hashmap + Compile without hashmap scrolling-optimization code. This algorithm is + the default. + + --disable-leaks + For testing, compile-in code that frees memory that normally would not + be freed, to simplify analysis of memory-leaks. + + --disable-macros + For testing, use functions rather than macros. The program will run + more slowly, but it is simpler to debug. This makes a header file + "nomacros.h". See also the --enable-expanded option. + + --disable-overwrite + If you are installing ncurses on a system which contains another + development version of curses, or which could be confused by the loader + for another version, we recommend that you leave out the link to + -lcurses. The ncurses library is always available as -lncurses. + Disabling overwrite also causes the ncurses header files to be + installed into a subdirectory, e.g., /usr/local/include/ncurses, + rather than the include directory. This makes it simpler to avoid + compile-time conflicts with other versions of curses.h + + --disable-root-environ + Compile with environment restriction, so certain environment variables + are not available when running as root, or via a setuid/setgid + application. These are (for example $TERMINFO) those that allow the + search path for the terminfo or termcap entry to be customized. + + --disable-scroll-hints + Compile without scroll-hints code. This option is ignored when + hashmap scrolling is configured, which is the default. + + --enable-add-ons=DIR... + This is used to check if this package is a glibc add-on. This is used + only by the glibc makefiles. + + --enable-assertions + For testing, compile-in assertion code. This is used only for a few + places where ncurses cannot easily recover by returning an error code. + + --enable-broken_linker + A few platforms have what we consider a broken linker: it cannot link + objects from an archive solely by referring to data objects in those + files, but requires a function reference. This configure option + changes several data references to functions to work around this + problem. + + NOTE: With ncurses 5.1, this may not be necessary, since we are + told that some linkers interpret uninitialized global data as a + different type of reference which behaves as described above. We have + explicitly initialized all of the global data to work around the + problem. + + --enable-bsdpad + Recognize BSD-style prefix padding. Some ancient BSD programs (such as + nethack) call tputs("50") to implement delays. + + --enable-colorfgbg + Compile with experimental $COLORFGBG code. That environment variable + is set by some terminal emulators as a hint to applications, by + advertising the default foreground and background colors. During + initialization, ncurses sets color pair 0 to match this. + + --enable-const + The curses interface as documented in XSI is rather old, in fact + including features that precede ANSI C. The prototypes generally do + not make effective use of "const". When using stricter compilers (or + gcc with appropriate warnings), you may see warnings about the mismatch + between const and non-const data. We provide a configure option which + changes the interfaces to use const - quieting these warnings and + reflecting the actual use of the parameters more closely. The ncurses + library uses the symbol NCURSES_CONST for these instances of const, + and if you have asked for compiler warnings, will add gcc's const-qual + warning. There will still be warnings due to subtle inconsistencies + in the interface, but at a lower level. + + NOTE: configuring ncurses with this option may detract from the + portability of your applications by encouraging you to use const in + places where the XSI curses interface would not allow them. Similar + issues arise when porting to SVr4 curses, which uses const in even + fewer places. + + --enable-echo + Use the option --disable-echo to make the build-log less verbose by + suppressing the display of the compile and link commands. This makes + it easier to see the compiler warnings. (You can always use "make -n" + to see the options that are used). + + --enable-expanded + For testing, generate functions for certain macros to make them visible + as such to the debugger. See also the --disable-macros option. + + --enable-getcap + Use the 4.4BSD getcap code if available, or a bundled version of it to + fetch termcap entries. Entries read in this way cannot use (make + cross-references to) the terminfo tree, but it is faster than reading + /etc/termcap. + + --enable-getcap-cache + Cache translated termcaps under the directory $HOME/.terminfo + + NOTE: this sounds good - it makes ncurses run faster the second time. + But look where the data comes from - an /etc/termcap containing lots of + entries that are not up to date. If you configure with this option and + forget to install the terminfo database before running an ncurses + application, you will end up with a hidden terminfo database that + generally does not support color and will miss some function keys. + + --enable-hard-tabs + Compile-in cursor-optimization code that uses hard-tabs. We would make + this a standard feature except for the concern that the terminfo entry + may not be accurate, or that your stty settings have disabled the use + of tabs. + + --enable-no-padding + Compile-in support for the $NCURSES_NO_PADDING environment variable, + which allows you to suppress the effect of non-mandatory padding in + terminfo entries. This is the default, unless you have disabled the + extended functions. + + --enable-rpath + Use rpath option when generating shared libraries, and with some + restrictions when linking the corresponding programs. This applies + mainly to systems using the GNU linker (read the manpage). + + --enable-safe-sprintf + Compile with experimental safe-sprintf code. You may consider using + this if you are building ncurses for a system that has neither + vsnprintf() or vsprintf(). It is slow, however. + + --enable-sigwinch + Compile support for ncurses' SIGWINCH handler. If your application has + its own SIGWINCH handler, ncurses will not use its own. The ncurses + handler causes wgetch() to return KEY_RESIZE when the screen-size + changes. This option is the default, unless you have disabled the + extended functions. + + --enable-symlinks + If your system supports symbolic links, make tic use symbolic links + rather than hard links to save diskspace when writing aliases in the + terminfo database. + + --enable-tcap-names + Compile-in support for user-definable terminal capabilities. Use the + -x option of tic and infocmp to treat unrecognized terminal + capabilities as user-defined strings. This option is the default, + unless you have disabled the extended functions. + + --enable-termcap + Compile in support for reading terminal descriptions from termcap if no + match is found in the terminfo database. See also the --enable-getcap + and --enable-getcap-cache options. + + --enable-warnings + Turn on GCC compiler warnings. There should be only a few. + + --enable-widec + Compile with experimental wide-character code. This makes a different + version of the libraries (e.g., libncursesw.so), which stores + characters in 16-bits. We provide a simple UTF-8 driver and test + program to use this feature with terminals that can display UTF-8. + + NOTE: applications compiled with this configuration are not compatible + with those built for 8-bit characters. You cannot simply make a + symbolic link to equate libncurses.so with libncursesw.so + + --enable-xmc-glitch + Compile-in support experimental xmc (magic cookie) code. + + --with-ada-compiler=CMD + Specify the Ada95 compiler command (default "gnatmake") + + --with-ada-include=DIR + Tell where to install the Ada includes (default: + PREFIX/lib/ada/adainclude) + + --with-ada-objects=DIR + Tell where to install the Ada objects (default: PREFIX/lib/ada/adalib) + + --with-database=XXX + Specify the terminfo source file to install. Usually you will wish + to install ncurses' default (misc/terminfo.src). Certain systems + have special requirements, e.g, OS/2 EMX has a customized terminfo + source file. + + --with-dbmalloc + For testing, compile and link with Conor Cahill's dbmalloc library. + + --with-debug + Generate debug-libraries (default). These are named by adding "_g" + to the root, e.g., libncurses_g.a + + --with-default-terminfo-dir=XXX + Specify the default terminfo database directory. This is normally + DATADIR/terminfo, e.g., /usr/share/terminfo. + + --with-develop + Enable experimental/development options. This does not count those + that change the interface, such as --enable-widec. + + --with-dmalloc + For testing, compile and link with Gray Watson's dmalloc library. + + --with-fallbacks=XXX + Specify a list of fallback terminal descriptions which will be + compiled into the ncurses library. See CONFIGURING FALLBACK ENTRIES. + + --with-gpm + use Alessandro Rubini's GPM library to provide mouse support on the + Linux console. + + --with-install-prefix=XXX + Allows you to specify an alternate location for installing ncurses + after building it. The value you specify is prepended to the "real" + install location. This simplifies making binary packages. + + NOTE: a few systems build shared libraries with fixed pathnames; this + option probably will not work for those configurations. + + --with-libtool + Generate libraries with libtool. If this option is selected, then + it overrides all other library model specifications. + + --with-manpage-format=XXX + Tell the configure script how you would like to install man-pages. The + option value must be one of these: gzip, compress, BSDI, normal, + formatted. If you do not give this option, the configure script + attempts to determine which is the case. + + --with-manpage-renames=XXX + Tell the configure script that you wish to rename the manpages while + installing. Currently the only distribution which does this is + the Linux Debian. The option value specifies the name of a file + that lists the renamed files, e.g., $srcdir/man/man_db.renames + + --with-manpage-symlinks + Tell the configure script that you wish to make symbolic links in the + man-directory for aliases to the man-pages. This is the default, but + can be disabled for systems that provide this automatically. Doing + this on systems that do not support symbolic links will result in + copying the man-page for each alias. + + --with-manpage-tbl + Tell the configure script that you with to preprocess the manpages + by running them through tbl to generate tables understandable by + nroff. + + --with-normal + Generate normal (i.e., static) libraries (default). + + --with-profile + Generate profile-libraries These are named by adding "_p" to the root, + e.g., libncurses_p.a + + --with-rcs-ids + Compile-in RCS identifiers. Most of the C files have an identifier. + + --with-shared + Generate shared-libraries. The names given depend on the system for + which you are building, typically using a ".so" suffix, along with + symbolic links that refer to the release version. + + NOTE: Unless you override the configure script by setting the $CFLAGS + environment variable, these will not be built with the -g debugging + option. + + --with-shlib-version=XXX + Specify whether to use the release or ABI version for shared libraries. + This is normally chosen automatically based on the type of system + which you are building on. We use it for testing the configure script. + + --with-system-type=XXX + For testing, override the derived host system-type which is used to + decide things such as the linker commands used to build shared + libraries. This is normally chosen automatically based on the type of + system which you are building on. We use it for testing the configure + script. + + --with-terminfo-dirs=XXX + Specify a search-list of terminfo directories which will be compiled + into the ncurses library (default: DATADIR/terminfo) + + --with-termlib + When building the ncurses library, organize this as two parts: the + curses library (libncurses) and the low-level terminfo library + (libtinfo). This is done to accommodate applications that use only + the latter. The terminfo library is about half the size of the total. + + --without-ada + Suppress the configure script's check for Ada95, do not build the + Ada95 binding and related demo. + + --without-curses-h + Don't install the ncurses header with the name "curses.h". Rather, + install as "ncurses.h" and modify the installed headers and manpages + accordingly. + + --without-cxx + XSI curses declares "bool" as part of the interface. C++ also declares + "bool". Neither specifies the size and type of booleans, but both + insist on the same name. We chose to accommodate this by making the + configure script check for the size and type (e.g., unsigned or signed) + that your C++ compiler uses for booleans. If you do not wish to use + ncurses with C++, use this option to tell the configure script to not + adjust ncurses bool to match C++. + + --without-cxx-binding + Suppress the configure script's check for C++, do not build the + C++ binding and related demo. + + --without-progs + Tell the configure script to suppress the build of ncurses' application + programs (e.g., tic). The test applications will still be built if you + type "make", though not if you simply do "make install". + + +COMPATIBILITY WITH OLDER VERSIONS OF NCURSES: +-------------------------------------------- + + Because ncurses implements the X/Open Curses Specification, its interface + is fairly stable. That does not mean the interface does not change. + Changes are made to the documented interfaces when we find differences + between ncurses and X/Open or implementations which they certify (such as + Solaris). We add extensions to those interfaces to solve problems not + addressed by the original curses design, but those must not conflict with + the X/Open documentation. + + Here are some of the major interface changes, and related problems which + you may encounter when building a system with different versions of + ncurses: + + 5.1 (July 8, 2000) + Interface changes: + + + made the extended terminal capabilities + (configure --enable-tcap-names) a standard feature. This should + be transparent to applications that do not require it. + + + removed the trace() function and related trace support from the + production library. + + + modified curses.h.in, undef'ing some symbols to avoid conflict + with C++ STL. + + Added extensions: assume_default_colors(). + + 5.0 (October 23, 1999) + Interface changes: + + + implemented the wcolor_set() and slk_color() functions. + + + move macro winch to a function, to hide details of struct ldat + + + corrected prototypes for slk_* functions, using chtype rather than + attr_t. + + + the slk_attr_{set,off,on} functions need an additional void* + parameter according to XSI. + + + modified several prototypes to correspond with 1997 version of X/Open + Curses: [w]attr_get(), [w]attr_set(), border_set() have different + parameters. Some functions were renamed or misspelled: + erase_wchar(), in_wchntr(), mvin_wchntr(). Some developers have used + attr_get(). + + Added extensions: keybound(), curses_version(). + + Terminfo database changes: + + + change translation for termcap 'rs' to terminfo 'rs2', which is + the documented equivalent, rather than 'rs1'. + + The problems are subtler in recent releases. + + a) This release provides users with the ability to define their own + terminal capability extensions, like termcap. To accomplish this, + we redesigned the TERMTYPE struct (in term.h). Very few + applications use this struct. They must be recompiled to work with + the 5.0 library. + + a) If you use the extended terminfo names (i.e., you used configure + --enable-tcap-names), the resulting terminfo database can have some + entries which are not readable by older versions of ncurses. This + is a bug in the older versions: + + + the terminfo database stores booleans, numbers and strings in + arrays. The capabilities that are listed in the arrays are + specified by X/Open. ncurses recognizes a number of obsolete and + extended names which are stored past the end of the specified + entries. + + + a change to read_entry.c in 951001 made the library do an lseek() + call incorrectly skipping data which is already read from the + string array. This happens when the number of strings in the + terminfo data file is greater than STRCOUNT, the number of + specified and obsolete or extended strings. + + + as part of alignment with the X/Open final specification, in the + 990109 patch we added two new terminfo capabilities: + set_a_attributes and set_pglen_inch). This makes the indices for + the obsolete and extended capabilities shift up by 2. + + + the last two capabilities in the obsolete/extended list are memu + and meml, which are found in most terminfo descriptions for xterm. + + When trying to read this terminfo entry, the spurious lseek() + causes the library to attempt to read the final portion of the + terminfo data (the text of the string capabilities) 4 characters + past its starting point, and reads 4 characters too few. The + library rejects the data, and applications are unable to + initialize that terminal type. + + FIX: remove memu and meml from the xterm description. They are + obsolete, not used by ncurses. (It appears that the feature was + added to xterm to make it more like hpterm). + + This is not a problem if you do not use the -x option of tic to + create a terminfo database with extended names. Note that the + user-defined terminal capabilities are not affected by this bug, + since they are stored in a table after the older terminfo data ends, + and are invisible to the older libraries. + + c) Some developers did not wish to use the C++ binding, and used the + configure --without-cxx option. This causes problems if someone + uses the ncurses library from C++ because that configure test + determines the type for C++'s bool and makes ncurses match it, since + both C++ and curses are specified to declare bool. Calling ncurses + functions with the incorrect type for bool will cause execution + errors. In 5.0 we added a configure option "--without-cxx-binding" + which controls whether the binding itself is built and installed. + + 4.2 (March 2, 1998) + Interface changes: + + + correct prototype for termattrs() as per XPG4 version 2. + + + add placeholder prototypes for color_set(), erasewchar(), + term_attrs(), wcolor_set() as per XPG4 version 2. + + + add macros getcur[xy] getbeg[xy] getpar[xy], which are defined in + SVr4 headers. + + New extensions: keyok() and define_key(). + + Terminfo database changes: + + + corrected definition in curses.h for ACS_LANTERN, which was 'I' + rather than 'i'. + + 4.1 (May 15, 1997) + + We added these extensions: use_default_colors(). Also added + configure option --enable-const, to support the use of const where + X/Open should have, but did not, specify. + + The terminfo database content changed the representation of color for + most entries that use ANSI colors. SVr4 curses treats the setaf/setab + and setf/setb capabilities differently, interchanging the red/blue + colors in the latter. + + 4.0 (December 24, 1996) + + We bumped to version 4.0 because the newly released dynamic loader + (ld.so.1.8.5) on Linux did not load shared libraries whose ABI and REL + versions were inconsistent. At that point, ncurses ABI was 3.4 and the + REL was 1.9.9g, so we made them consistent. + + 1.9.9g (December 1, 1996) + + This fixed most of the problems with 1.9.9e, and made these interface + changes: + + + remove tparam(), which had been provided for compatibility with + some termcap. tparm() is standard, and does not conflict with + application's fallback for missing tparam(). + + + turn off hardware echo in initscr(). This changes the sense of the + echo() function, which was initialized to echoing rather than + nonechoing (the latter is specified). There were several other + corrections to the terminal I/O settings which cause applications to + behave differently. + + + implemented several functions (such as attr_on()) which were + available only as macros. + + + corrected several typos in curses.h.in (i.e., the mvXXXX macros). + + + corrected prototypes for delay_output(), + has_color, immedok() and idcok(). + + + corrected misspelled getbkgd(). Some applications used the + misspelled name. + + + added _yoffset to WINDOW. The size of WINDOW does not impact + applications, since they use only pointers to WINDOW structs. + + These changes were made to the terminfo database: + + + removed boolean 'getm' which was available as an extended name. + + We added these extensions: wresize(), resizeterm(), has_key() and + mcprint(). + + 1.9.9e (March 24, 1996) + + not recommended (a last-minute/untested change left the forms and + menus libraries unusable since they do not repaint the screen). + Foreground/background colors are combined incorrectly, working properly + only on a black background. When this was released, the X/Open + specification was available only in draft form. + + Some applications (such as lxdialog) were "fixed" to work with the + incorrect color scheme. + + +IF YOU ARE A SYSTEM INTEGRATOR: +------------------------------ + + Beginning with 1.9.9, the ncurses distribution includes both a tset + utility and /usr/share/tabset directory. If you are installing ncurses, + it is no longer either necessary or desirable to install tset-jv. + + Configuration and Installation: + + Configure with --prefix=/usr to make the install productions put + libraries and headers in the correct locations (overwriting any + previous curses libraries and headers). This will put the terminfo + hierarchy under /usr/share/terminfo; you may want to override this with + --datadir=/usr/share/misc; terminfo and tabset are installed under the + data directory. + + Please configure the ncurses library in a pure-terminfo mode; that + is, with the --disable-termcap option. This will make the ncurses + library smaller and faster. The ncurses library includes a termcap + emulation that queries the terminfo database, so even applications + that use raw termcap to query terminal characteristics will win + (providing you recompile and relink them!). + + If you must configure with termcap fallback enabled, you may also + wish to use the --enable-getcap option. This option speeds up + termcap-based startups, at the expense of not allowing personal + termcap entries to reference the terminfo tree. See the code in + ncurses/tinfo/read_termcap.c for details. + + Note that if you have $TERMCAP set, ncurses will use that value + to locate termcap data. In particular, running from xterm will + set $TERMCAP to the contents of the xterm's termcap entry. + If ncurses sees that, it will not examine /etc/termcap. + + Keyboard Mapping: + + The terminfo file assumes that Shift-Tab generates \E[Z (the ECMA-48 + reverse-tabulation sequence) rather than ^I. Here are the loadkeys -d + mappings that will set this up: + + keycode 15 = Tab Tab + alt keycode 15 = Meta_Tab + shift keycode 15 = F26 + string F26 ="\033[Z" + + Naming the Console Terminal + + In various Linuxes (and possibly elsewhere) there has been a practice + of designating the system console driver type as `console'. Please + do not do this any more! It complicates peoples' lives, because it + can mean that several different terminfo entries from different + operating systems all logically want to be called `console'. + + Please pick a name unique to your console driver and set that up + in the /etc/inittab table or local equivalent. Send the entry to the + terminfo maintainer (listed in the misc/terminfo file) to be included + in the terminfo file, if it's not already there. See the + term(7) manual page included with this distribution for more on + conventions for choosing type names. + + Here are some recommended primary console names: + + linux -- Linux console driver + freebsd -- FreeBSD + netbsd -- NetBSD + bsdos -- BSD/OS + + If you are responsible for integrating ncurses for one of these + distribution, please either use the recommended name or get back + to us explaining why you don't want to, so we can work out nomenclature + that will make users' lives easier rather than harder. + + +RECENT XTERM VERSIONS: +--------------------- + + The terminfo database file included with this distribution assumes you + are running an XFree86 xterm based on X11R6 (i.e., xterm-r6). The + earlier X11R5 entry (xterm-r5) is provided as well. + + If you are running XFree86 version 3.2 (actually 3.1.2F and up), you + should consider using the xterm-xf86-v32 (or later, the most recent + version is always named "xterm-xfree86") entry, which adds ANSI color + and the VT220 capabilities which have been added in XFree86. If you + are running a mixed network, however, where this terminal description + may be used on an older xterm, you may have problems, since + applications that assume these capabilities will produce incorrect + output on the older xterm (e.g., highlighting is not cleared). + + +CONFIGURING FALLBACK ENTRIES: +---------------------------- + + In order to support operation of ncurses programs before the terminfo + tree is accessible (that is, in single-user mode or at OS installation + time) the ncurses library can be compiled to include an array of + pre-fetched fallback entries. + + These entries are checked by setupterm() only when the conventional + fetches from the terminfo tree and the termcap fallback (if configured) + have been tried and failed. Thus, the presence of a fallback will not + shadow modifications to the on-disk entry for the same type, when that + entry is accessible. + + By default, there are no entries on the fallback list. After you + have built the ncurses suite for the first time, you can change + the list (the process needs infocmp(1)). To do so, use the script + MKfallback.sh. A configure script option --with-fallbacks does this + (it accepts a comma-separated list of the names you wish, and does + not require a rebuild). + + If you wanted (say) to have linux, vt100, and xterm fallbacks, you + would use the commands + + cd ncurses; + MKfallback.sh linux vt100 xterm >fallback.c + + Then just rebuild and reinstall the library as you would normally. + You can restore the default empty fallback list with + + MKfallback.sh >fallback.c + + The overhead for an empty fallback list is one trivial stub function. + Any non-empty fallback list is const-ed and therefore lives in sharable + text space. You can look at the comment trailing each initializer in + the generated ncurses/fallback.c file to see the core cost of the + fallbacks. A good rule of thumb for modern vt100-like entries is that + each one will cost about 2.5K of text space. + + +BSD CONVERSION NOTES: +-------------------- + + If you need to support really ancient BSD programs, you probably + want to configure with the --enable-bsdpad option. What this does + is enable code in tputs() that recognizes a numeric prefix on a + capability as a request for that much trailing padding in milliseconds. + There are old BSD programs that do things like tputs("50"). + + (If you are distributing ncurses as a support-library component of + an application you probably want to put the remainder of this section + in the package README file.) + + The following note applies only if you have configured ncurses with + --enable-termcap. + +------------------------------- CUT HERE -------------------------------- + +If you are installing this application privately (either because you +have no root access or want to experiment with it before doing a root +installation), there are a couple of details you need to be aware of. +They have to do with the ncurses library, which uses terminfo rather +than termcap for describing terminal characteristics. + +Though the ncurses library is terminfo-based, it will interpret your +TERMCAP variable (if present), any local termcap files you reference +through it, and the system termcap file. However, in order to avoid +slowing down your application startup, it will only do this once per +terminal type! + +The first time you load a given terminal type from your termcap +database, the library initialization code will automatically write it +in terminfo format to a subdirectory under $HOME/.terminfo. After +that, the initialization code will find it there and do a (much +faster) terminfo fetch. + +Usually, all this means is that your home directory will silently grow +an invisible .terminfo subdirectory which will get filled in with +terminfo descriptions of terminal types as you invoke them. If anyone +ever installs a global terminfo tree on your system, this will quietly +stop happening and your $HOME/.terminfo will become redundant. + +The objective of all this logic is to make converting from BSD termcap +as painless as possible without slowing down your application (termcap +compilation is expensive). + +If you don't have a TERMCAP variable or custom personal termcap file, +you can skip the rest of this dissertation. + +If you *do* have a TERMCAP variable and/or a custom personal termcap file +that defines a terminal type, that definition will stop being visible +to this application after the first time you run it, because it will +instead see the terminfo entry that it wrote to $HOME/terminfo the +first time around. + +Subsequently, editing the TERMCAP variable or personal TERMCAP file +will have no effect unless you explicitly remove the terminfo entry +under $HOME/terminfo. If you do that, the entry will be recompiled +from your termcap resources the next time it is invoked. + +To avoid these complications, use infocmp(1) and tic(1) to edit the +terminfo directory directly. + +------------------------------- CUT HERE -------------------------------- + +USING NCURSES WITH AFS: + AFS treats each directory as a separate logical filesystem, you + can't hard-link across them. The --enable-symlinks option copes + with this by making tic use symbolic links. + +USING NCURSES WITH EMACS: + GNU Emacs has its own termcap support. By default, it uses a mixture + of those functions and code linked from the host system's libraries. + You need to foil this and shut out the GNU termcap library entirely. + + In order to do this, hack the Linux config file (s/linux.h) to contain + a #define TERMINFO and set the symbol LIBS_TERMCAP to "-lncurses". + + We have submitted such a change for the 19.30 release, so it may + already be applied in your sources -- check for the #define TERMINFO. + +USING NCURSES WITH GPM: + Ncurses 4.1 and up can be configured to use GPM (General Purpose Mouse) + which is used on Linux console. Be aware that GPM is commonly + installed as a shared library which contains a wrapper for the curses + wgetch() function (libcurses.o). Some integrators have simplified + linking applications by combining all or part of libcurses.so (the BSD + curses) into the libgpm.so file, producing symbol conflicts with + ncurses (specifically the wgetch function). You may be able to work + around this problem by linking as follows: + + cc -o foo foo.o -lncurses -lgpm -lncurses + + but the linker may not cooperate, producing mysterious errors. + A patched version of gpm is available: + + dickey.his.com:/ncurses/gpm-1.10-970125.tar.gz + + This patch is incorporated in gpm 1.12; however some integrators + are slow to update this library. Current distributions of gpm can + be configured properly using the --without-curses option. + +BUILDING NCURSES WITH A CROSS-COMPILER + Ncurses can be built with a cross-compiler. Some parts must be built + with the host's compiler since they are used for building programs + (e.g., ncurses/make_hash and ncurses/make_keys) that generate tables + that are compiled into the ncurses library. You should set the + BUILD_CC environment variable to your host's compiler, and run the + configure script configuring for the cross-compiler. + + Note that all of the generated source-files which are part of ncurses + will be made if you use + + make sources + + This would be useful in porting to an environment which has little + support for the tools used to generate the sources, e.g., sed, awk and + Bourne-shell. + +BUGS: + Send any feedback to the ncurses mailing list at + bug-ncurses@gnu.org. To subscribe send mail to + bug-ncurses-request@gnu.org with body that reads: + subscribe ncurses + + The Hacker's Guide in the doc directory includes some guidelines + on how to report bugs in ways that will get them fixed most quickly. diff --git a/ncurses-5.2/MANIFEST b/ncurses-5.2/MANIFEST new file mode 100644 index 0000000..24368e5 --- /dev/null +++ b/ncurses-5.2/MANIFEST @@ -0,0 +1,866 @@ +./ANNOUNCE +./Ada95/Makefile.in +./Ada95/README +./Ada95/TODO +./Ada95/gen/Makefile.in +./Ada95/gen/gen.c +./Ada95/gen/html.m4 +./Ada95/gen/normal.m4 +./Ada95/gen/table.m4 +./Ada95/gen/terminal_interface-curses-aux.ads.m4 +./Ada95/gen/terminal_interface-curses-forms-field_types.ads.m4 +./Ada95/gen/terminal_interface-curses-forms-field_user_data.ads.m4 +./Ada95/gen/terminal_interface-curses-forms-form_user_data.ads.m4 +./Ada95/gen/terminal_interface-curses-forms.ads.m4 +./Ada95/gen/terminal_interface-curses-menus-item_user_data.ads.m4 +./Ada95/gen/terminal_interface-curses-menus-menu_user_data.ads.m4 +./Ada95/gen/terminal_interface-curses-menus.ads.m4 +./Ada95/gen/terminal_interface-curses-mouse.ads.m4 +./Ada95/gen/terminal_interface-curses-panels-user_data.ads.m4 +./Ada95/gen/terminal_interface-curses-panels.ads.m4 +./Ada95/gen/terminal_interface-curses.ads.m4 +./Ada95/samples/Makefile.in +./Ada95/samples/README +./Ada95/samples/explain.txt +./Ada95/samples/rain.adb +./Ada95/samples/rain.ads +./Ada95/samples/sample-curses_demo-attributes.adb +./Ada95/samples/sample-curses_demo-attributes.ads +./Ada95/samples/sample-curses_demo-mouse.adb +./Ada95/samples/sample-curses_demo-mouse.ads +./Ada95/samples/sample-curses_demo.adb +./Ada95/samples/sample-curses_demo.ads +./Ada95/samples/sample-explanation.adb +./Ada95/samples/sample-explanation.ads +./Ada95/samples/sample-form_demo-aux.adb +./Ada95/samples/sample-form_demo-aux.ads +./Ada95/samples/sample-form_demo-handler.adb +./Ada95/samples/sample-form_demo-handler.ads +./Ada95/samples/sample-form_demo.adb +./Ada95/samples/sample-form_demo.ads +./Ada95/samples/sample-function_key_setting.adb +./Ada95/samples/sample-function_key_setting.ads +./Ada95/samples/sample-header_handler.adb +./Ada95/samples/sample-header_handler.ads +./Ada95/samples/sample-helpers.adb +./Ada95/samples/sample-helpers.ads +./Ada95/samples/sample-keyboard_handler.adb +./Ada95/samples/sample-keyboard_handler.ads +./Ada95/samples/sample-manifest.ads +./Ada95/samples/sample-menu_demo-aux.adb +./Ada95/samples/sample-menu_demo-aux.ads +./Ada95/samples/sample-menu_demo-handler.adb +./Ada95/samples/sample-menu_demo-handler.ads +./Ada95/samples/sample-menu_demo.adb +./Ada95/samples/sample-menu_demo.ads +./Ada95/samples/sample-my_field_type.adb +./Ada95/samples/sample-my_field_type.ads +./Ada95/samples/sample-text_io_demo.adb +./Ada95/samples/sample-text_io_demo.ads +./Ada95/samples/sample.adb +./Ada95/samples/sample.ads +./Ada95/samples/status.adb +./Ada95/samples/status.ads +./Ada95/samples/tour.adb +./Ada95/samples/tour.ads +./Ada95/src/Makefile.in +./Ada95/src/terminal_interface-curses-aux.adb +./Ada95/src/terminal_interface-curses-forms-field_types-alpha.adb +./Ada95/src/terminal_interface-curses-forms-field_types-alpha.ads +./Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.adb +./Ada95/src/terminal_interface-curses-forms-field_types-alphanumeric.ads +./Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.adb +./Ada95/src/terminal_interface-curses-forms-field_types-enumeration-ada.ads +./Ada95/src/terminal_interface-curses-forms-field_types-enumeration.adb +./Ada95/src/terminal_interface-curses-forms-field_types-enumeration.ads +./Ada95/src/terminal_interface-curses-forms-field_types-intfield.adb +./Ada95/src/terminal_interface-curses-forms-field_types-intfield.ads +./Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.adb +./Ada95/src/terminal_interface-curses-forms-field_types-ipv4_address.ads +./Ada95/src/terminal_interface-curses-forms-field_types-numeric.adb +./Ada95/src/terminal_interface-curses-forms-field_types-numeric.ads +./Ada95/src/terminal_interface-curses-forms-field_types-regexp.adb +./Ada95/src/terminal_interface-curses-forms-field_types-regexp.ads +./Ada95/src/terminal_interface-curses-forms-field_types-user-choice.adb +./Ada95/src/terminal_interface-curses-forms-field_types-user-choice.ads +./Ada95/src/terminal_interface-curses-forms-field_types-user.adb +./Ada95/src/terminal_interface-curses-forms-field_types-user.ads +./Ada95/src/terminal_interface-curses-forms-field_types.adb +./Ada95/src/terminal_interface-curses-forms-field_user_data.adb +./Ada95/src/terminal_interface-curses-forms-form_user_data.adb +./Ada95/src/terminal_interface-curses-forms.adb +./Ada95/src/terminal_interface-curses-menus-item_user_data.adb +./Ada95/src/terminal_interface-curses-menus-menu_user_data.adb +./Ada95/src/terminal_interface-curses-menus.adb +./Ada95/src/terminal_interface-curses-mouse.adb +./Ada95/src/terminal_interface-curses-panels-user_data.adb +./Ada95/src/terminal_interface-curses-panels.adb +./Ada95/src/terminal_interface-curses-text_io-aux.adb +./Ada95/src/terminal_interface-curses-text_io-aux.ads +./Ada95/src/terminal_interface-curses-text_io-complex_io.adb +./Ada95/src/terminal_interface-curses-text_io-complex_io.ads +./Ada95/src/terminal_interface-curses-text_io-decimal_io.adb +./Ada95/src/terminal_interface-curses-text_io-decimal_io.ads +./Ada95/src/terminal_interface-curses-text_io-enumeration_io.adb +./Ada95/src/terminal_interface-curses-text_io-enumeration_io.ads +./Ada95/src/terminal_interface-curses-text_io-fixed_io.adb +./Ada95/src/terminal_interface-curses-text_io-fixed_io.ads +./Ada95/src/terminal_interface-curses-text_io-float_io.adb +./Ada95/src/terminal_interface-curses-text_io-float_io.ads +./Ada95/src/terminal_interface-curses-text_io-integer_io.adb +./Ada95/src/terminal_interface-curses-text_io-integer_io.ads +./Ada95/src/terminal_interface-curses-text_io-modular_io.adb +./Ada95/src/terminal_interface-curses-text_io-modular_io.ads +./Ada95/src/terminal_interface-curses-text_io.adb +./Ada95/src/terminal_interface-curses-text_io.ads +./Ada95/src/terminal_interface-curses.adb +./Ada95/src/terminal_interface.ads +./INSTALL +./MANIFEST +./Makefile.glibc +./Makefile.in +./Makefile.os2 +./NEWS +./README +./README.emx +./README.glibc +./TO-DO +./aclocal.m4 +./announce.html.in +./c++/Makefile.in +./c++/NEWS +./c++/PROBLEMS +./c++/README-first +./c++/cursesapp.cc +./c++/cursesapp.h +./c++/cursesf.cc +./c++/cursesf.h +./c++/cursesm.cc +./c++/cursesm.h +./c++/cursesmain.cc +./c++/cursesp.cc +./c++/cursesp.h +./c++/cursespad.cc +./c++/cursesw.cc +./c++/cursesw.h +./c++/cursslk.cc +./c++/cursslk.h +./c++/demo.cc +./c++/edit_cfg.sh +./c++/etip.h.in +./c++/headers +./c++/internal.h +./c++/modules +./config.guess +./config.sub +./configure +./configure.in +./convert_configure.pl +./dist.mk +./doc/hackguide.doc +./doc/html/Ada95.html +./doc/html/ada/files.htm +./doc/html/ada/files/T.htm +./doc/html/ada/funcs.htm +./doc/html/ada/funcs/A.htm +./doc/html/ada/funcs/B.htm +./doc/html/ada/funcs/C.htm +./doc/html/ada/funcs/D.htm +./doc/html/ada/funcs/E.htm +./doc/html/ada/funcs/F.htm +./doc/html/ada/funcs/G.htm +./doc/html/ada/funcs/H.htm +./doc/html/ada/funcs/I.htm +./doc/html/ada/funcs/K.htm +./doc/html/ada/funcs/L.htm +./doc/html/ada/funcs/M.htm +./doc/html/ada/funcs/N.htm +./doc/html/ada/funcs/O.htm +./doc/html/ada/funcs/P.htm +./doc/html/ada/funcs/Q.htm +./doc/html/ada/funcs/R.htm +./doc/html/ada/funcs/S.htm +./doc/html/ada/funcs/T.htm +./doc/html/ada/funcs/U.htm +./doc/html/ada/funcs/V.htm +./doc/html/ada/funcs/W.htm +./doc/html/ada/index.htm +./doc/html/ada/main.htm +./doc/html/ada/table.html +./doc/html/ada/terminal_interface-curses-aux__adb.htm +./doc/html/ada/terminal_interface-curses-aux__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-alpha__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-alpha__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-alphanumeric__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-enumeration-ada__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-enumeration__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-intfield__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-intfield__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-ipv4_address__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-numeric__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-numeric__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-regexp__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-regexp__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-user-choice__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-user__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types-user__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_types__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_types__ads.htm +./doc/html/ada/terminal_interface-curses-forms-field_user_data__adb.htm +./doc/html/ada/terminal_interface-curses-forms-field_user_data__ads.htm +./doc/html/ada/terminal_interface-curses-forms-form_user_data__adb.htm +./doc/html/ada/terminal_interface-curses-forms-form_user_data__ads.htm +./doc/html/ada/terminal_interface-curses-forms__adb.htm +./doc/html/ada/terminal_interface-curses-forms__ads.htm +./doc/html/ada/terminal_interface-curses-menus-item_user_data__adb.htm +./doc/html/ada/terminal_interface-curses-menus-item_user_data__ads.htm +./doc/html/ada/terminal_interface-curses-menus-menu_user_data__adb.htm +./doc/html/ada/terminal_interface-curses-menus-menu_user_data__ads.htm +./doc/html/ada/terminal_interface-curses-menus__adb.htm +./doc/html/ada/terminal_interface-curses-menus__ads.htm +./doc/html/ada/terminal_interface-curses-mouse__adb.htm +./doc/html/ada/terminal_interface-curses-mouse__ads.htm +./doc/html/ada/terminal_interface-curses-panels-user_data__adb.htm +./doc/html/ada/terminal_interface-curses-panels-user_data__ads.htm +./doc/html/ada/terminal_interface-curses-panels__adb.htm +./doc/html/ada/terminal_interface-curses-panels__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-aux__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-aux__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-complex_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-complex_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-decimal_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-decimal_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-enumeration_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-enumeration_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-fixed_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-fixed_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-float_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-float_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-integer_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-integer_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io-modular_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io-modular_io__ads.htm +./doc/html/ada/terminal_interface-curses-text_io__adb.htm +./doc/html/ada/terminal_interface-curses-text_io__ads.htm +./doc/html/ada/terminal_interface-curses__adb.htm +./doc/html/ada/terminal_interface-curses__ads.htm +./doc/html/ada/terminal_interface__ads.htm +./doc/html/announce.html +./doc/html/hackguide.html +./doc/html/index.html +./doc/html/man/captoinfo.1m.html +./doc/html/man/clear.1.html +./doc/html/man/curs_addch.3x.html +./doc/html/man/curs_addchstr.3x.html +./doc/html/man/curs_addstr.3x.html +./doc/html/man/curs_attr.3x.html +./doc/html/man/curs_beep.3x.html +./doc/html/man/curs_bkgd.3x.html +./doc/html/man/curs_border.3x.html +./doc/html/man/curs_clear.3x.html +./doc/html/man/curs_color.3x.html +./doc/html/man/curs_delch.3x.html +./doc/html/man/curs_deleteln.3x.html +./doc/html/man/curs_extend.3x.html +./doc/html/man/curs_getch.3x.html +./doc/html/man/curs_getstr.3x.html +./doc/html/man/curs_getyx.3x.html +./doc/html/man/curs_inch.3x.html +./doc/html/man/curs_inchstr.3x.html +./doc/html/man/curs_initscr.3x.html +./doc/html/man/curs_inopts.3x.html +./doc/html/man/curs_insch.3x.html +./doc/html/man/curs_insstr.3x.html +./doc/html/man/curs_instr.3x.html +./doc/html/man/curs_kernel.3x.html +./doc/html/man/curs_mouse.3x.html +./doc/html/man/curs_move.3x.html +./doc/html/man/curs_outopts.3x.html +./doc/html/man/curs_overlay.3x.html +./doc/html/man/curs_pad.3x.html +./doc/html/man/curs_print.3x.html +./doc/html/man/curs_printw.3x.html +./doc/html/man/curs_refresh.3x.html +./doc/html/man/curs_scanw.3x.html +./doc/html/man/curs_scr_dump.3x.html +./doc/html/man/curs_scroll.3x.html +./doc/html/man/curs_slk.3x.html +./doc/html/man/curs_termattrs.3x.html +./doc/html/man/curs_termcap.3x.html +./doc/html/man/curs_terminfo.3x.html +./doc/html/man/curs_touch.3x.html +./doc/html/man/curs_trace.3x.html +./doc/html/man/curs_util.3x.html +./doc/html/man/curs_window.3x.html +./doc/html/man/default_colors.3x.html +./doc/html/man/define_key.3x.html +./doc/html/man/form.3x.html +./doc/html/man/form_cursor.3x.html +./doc/html/man/form_data.3x.html +./doc/html/man/form_driver.3x.html +./doc/html/man/form_field.3x.html +./doc/html/man/form_field_attributes.3x.html +./doc/html/man/form_field_buffer.3x.html +./doc/html/man/form_field_info.3x.html +./doc/html/man/form_field_just.3x.html +./doc/html/man/form_field_new.3x.html +./doc/html/man/form_field_opts.3x.html +./doc/html/man/form_field_userptr.3x.html +./doc/html/man/form_field_validation.3x.html +./doc/html/man/form_fieldtype.3x.html +./doc/html/man/form_hook.3x.html +./doc/html/man/form_new.3x.html +./doc/html/man/form_new_page.3x.html +./doc/html/man/form_opts.3x.html +./doc/html/man/form_page.3x.html +./doc/html/man/form_post.3x.html +./doc/html/man/form_requestname.3x.html +./doc/html/man/form_userptr.3x.html +./doc/html/man/form_win.3x.html +./doc/html/man/infocmp.1m.html +./doc/html/man/infotocap.1m.html +./doc/html/man/keybound.3x.html +./doc/html/man/keyok.3x.html +./doc/html/man/menu.3x.html +./doc/html/man/menu_attributes.3x.html +./doc/html/man/menu_cursor.3x.html +./doc/html/man/menu_driver.3x.html +./doc/html/man/menu_format.3x.html +./doc/html/man/menu_hook.3x.html +./doc/html/man/menu_items.3x.html +./doc/html/man/menu_mark.3x.html +./doc/html/man/menu_new.3x.html +./doc/html/man/menu_opts.3x.html +./doc/html/man/menu_pattern.3x.html +./doc/html/man/menu_post.3x.html +./doc/html/man/menu_requestname.3x.html +./doc/html/man/menu_spacing.3x.html +./doc/html/man/menu_userptr.3x.html +./doc/html/man/menu_win.3x.html +./doc/html/man/mitem_current.3x.html +./doc/html/man/mitem_name.3x.html +./doc/html/man/mitem_new.3x.html +./doc/html/man/mitem_opts.3x.html +./doc/html/man/mitem_userptr.3x.html +./doc/html/man/mitem_value.3x.html +./doc/html/man/mitem_visible.3x.html +./doc/html/man/ncurses.3x.html +./doc/html/man/panel.3x.html +./doc/html/man/resizeterm.3x.html +./doc/html/man/term.5.html +./doc/html/man/term.7.html +./doc/html/man/terminfo.5.html +./doc/html/man/tic.1m.html +./doc/html/man/toe.1m.html +./doc/html/man/tput.1.html +./doc/html/man/tset.1.html +./doc/html/man/wresize.3x.html +./doc/html/ncurses-intro.html +./doc/ncurses-intro.doc +./form/Makefile.in +./form/READ.ME +./form/fld_arg.c +./form/fld_attr.c +./form/fld_current.c +./form/fld_def.c +./form/fld_dup.c +./form/fld_ftchoice.c +./form/fld_ftlink.c +./form/fld_info.c +./form/fld_just.c +./form/fld_link.c +./form/fld_max.c +./form/fld_move.c +./form/fld_newftyp.c +./form/fld_opts.c +./form/fld_pad.c +./form/fld_page.c +./form/fld_stat.c +./form/fld_type.c +./form/fld_user.c +./form/form.h +./form/form.priv.h +./form/frm_cursor.c +./form/frm_data.c +./form/frm_def.c +./form/frm_driver.c +./form/frm_hook.c +./form/frm_opts.c +./form/frm_page.c +./form/frm_post.c +./form/frm_req_name.c +./form/frm_scale.c +./form/frm_sub.c +./form/frm_user.c +./form/frm_win.c +./form/fty_alnum.c +./form/fty_alpha.c +./form/fty_enum.c +./form/fty_int.c +./form/fty_ipv4.c +./form/fty_num.c +./form/fty_regex.c +./form/headers +./form/llib-lform +./form/modules +./include/Caps +./include/MKhashsize.sh +./include/MKncurses_def.sh +./include/MKparametrized.sh +./include/MKterm.h.awk.in +./include/Makefile.in +./include/capdefaults.c +./include/curses.h.in +./include/edit_cfg.sh +./include/headers +./include/nc_alloc.h +./include/nc_panel.h +./include/ncurses_cfg.hin +./include/ncurses_defs +./include/term_entry.h +./include/termcap.h.in +./include/tic.h +./include/unctrl.h.in +./install-sh +./man/MKterminfo.sh +./man/Makefile.in +./man/captoinfo.1m +./man/clear.1 +./man/curs_addch.3x +./man/curs_addchstr.3x +./man/curs_addstr.3x +./man/curs_attr.3x +./man/curs_beep.3x +./man/curs_bkgd.3x +./man/curs_border.3x +./man/curs_clear.3x +./man/curs_color.3x +./man/curs_delch.3x +./man/curs_deleteln.3x +./man/curs_extend.3x +./man/curs_getch.3x +./man/curs_getstr.3x +./man/curs_getyx.3x +./man/curs_inch.3x +./man/curs_inchstr.3x +./man/curs_initscr.3x +./man/curs_inopts.3x +./man/curs_insch.3x +./man/curs_insstr.3x +./man/curs_instr.3x +./man/curs_kernel.3x +./man/curs_mouse.3x +./man/curs_move.3x +./man/curs_outopts.3x +./man/curs_overlay.3x +./man/curs_pad.3x +./man/curs_print.3x +./man/curs_printw.3x +./man/curs_refresh.3x +./man/curs_scanw.3x +./man/curs_scr_dump.3x +./man/curs_scroll.3x +./man/curs_slk.3x +./man/curs_termattrs.3x +./man/curs_termcap.3x +./man/curs_terminfo.3x +./man/curs_touch.3x +./man/curs_trace.3x +./man/curs_util.3x +./man/curs_window.3x +./man/default_colors.3x +./man/define_key.3x +./man/form.3x +./man/form_cursor.3x +./man/form_data.3x +./man/form_driver.3x +./man/form_field.3x +./man/form_field_attributes.3x +./man/form_field_buffer.3x +./man/form_field_info.3x +./man/form_field_just.3x +./man/form_field_new.3x +./man/form_field_opts.3x +./man/form_field_userptr.3x +./man/form_field_validation.3x +./man/form_fieldtype.3x +./man/form_hook.3x +./man/form_new.3x +./man/form_new_page.3x +./man/form_opts.3x +./man/form_page.3x +./man/form_post.3x +./man/form_requestname.3x +./man/form_userptr.3x +./man/form_win.3x +./man/infocmp.1m +./man/infotocap.1m +./man/keybound.3x +./man/keyok.3x +./man/make_sed.sh +./man/man_db.renames +./man/manlinks.sed +./man/menu.3x +./man/menu_attributes.3x +./man/menu_cursor.3x +./man/menu_driver.3x +./man/menu_format.3x +./man/menu_hook.3x +./man/menu_items.3x +./man/menu_mark.3x +./man/menu_new.3x +./man/menu_opts.3x +./man/menu_pattern.3x +./man/menu_post.3x +./man/menu_requestname.3x +./man/menu_spacing.3x +./man/menu_userptr.3x +./man/menu_win.3x +./man/mitem_current.3x +./man/mitem_name.3x +./man/mitem_new.3x +./man/mitem_opts.3x +./man/mitem_userptr.3x +./man/mitem_value.3x +./man/mitem_visible.3x +./man/ncurses.3x +./man/panel.3x +./man/resizeterm.3x +./man/term.5 +./man/term.7 +./man/terminfo.head +./man/terminfo.tail +./man/tic.1m +./man/toe.1m +./man/tput.1 +./man/tset.1 +./man/wresize.3x +./menu/Makefile.in +./menu/READ.ME +./menu/eti.h +./menu/headers +./menu/llib-lmenu +./menu/m_attribs.c +./menu/m_cursor.c +./menu/m_driver.c +./menu/m_format.c +./menu/m_global.c +./menu/m_hook.c +./menu/m_item_cur.c +./menu/m_item_nam.c +./menu/m_item_new.c +./menu/m_item_opt.c +./menu/m_item_top.c +./menu/m_item_use.c +./menu/m_item_val.c +./menu/m_item_vis.c +./menu/m_items.c +./menu/m_new.c +./menu/m_opts.c +./menu/m_pad.c +./menu/m_pattern.c +./menu/m_post.c +./menu/m_req_name.c +./menu/m_scale.c +./menu/m_spacing.c +./menu/m_sub.c +./menu/m_userptr.c +./menu/m_win.c +./menu/menu.h +./menu/menu.priv.h +./menu/mf_common.h +./menu/modules +./misc/Makefile.in +./misc/chkdef.cmd +./misc/cleantic.cmd +./misc/cmpdef.cmd +./misc/emx.src +./misc/form.def +./misc/form.ref +./misc/indent.pro +./misc/makedef.cmd +./misc/makellib +./misc/menu.def +./misc/menu.ref +./misc/ncurses.def +./misc/ncurses.ref +./misc/panel.def +./misc/panel.ref +./misc/run_tic.in +./misc/shlib +./misc/tabset/std +./misc/tabset/stdcrt +./misc/tabset/vt100 +./misc/tabset/vt300 +./misc/tdlint +./misc/terminfo.src +./mk-0th.awk +./mk-1st.awk +./mk-2nd.awk +./mkinstalldirs +./ncurses/Makefile.in +./ncurses/README +./ncurses/SigAction.h +./ncurses/base/MKkeyname.awk +./ncurses/base/MKlib_gen.sh +./ncurses/base/MKunctrl.awk +./ncurses/base/README +./ncurses/base/define_key.c +./ncurses/base/keybound.c +./ncurses/base/keyok.c +./ncurses/base/lib_addch.c +./ncurses/base/lib_addstr.c +./ncurses/base/lib_beep.c +./ncurses/base/lib_bkgd.c +./ncurses/base/lib_box.c +./ncurses/base/lib_chgat.c +./ncurses/base/lib_clear.c +./ncurses/base/lib_clearok.c +./ncurses/base/lib_clrbot.c +./ncurses/base/lib_clreol.c +./ncurses/base/lib_color.c +./ncurses/base/lib_colorset.c +./ncurses/base/lib_delch.c +./ncurses/base/lib_delwin.c +./ncurses/base/lib_dft_fgbg.c +./ncurses/base/lib_echo.c +./ncurses/base/lib_endwin.c +./ncurses/base/lib_erase.c +./ncurses/base/lib_flash.c +./ncurses/base/lib_freeall.c +./ncurses/base/lib_getch.c +./ncurses/base/lib_getstr.c +./ncurses/base/lib_hline.c +./ncurses/base/lib_immedok.c +./ncurses/base/lib_inchstr.c +./ncurses/base/lib_initscr.c +./ncurses/base/lib_insch.c +./ncurses/base/lib_insdel.c +./ncurses/base/lib_insstr.c +./ncurses/base/lib_instr.c +./ncurses/base/lib_isendwin.c +./ncurses/base/lib_leaveok.c +./ncurses/base/lib_mouse.c +./ncurses/base/lib_move.c +./ncurses/base/lib_mvwin.c +./ncurses/base/lib_newterm.c +./ncurses/base/lib_newwin.c +./ncurses/base/lib_nl.c +./ncurses/base/lib_overlay.c +./ncurses/base/lib_pad.c +./ncurses/base/lib_printw.c +./ncurses/base/lib_redrawln.c +./ncurses/base/lib_refresh.c +./ncurses/base/lib_restart.c +./ncurses/base/lib_scanw.c +./ncurses/base/lib_screen.c +./ncurses/base/lib_scroll.c +./ncurses/base/lib_scrollok.c +./ncurses/base/lib_scrreg.c +./ncurses/base/lib_set_term.c +./ncurses/base/lib_slk.c +./ncurses/base/lib_slkatr_set.c +./ncurses/base/lib_slkatrof.c +./ncurses/base/lib_slkatron.c +./ncurses/base/lib_slkatrset.c +./ncurses/base/lib_slkattr.c +./ncurses/base/lib_slkclear.c +./ncurses/base/lib_slkcolor.c +./ncurses/base/lib_slkinit.c +./ncurses/base/lib_slklab.c +./ncurses/base/lib_slkrefr.c +./ncurses/base/lib_slkset.c +./ncurses/base/lib_slktouch.c +./ncurses/base/lib_touch.c +./ncurses/base/lib_ungetch.c +./ncurses/base/lib_vline.c +./ncurses/base/lib_wattroff.c +./ncurses/base/lib_wattron.c +./ncurses/base/lib_winch.c +./ncurses/base/lib_window.c +./ncurses/base/memmove.c +./ncurses/base/nc_panel.c +./ncurses/base/resizeterm.c +./ncurses/base/safe_sprintf.c +./ncurses/base/sigaction.c +./ncurses/base/tries.c +./ncurses/base/version.c +./ncurses/base/vsscanf.c +./ncurses/base/wresize.c +./ncurses/curses.priv.h +./ncurses/fifo_defs.h +./ncurses/llib-lncurses +./ncurses/modules +./ncurses/tinfo/MKcaptab.awk +./ncurses/tinfo/MKfallback.sh +./ncurses/tinfo/MKnames.awk +./ncurses/tinfo/README +./ncurses/tinfo/access.c +./ncurses/tinfo/add_tries.c +./ncurses/tinfo/alloc_entry.c +./ncurses/tinfo/alloc_ttype.c +./ncurses/tinfo/captoinfo.c +./ncurses/tinfo/comp_error.c +./ncurses/tinfo/comp_expand.c +./ncurses/tinfo/comp_hash.c +./ncurses/tinfo/comp_parse.c +./ncurses/tinfo/comp_scan.c +./ncurses/tinfo/doalloc.c +./ncurses/tinfo/free_ttype.c +./ncurses/tinfo/getenv_num.c +./ncurses/tinfo/home_terminfo.c +./ncurses/tinfo/init_keytry.c +./ncurses/tinfo/keys.list +./ncurses/tinfo/lib_acs.c +./ncurses/tinfo/lib_baudrate.c +./ncurses/tinfo/lib_cur_term.c +./ncurses/tinfo/lib_data.c +./ncurses/tinfo/lib_has_cap.c +./ncurses/tinfo/lib_kernel.c +./ncurses/tinfo/lib_longname.c +./ncurses/tinfo/lib_napms.c +./ncurses/tinfo/lib_options.c +./ncurses/tinfo/lib_print.c +./ncurses/tinfo/lib_raw.c +./ncurses/tinfo/lib_setup.c +./ncurses/tinfo/lib_termcap.c +./ncurses/tinfo/lib_termname.c +./ncurses/tinfo/lib_tgoto.c +./ncurses/tinfo/lib_ti.c +./ncurses/tinfo/lib_tparm.c +./ncurses/tinfo/lib_tputs.c +./ncurses/tinfo/lib_ttyflags.c +./ncurses/tinfo/make_keys.c +./ncurses/tinfo/name_match.c +./ncurses/tinfo/parse_entry.c +./ncurses/tinfo/read_entry.c +./ncurses/tinfo/read_termcap.c +./ncurses/tinfo/setbuf.c +./ncurses/tinfo/strings.c +./ncurses/tinfo/write_entry.c +./ncurses/trace/README +./ncurses/trace/lib_trace.c +./ncurses/trace/lib_traceatr.c +./ncurses/trace/lib_tracebits.c +./ncurses/trace/lib_tracechr.c +./ncurses/trace/lib_tracedmp.c +./ncurses/trace/lib_tracemse.c +./ncurses/trace/trace_buf.c +./ncurses/trace/trace_tries.c +./ncurses/trace/trace_xnames.c +./ncurses/tty/MKexpanded.sh +./ncurses/tty/hardscroll.c +./ncurses/tty/hashmap.c +./ncurses/tty/lib_mvcur.c +./ncurses/tty/lib_tstp.c +./ncurses/tty/lib_twait.c +./ncurses/tty/lib_vidattr.c +./ncurses/tty/tty_display.h +./ncurses/tty/tty_input.h +./ncurses/tty/tty_update.c +./panel/Makefile.in +./panel/headers +./panel/llib-lpanel +./panel/modules +./panel/p_above.c +./panel/p_below.c +./panel/p_bottom.c +./panel/p_delete.c +./panel/p_hidden.c +./panel/p_hide.c +./panel/p_move.c +./panel/p_new.c +./panel/p_replace.c +./panel/p_show.c +./panel/p_top.c +./panel/p_update.c +./panel/p_user.c +./panel/p_win.c +./panel/panel.c +./panel/panel.h +./panel/panel.priv.h +./progs/MKtermsort.sh +./progs/Makefile.in +./progs/capconvert +./progs/clear.c +./progs/clear.sh +./progs/dump_entry.c +./progs/dump_entry.h +./progs/infocmp.c +./progs/modules +./progs/progs.priv.h +./progs/tic.c +./progs/toe.c +./progs/tput.c +./progs/tset.c +./sysdeps/unix/sysv/linux/Makefile +./sysdeps/unix/sysv/linux/alpha/configure +./sysdeps/unix/sysv/linux/configure +./sysdeps/unix/sysv/linux/edit_man.sed +./sysdeps/unix/sysv/linux/edit_man.sh +./sysdeps/unix/sysv/linux/run_tic.sh +./tack/COPYING +./tack/HISTORY +./tack/Makefile.in +./tack/README +./tack/ansi.c +./tack/charset.c +./tack/color.c +./tack/control.c +./tack/crum.c +./tack/edit.c +./tack/fun.c +./tack/init.c +./tack/menu.c +./tack/modes.c +./tack/modules +./tack/output.c +./tack/pad.c +./tack/scan.c +./tack/sync.c +./tack/sysdep.c +./tack/tack.1 +./tack/tack.c +./tack/tack.h +./tar-copy.sh +./test/Makefile.in +./test/README +./test/blue.c +./test/bs.6 +./test/bs.c +./test/cardfile.c +./test/cardfile.dat +./test/configure +./test/configure.in +./test/ditto.c +./test/dots.c +./test/filter.c +./test/firework.c +./test/firstlast.c +./test/gdc.6 +./test/gdc.c +./test/hanoi.c +./test/hashtest.c +./test/keynames.c +./test/knight.c +./test/lrtest.c +./test/modules +./test/ncurses.c +./test/ncurses_tst.hin +./test/newdemo.c +./test/railroad.c +./test/rain.c +./test/tclock.c +./test/test.priv.h +./test/testaddch.c +./test/testcurs.c +./test/testscanw.c +./test/tracemunch +./test/view.c +./test/worm.c +./test/xmas.c diff --git a/ncurses-5.2/Makefile.glibc b/ncurses-5.2/Makefile.glibc new file mode 100644 index 0000000..780650a --- /dev/null +++ b/ncurses-5.2/Makefile.glibc @@ -0,0 +1,403 @@ +# Copyright (C) 1997,1998 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If not, +# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# +# Makefile for ncurses part. +# +subdir := ncurses + +ncurses-version = 4.2 +form-version = $(ncurses-version) +menu-version = $(ncurses-version) +panel-version = $(ncurses-version) + +extras := form menu ncurses panel + +extra-libs = $(extras:%=lib%) +# These libraries will be built in the `others' pass rather than +# the `lib' pass, because they depend on libc.so being built already. +extra-libs-others = $(extra-libs) + +# The sources are found in the appropriate subdir. +subdir-dirs = $(extras) progs test +vpath %.c $(subdir-dirs) +vpath %.h $(subdir-dirs) + +libform-routines = \ + fld_arg \ + fld_attr \ + fld_current \ + fld_def \ + fld_dup \ + fld_ftchoice \ + fld_ftlink \ + fld_info \ + fld_just \ + fld_link \ + fld_max \ + fld_move \ + fld_newftyp \ + fld_opts \ + fld_pad \ + fld_page \ + fld_stat \ + fld_type \ + fld_user \ + frm_cursor \ + frm_data \ + frm_def \ + frm_driver \ + frm_hook \ + frm_opts \ + frm_page \ + frm_post \ + frm_req_name \ + frm_scale \ + frm_sub \ + frm_user \ + frm_win \ + fty_alnum \ + fty_alpha \ + fty_enum \ + fty_int \ + fty_ipv4 \ + fty_num \ + fty_regex + +libncurses-routines = \ + base/define_key \ + base/keybound \ + base/keyok \ + base/lib_addch \ + base/lib_addstr \ + base/lib_beep \ + base/lib_bkgd \ + base/lib_box \ + base/lib_chgat \ + base/lib_clear \ + base/lib_clearok \ + base/lib_clrbot \ + base/lib_clreol \ + base/lib_color \ + base/lib_colorset \ + base/lib_delch \ + base/lib_delwin \ + base/lib_dft_fgbg \ + base/lib_echo \ + base/lib_endwin \ + base/lib_erase \ + base/lib_flash \ + base/lib_freeall \ + base/lib_getch \ + base/lib_getstr \ + base/lib_hline \ + base/lib_immedok \ + base/lib_inchstr \ + base/lib_initscr \ + base/lib_insch \ + base/lib_insdel \ + base/lib_insstr \ + base/lib_instr \ + base/lib_isendwin \ + base/lib_leaveok \ + base/lib_mouse \ + base/lib_move \ + base/lib_mvwin \ + base/lib_newterm \ + base/lib_newwin \ + base/lib_nl \ + base/lib_overlay \ + base/lib_pad \ + base/lib_printw \ + base/lib_redrawln \ + base/lib_refresh \ + base/lib_restart \ + base/lib_scanw \ + base/lib_screen \ + base/lib_scroll \ + base/lib_scrollok \ + base/lib_scrreg \ + base/lib_set_term \ + base/lib_slk \ + base/lib_slkatr_set \ + base/lib_slkatrof \ + base/lib_slkatron \ + base/lib_slkatrset \ + base/lib_slkattr \ + base/lib_slkclear \ + base/lib_slkcolor \ + base/lib_slkinit \ + base/lib_slklab \ + base/lib_slkrefr \ + base/lib_slkset \ + base/lib_slktouch \ + base/lib_touch \ + base/lib_ungetch \ + base/lib_vline \ + base/lib_wattroff \ + base/lib_wattron \ + base/lib_winch \ + base/lib_window \ + base/memmove \ + base/nc_panel \ + base/resizeterm \ + base/safe_sprintf \ + base/sigaction \ + base/tries \ + base/version \ + base/vsscanf \ + base/wresize \ + codes \ + comp_captab \ + expanded \ + fallback \ + lib_gen \ + lib_keyname \ + names \ + tinfo/access \ + tinfo/add_tries \ + tinfo/alloc_entry \ + tinfo/alloc_ttype \ + tinfo/captoinfo \ + tinfo/comp_error \ + tinfo/comp_expand \ + tinfo/comp_hash \ + tinfo/comp_parse \ + tinfo/comp_scan \ + tinfo/doalloc \ + tinfo/free_ttype \ + tinfo/getenv_num \ + tinfo/home_terminfo \ + tinfo/init_keytry \ + tinfo/lib_acs \ + tinfo/lib_baudrate \ + tinfo/lib_cur_term \ + tinfo/lib_data \ + tinfo/lib_has_cap \ + tinfo/lib_kernel \ + tinfo/lib_longname \ + tinfo/lib_napms \ + tinfo/lib_options \ + tinfo/lib_print \ + tinfo/lib_raw \ + tinfo/lib_setup \ + tinfo/lib_termcap \ + tinfo/lib_termname \ + tinfo/lib_tgoto \ + tinfo/lib_ti \ + tinfo/lib_tparm \ + tinfo/lib_tputs \ + tinfo/lib_ttyflags \ + tinfo/name_match \ + tinfo/parse_entry \ + tinfo/read_entry \ + tinfo/read_termcap \ + tinfo/setbuf \ + tinfo/strings \ + tinfo/write_entry \ + trace/lib_trace \ + trace/lib_traceatr \ + trace/lib_tracebits \ + trace/lib_tracechr \ + trace/lib_tracedmp \ + trace/lib_tracemse \ + trace/trace_buf \ + trace/trace_tries \ + trace/trace_xnames \ + tty/hardscroll \ + tty/hashmap \ + tty/lib_mvcur \ + tty/lib_tstp \ + tty/lib_vidattr \ + tty/lib_twait \ + tty/tty_update \ + unctrl + +libmenu-routines = \ + m_attribs \ + m_cursor \ + m_driver \ + m_format \ + m_global \ + m_hook \ + m_item_cur \ + m_item_nam \ + m_item_new \ + m_item_opt \ + m_item_top \ + m_item_use \ + m_item_val \ + m_item_vis \ + m_items \ + m_new \ + m_opts \ + m_pad \ + m_pattern \ + m_post \ + m_req_name \ + m_scale \ + m_spacing \ + m_sub \ + m_userptr \ + m_win + +libpanel-routines = \ + panel \ + p_above \ + p_below \ + p_bottom \ + p_delete \ + p_hide \ + p_hidden \ + p_move \ + p_new \ + p_replace \ + p_show \ + p_top \ + p_update \ + p_user \ + p_win + +headers = curses.h eti.h form.h menu.h panel.h term.h termcap.h \ + unctrl.h +others = clear infocmp tic toe tput tset +install-bin = $(others) + +clear-objs = clear.o +infocmp-objs = infocmp.o dump_entry.o +tic-objs = tic.o dump_entry.o +toe-objs = toe.o dump_entry.o +tput-objs = tput.o +tset-objs = tset.o dump_entry.o +extra-objs = $(tic-objs) $(toe-objs) $(infocmp-objs) $(clear-objs) \ + $(tput-objs) $(tset-objs) + +test-srcs = blue bs cardfile ditto firework firstlast gdc hanoi hashtest knight \ + lrtest ncurses newdemo rain tclock testaddch testcurs \ + testscanw view worm xmas + +include ../Rules + +ifndef tabsetdir +tabsetdir = $(datadir)/tabset +endif +ifndef inst_tabsetdir +inst_tabsetdir = $(install_root)/$(tabsetdir) +endif + +ifndef terminfodir +terminfodir = $(datadir)/terminfo +endif +ifndef inst_terminfodir +inst_terminfodir = $(install_root)/$(terminfodir) +endif + +ifndef mandir +mandir = $(prefix)/man +endif + +ifndef inst_mandir +inst_mandir = $(install_root)/$(mandir) +endif + +CPPFLAGS += -DTERMINFO='"$(terminfodir)"' -Iinclude -Iform -Incurses \ + -Imenu -Ipanel -Iprogs -Itest + +ifneq ($(strip $(objpfx)),) +CPPFLAGS += -I$(objpfx) +endif + +LDLIBS-tclock = math/libm + +tests: $(test-srcs:%=$(objpfx)%) + +$(objpfx)clear: $(addprefix $(objpfx),$(clear-objs)) +$(objpfx)infocmp: $(addprefix $(objpfx),$(infocmp-objs)) +$(objpfx)tic: $(addprefix $(objpfx),$(tic-objs)) +$(objpfx)toe: $(addprefix $(objpfx),$(toe-objs)) +$(objpfx)tput: $(addprefix $(objpfx),$(tput-objs)) +$(objpfx)tset: $(addprefix $(objpfx),$(tset-objs)) + +ifeq ($(build-shared),yes) +$(others:%=$(objpfx)%): $(objpfx)libncurses.so +else +$(others:%=$(objpfx)%): $(objpfx)libncurses.a +endif + +$(test-srcs:%=$(objpfx)%): $(objpfx)libform.a $(objpfx)libmenu.a \ + $(objpfx)libpanel.a $(objpfx)libncurses.a + +# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +# This ensures they will load libc.so for needed symbols if loaded by +# a statically-linked program that hasn't already loaded it. +$(extras:%=$(objpfx)lib%.so): $(common-objpfx)libc.so + +subdir_install: $(inst_libdir)/libtermcap.a $(inst_libdir)/libcurses.a \ + $(inst_bindir)/reset $(inst_bindir)/captoinfo + +$(inst_libdir)/libtermcap.a $(inst_libdir)/libcurses.a: \ + $(inst_libdir)/libncurses.a + $(make-link) + +$(inst_bindir)/reset: $(inst_bindir)/tset + $(make-link) + +$(inst_bindir)/captoinfo: $(inst_bindir)/tic + $(make-link) + +ifeq (yes,$(build-shared)) +subdir_install: $(inst_libdir)/libtermcap.so $(inst_libdir)/libcurses.so + +$(inst_libdir)/libtermcap.so $(inst_libdir)/libcurses.so: \ + $(inst_libdir)/libncurses.so + $(make-link) +endif + +subdir_install: $(inst_mandir)/man5/terminfo.5 + +$(inst_mandir)/man5/terminfo.5: $(objpfx)terminfo.5 $(wildcard man/*.[0-9]*) + $(make-target-directory) + sh $(edit_man-sh) $(prefix) $(inst_mandir) $(edit_man-sed) $^ + +subdir_install: $(inst_tabsetdir)/std + +$(inst_tabsetdir)/std: \ + $(filter-out misc/tabset/CVS, $(wildcard misc/tabset/*)) + $(make-target-directory) + for f in $^; do \ + echo installing $$f; \ + $(INSTALL_DATA) $$f $(inst_tabsetdir); \ + done + + +ifeq (no,$(cross-compiling)) +subdir_install: $(inst_terminfodir)/v/vt100 + +$(inst_terminfodir)/v/vt100: misc/terminfo.src $(objpfx)tic + $(make-target-directory) + sh $(run_tic-sh) $(common-objpfx) misc $(terminfodir) \ + $(install_root) +endif + +subdir_distclean subdir_realclean: + -rm -f $(addprefix $(objpfx), MKterm.h.awk codes.c \ + comp_captab.c confdefs.h config.log curses.h \ + expanded.c fallback.c hashsize.h keys.tries \ + lib_gen.c lib_keyname.c names.c ncurses_cfg.h \ + nomacros.h parametrized.h term.h termcap.h \ + terminfo.5 termsort.c unctrl.c unctrl.h) diff --git a/ncurses-5.2/Makefile.in b/ncurses-5.2/Makefile.in new file mode 100644 index 0000000..21238b0 --- /dev/null +++ b/ncurses-5.2/Makefile.in @@ -0,0 +1,92 @@ +# $Id$ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Thomas E. Dickey 1996,1997 +# +# Master Makefile for ncurses library. + +SHELL = /bin/sh + +DESTDIR=@DESTDIR@ +CF_MFLAGS = @cf_cv_makeflags@ DESTDIR="$(DESTDIR)" + +@SET_MAKE@ + +NCURSES_MAJOR = @NCURSES_MAJOR@ +NCURSES_MINOR = @NCURSES_MINOR@ +NCURSES_PATCH = @NCURSES_PATCH@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +ticdir = @TERMINFO@ +includedir = @includedir@ +libdir = @libdir@ +mandir = @mandir@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +DIRS_TO_MAKE = @DIRS_TO_MAKE@ + +all :: $(DIRS_TO_MAKE) + +$(DIRS_TO_MAKE) : + mkdir $@ + +preinstall : + @ echo '' + @ echo '** Configuration summary for NCURSES $(NCURSES_MAJOR).$(NCURSES_MINOR) $(NCURSES_PATCH):' + @ echo '' + @ echo ' bin directory: '$(bindir) + @ echo ' lib directory: '$(libdir) + @ echo ' include directory: '$(includedir) + @ echo ' man directory: '$(mandir) + @ echo ' terminfo directory: '$(ticdir) + @ echo '' + @ test "$(includedir)" = "$(prefix)/include" || \ + echo '** Include-directory is not in a standard location' + @ test ! -f $(includedir)/termcap.h || \ + fgrep NCURSES_VERSION $(includedir)/termcap.h >/dev/null || \ + echo '** Will overwrite non-ncurses termcap.h' + @ test ! -f $(includedir)/curses.h || \ + fgrep NCURSES_VERSION $(includedir)/curses.h >/dev/null || \ + echo '** Will overwrite non-ncurses curses.h' + +# Put the common rules here so that we can easily construct the list of +# directories to visit. +all \ +clean \ +distclean \ +mostlyclean \ +realclean \ +sources \ +uninstall \ +install :: diff --git a/ncurses-5.2/Makefile.os2 b/ncurses-5.2/Makefile.os2 new file mode 100644 index 0000000..ed0f68a --- /dev/null +++ b/ncurses-5.2/Makefile.os2 @@ -0,0 +1,234 @@ +################################################################################ +# Wrapper Makefile for ncurses library under OS/2. +################################################################################ +# $Id$ +# +# Author: Juan Jose Garcia Ripoll . +# Webpage: http://www.arrakis.es/~worm/ +################################################################################ +# +# Notes (from I Zakharevich) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# I could build the library with the following sequence of commands: +# +# touch Makefile +# make -f Makefile.os2 config +# make -f Makefile.os2 CC=gcc HOSTCC=gcc CXX=gcc +# +# Ignoring the following errors: +# Invalid configuration `os2'... +# ... ac_maketemp="make": not found +# ... syntax error: `done' unexpected +# No rule to make target `lib/ncurses4.dll' +# +# You may need to run +# +# rm make.defs +# make -f Makefile.os2 make.defs +# +# if the build of misc/panel.def fails. +# +# If you do not have perl, the configuration will fail. Use autoconf to +# generate the EMX-specific configure script (see README.emx), and run the +# configure script to generate the makefiles. Then, run +# +# make -f Makefile.os2 make.dlls +# +# Notes (from J J G Ripoll) +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# The `make.defs' rule creates the new '.def' files and outputs a diagnostic +# about symbols that disappear from one release to the other, as well as +# checks about the new '.def' consistency. If there were no problems, the +# maintainer is free to replace the `.ref' files with the newer ones using the +# `save.defs' rule. So, the only tough work is ensuring that the symbols that +# disappear are not essential. +# +# I first thought about killing '_nc_*' symbols, but it seems that some of +# them --_nc_panel_hook, _nc_ada*, etc-- are needed outside ncurses.dll. +# However, the whole size of the export table will not be larger than 1k or +# so. +# +# [installation] +# +# The way things are handled in misc/Makefile is not well suited for OS/2, +# where only emx.src is needed. Thus, I've written a few wrapper rules in +# Makefile.os2 that handle installation/deinstallation. +# +# [distribution] +# +# There's also a new rule that configures and builds a sort of binary +# distribution, much like the one I prepared for 1.9.9e. It's `os2dist'. +# +################################################################################ + +all :: config + +# This is for configuring + +# What is a useful value for this? +CONFIG_OPTS = --enable-termcap +WWWGET = lynx -source +MV_F = mv -f +DLL_LN_OPTS = -Zcrtdll -Zdll -Zomf -Zmt + +config: config.cache + +config.cache: configure.cmd configure + -$(MV_F) $@ $@.ref + configure.cmd $(CONFIG_OPTS) + +configure.cmd: configure convert_configure.pl + perl convert_configure.pl configure > $@ + +convert_configure.pl: + $(WWWGET) ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2/$@ > $@ + +install :: + echo *** + echo *** Do not use this command. Use install.os2 instead. + echo *** + exit 2 + +install.os2 : install.emxdata install.libs install.progs + +include ./Makefile + +all :: make.dlls + +# +# DLLs and that stuff +# + +LIBRARIES = ncurses form menu panel + +DLL_TAG = $(NCURSES_MAJOR) +LIB_TAG = _s + +DLL_ROOTS = $(addsuffix $(DLL_TAG), $(LIBRARIES)) +DLLS = $(addsuffix .dll, $(addprefix ./lib/, $(DLL_ROOTS))) + +LIB_ROOTS = $(addsuffix $(LIB_TAG), $(LIBRARIES)) +LIBS = $(addsuffix .lib, $(addprefix ./lib/, $(LIB_ROOTS))) + +LIBS_AOUT = $(addsuffix .a, $(addprefix ./lib/, $(LIB_ROOTS))) + +DEFS = $(addsuffix .def, $(addprefix ./misc/, $(LIBRARIES))) + +DLL_SIGNATURE = NCurses-$(NCURSES_MAJOR)-$(NCURSES_MINOR)-$(NCURSES_PATCH) + +./lib/%$(LIB_TAG).lib : ./misc/%.def + emximp -o $@ $< + +./lib/%$(LIB_TAG).a : ./misc/%.def + emximp -o $@ $< + +./lib/%$(DLL_TAG).dll : ./lib/%.a + emxomf -o ./lib/$*$(DLL_TAG).lib $< + if [ "$*" = "ncurses" ]; then \ + gcc $(LDFLAGS) $(DLL_LN_OPTS) ./lib/$*$(DLL_TAG).lib \ + ./misc/$*.def -o $@; \ + else \ + gcc $(LDFLAGS) $(DLL_LN_OPTS) ./lib/$*$(DLL_TAG).lib \ + ./lib/ncurses$(LIB_TAG).lib ./misc/$*.def -o $@; \ + fi + -rm -f ./lib/$*$(DLL_TAG).lib + +make.dlls : $(DEFS) $(LIBS) $(DLLS) $(LIBS_AOUT) + +$(DEFS) : make.defs + +LIBDIR = $(DESTDIR)$(libdir) +$(LIBDIR) : + mkdir -p $@ + +install.libs :: $(LIBS) $(DLLS) $(LIBDIR) + @for i in $(DLL_ROOTS); do \ + echo installing ./lib/$$i.dll as $(LIBDIR)/$$i.dll; \ + $(INSTALL_DATA) ./lib/$$i.dll $(LIBDIR)/$$i.dll; done + @for i in $(LIB_ROOTS); do \ + echo installing ./lib/$$i.lib as $(LIBDIR)/$$i.lib; \ + $(INSTALL_DATA) ./lib/$$i.lib $(LIBDIR)/$$i.lib; done + +uninstall.libs :: + -@for i in $(DLL_ROOTS); do \ + echo uninstalling $(LIBDIR)/$$i.dll; \ + rm -f $(LIBDIR)/$$i.dll; done + -@for i in $(LIB_ROOTS); do \ + echo uninstalling $(LIBDIR)/$$i.lib; \ + rm -f $(LIBDIR)/$$i.lib; done + +make.defs : + for i in $(LIBRARIES); do \ + echo LIBRARY $${i}$(DLL_TAG) INITINSTANCE TERMINSTANCE > ./misc/$$i.def; \ + echo DESCRIPTION \"$(DLL_SIGNATURE), module $$i\" >> ./misc/$$i.def; \ + echo CODE LOADONCALL >> ./misc/$$i.def; \ + echo DATA LOADONCALL NONSHARED MULTIPLE >> ./misc/$$i.def; \ + echo EXPORTS >> ./misc/$$i.def; \ + echo Creating $$i.def; \ + (cmd /C ".\\misc\\makedef.cmd ./lib/$$i.a ./misc/$$i.ref >> ./misc/$$i.def" \ + && cmd /C ".\\misc\\chkdef.cmd ./misc/$$i.def") \ + || exit 1; \ + done + touch make.defs + +save.defs : + for i in $(LIBRARIES); do \ + test -f ./misc/$$i.def && cp ./misc/$$i.def ./misc/$$i.ref; \ + done + +clean \ +os2clean :: + -rm -f $(DLLS) $(LIBS) + +realclean :: + -rm -f $(addprefix ./misc/, $(addsuffix .def, $(LIBRARIES))) + +# +# This is a simplified version of misc/Makefile +# + +TICDIR = $(DESTDIR)$(datadir)/terminfo +TABSETDIR = $(DESTDIR)$(datadir)/tabset + +$(TICDIR) : + mkdir -p $@ + +install \ +install.emxdata :: $(TICDIR) + -@rm -fr $(TICDIR)/* + echo Building terminfo database, please wait... + set TERMINFO=$(TICDIR); ./progs/tic ./misc/emx.src + echo Installing the terminfo cleaner and the sources... + cp ./misc/emx.src ./misc/cleantic.cmd $(TICDIR) + ./misc/cleantic.cmd $(TICDIR) + +uninstall \ +uninstall.emxdata :: + -cd $(TICDIR) && rm -rf * + -cd $(TABSETDIR) && rm -rf * + +# +# This is for preparing binary distributions +# + +OS2NAME=ncurses-$(NCURSES_MAJOR).$(NCURSES_MINOR)-emx + +# +# FIXME: this assumes that we can rerun the configure script, changing only +# the install-prefix. That means we cannot provide "interesting" options +# when building. +# +os2dist : + $(MAKE) -f Makefile.os2 os2clean + ./configure --without-debug --with-install-prefix=`pwd|sed -e 's@^.:@@'`/$(OS2NAME) + $(MAKE) -f Makefile.os2 $(CF_MFLAGS) install.os2 + -rm -f $(OS2NAME).zip + echo NCurses-$(NCURSES_MAJOR).$(NCURSES_MINOR)-$(NCURSES_PATCH) for emx > $(OS2NAME)/FILE_ID.DIZ + echo Binary release. >> $(OS2NAME)/FILE_ID.DIZ + zip -r $(OS2NAME).zip ./$(OS2NAME) + +clean \ +os2clean :: + -rm -rf $(OS2NAME) + -rm -f $(OS2NAME).zip + diff --git a/ncurses-5.2/NEWS b/ncurses-5.2/NEWS new file mode 100644 index 0000000..fe1b776 --- /dev/null +++ b/ncurses-5.2/NEWS @@ -0,0 +1,4584 @@ +-- $Id$ + +This is a log of changes that ncurses has gone through since Zeyd started +working with Pavel Curtis' original work, pcurses, in 1992. + +Changes through 1.9.9e are recorded by Zeyd M. Ben-Halim. +Changes since 1.9.9e are recorded by Thomas Dickey. + +20001021 5.2 release for upload to ftp.gnu.org + + update generated html files from manpages. + + modify dist.mk to use edit_man.sh to substitute autoconf'd variables + in html manpages. + + fix an uninitialized pointer in read_termcap.c (report by Todd C + Miller, from report/patch by Philip Guenther ). + + correct help-message and array limit in knight.c (patch by Brian + Raiter ). + > patch by Juergen Pfeifer: + + fix to avoid warning by GNAT-3.13p about use of inconsistent casing + for some identifiers defined in the standard package. + + cosmetic change to forms/fty_enum.c + +20001014 + + correct an off-by-one position in test/railroad.c which could cause + wrapping at the right margin. + + test/repair some issues with libtool configuration. Make + --disable-echo force libtool --silent. (Libtool does not work for + OS/2 EMX, works partly for SCO - libtool is still very specific to + gcc). + + change default of --with-manpage-tbl to "no", since for most of the + platforms which do have tbl installed, the system "man" program + understands how to run tbl automatically. + + minor improvement to force_bar() in comp_parse.c (Bernhard + Rosenkraenzer ). + + modify lib_tparm.c to use get_space() before writing terminating + null character, both for consistency as well as to ensure that if + save_char() was called immediately before, that the allocated memory + is enough (patch by Sergei Ivanov). + + add note about termcap ML capability which is duplicated between two + different capabilities: smgl and smglr (reported by Sergei Ivanov + ). + + correct parameter counts in include/Caps for dclk as well as some + printer-specific capabilities: csnm, defc, scs, scsd, smgtp, smglp. + > patch by Johnny C Lam : + + add support for building with libtool (apparently version 1.3.5, + since old versions do not handle -L../lib), using new configure + option --with-libtool. + + add configure option --with-manpage-tbl, which causes the manpages to + be preprocessed by tbl(1) prior to installation, + + add configure option --without-curses-h, which causes the + installation process to install curses.h as ncurses.h and make + appropriate changes to headers and manpages. + +20001009 + + correct order of options/parameters in run_tic.in invocation of tic, + which did not work with standard getopt() (reported by Ethan + Butterfield ). + + correct logic for 'reverse' variable in lib_vidattr.c, which was + setting it true without checking if newmode had A_REVERSE set, e.g., + using $TERM=ansi on OS/2 EMX (see 20000917). + > patch by Todd Miller: + + add a few missing use_terminfo_vars() and fixes up _nc_tgetent(). + Previously, _nc_cgetset() would still get called on cp so the + simplest thing is to set cp to NULL if !use_terminfo_vars(). + + added checks for an empty $HOME environment variable. + > patches by Ilya Zakharevich for OS/2 EMX: + + modify convert_configure.pl to support INSTALL. Change compiler + options in that script to use multithreading, needed for the mouse. + + modify OS/2 mouse support, retrying as a 2-button mouse if code fails + to set up a 3-button mouse. + + improve code for OS/2 mouse support, using _nc_timed_wait() to + replace select() call. + +20001007 + + change type of ospeed variable back to short to match its use in + legacy applications (reported by Andrey A Chernov). + + add case to configure script for --enable-rpath on IRIX (patch by + Albert Chin-A-Young). + + minor fix to position_check() function, to ensure it gets the whole + cursor report before decoding. + + add configure option --disable-assumed-color, to allow pre-5.1 + convention of default colors used for color-pair 0 to be configured + (see assume_default_colors()). + + rename configure option --enable-hashmap --disable-hashmap, and + reorder the configure options, splitting the experimental and + development + + add configure option --disable-root-environ, which tells ncurses to + disregard $TERMINFO and similar environment variables if the current + user is root, or running setuid/setgid (based on discussion with + several people). + + modified misc/run_tic.in to use tic -o, to eliminate dependency on + $TERMINFO variable for installs. + + add table entry for plab_norm to tput, so it passes in strings + for that capability. + + modify parse_format() in lib_tparm.c to ignore precision if it is + longer than 10000 (report by Jouko Pynnonen). + + rewrote limit checks in lib_mvcur.c using new functions + _nc_safe_strcat(), etc. Made other related changes to check lengths + used for strcat/strcpy (report by Jouko Pynnonen ). + +20000930 + + modify several descriptions, including those for setaf, setab, in + include/Caps to indicate that the entries are parameterized. This + information is used to tell which strings are translated when + converting to termcap. Fixes a problem where the generated termcap + would contain a spurious "%p1" for the terminfo "%p1%d". + + modify ld -rpath options (e.g., Linux, and Solaris) to use an + absolute pathname for the build tree's lib directory (prompted by + discussion with Albert Chin-A-Young). + + modify "make install.man" and "make uninstall.man" to include tack's + man-page. + + various fixes for install scripts used to support configure --srcdir + and --with-install-prefix (reported by Matthew Clarke + ). + + make configure script checks on variables $GCC and $GXX consistently + compare against 'yes' rather than test if they are nonnull, since + either may be set to the corresponding name of the C or C++ compiler + (report/patch by Albert Chin-A-Young). + +20000923 + + modify rs2 capability in xterm-r6 and similar where cursor + save/restore bracketed the sequence for resetting video attributes. + The cursor restore would undo that (from a NetBSD bug report by John + Hawkinson ). + + using parameter check added to tic, corrected 27 typos in + terminfo.src -TD + + modify tic to verify that its inputs are really files, in case + someone tries to read a directory (or /dev/zero). + + add a check for empty buffers returned by fgets() in comp_scan.c + next_char() function, in case tic is run on a non-text file (fixes + a core dump reported by Aaron Campbell ). + + add to railroad.c some code exercising tgoto(), providing an + alternate form of display if the terminal supports cursor addressing. + + split-out tgoto() again, this time into new file lib_tgoto.c, and + implement a conventional BSD-style tgoto() which is used if the + capability string does not contain terminfo-style padding or + parameters (requested by Andrey A Chernov). + + add check to tic which reports capabilities that do not reference + the expected number of parameters. + + add error checking to infocmp's -v and -m options to ensure that + the option value is indeed a number. + +20000917 + + add S0, E0 extensions to screen's terminfo entry, which is another + way to solve the misconfiguration issue -TD + + completed special case for tgoto from 20000916 + +20000916 + + update xterm terminfo entries to match XFree86 xterm patch #146 -TD + + add Matrix Orbital terminfo entries (from Eric Z Ayers + ). + + add special case to lib_tparm.c to allow 'screen' program to use a + termcap-style parameter "%." to tgoto() for switching character sets. + + use LN_S substitution in run_tic.in, to work on OS/2 EMX which has + no symbolic links. + + updated notes in README.emx regarding autoconf patches. + + replace a lookup table in lib_vidattr.c used to decode no_color_video + with a logic expression (suggested by Philippe Blain). + + add a/A toggle to ncurses.c 'b' test, which clears/sets alternate + character set attribute from the displayed text. + + correct inequality in parameter analysis of rewritten lib_tparm.c + which had the effect of ignoring p9 in set_attributes (sgr), breaking + alternate character set (reported by Piotr Majka ). + + correct ifdef'ing for GCC_PRINTF, GCC_SCANF which would not compile + with Sun WorkShop compilers since these tokens were empty (cf: + 20000902, reported by Albert Chin-A-Young). + +20000909 + + correct an uninitialized parameter to open_tempfile() in tic.c which + made "tic -I" give an ambiguous error message about tmpnam. + + add special case in lib_vidattr.c to reset underline and standout for + devices that have no sgr0 defined (patch by Don Lewis + ). Note that this will not work for bold + mode, since there is no exit-bold-mode capability. + + improved patch for Make_Enum_Type (patch by Juergen Pfeifer). + + modify tparm to disallow arithmetic on strings, analyze the varargs + list to read strings as strings and numbers as numbers. + + modify tparm's internal function spop() to treat a null pointer as + an empty string. + + modify tput program so it can be renamed or invoked via a link as + 'reset' or 'init', producing the same effect as 'tput reset' or 'tput + init'. + + add private entrypoint _nc_basename(), use to consolidate related + code in progs, as well as accommodating OS/2 EMX pathnames. + + remove NCURSES_CONST line from edit_cfg.sh to compensate for its + removal (except via AC_SUBST) from configure.in, making --enable-const + work again (reported by Juergen Pfeifer). + + regen'd configure to pick up "hpux*" change from 20000902. + +20000902 + + modify tset.c to check for transformed "reset" program name, if any. + + add a check for null pointer in Make_Enum_Type() (reported by Steven + W Orr ). + + change functions _nc_parse_entry() and postprocess_termcap() to avoid + using strtok(), because it is non-reentrant (reported by Andrey A + Chernov ). + + remove "hpux10.*" case from CF_SHARED_OPTS configure script macro. + This differed from the "hpux*" case by using reversed symbolic + links, which made the 5.1 version not match the configuration of + 5.0 shared libraries (reported by Albert Chin-A-Young). + + correct a dependency in Ada95/src/Makefile.in which prevented + building with configure --srcdir (patch by H Nanosecond + ). + + modify ifdef's in curses.h.in to avoid warning if GCC_PRINTF or + GCC_SCANF was not previously defined (reported by Pavel Roskin + ). + + add MKncurses_def.sh to generate fallback definitions for + ncurses_cfg.h, to quiet gcc -Wundef warnings, modified ifdef's in + code to consistently use "#if" rather than "#ifdef". + +20000826 + + add QNX qansi entries to terminfo -TD + + add os2 entry to misc/emx.src (). + + add configure option --with-database to allow specifying a different + terminfo source-file to install. On OS/2 EMX, this defaults to + misc/emx.src + + change misc/run_tic.sh to derive it from misc/run_tic.in, to simplify + setting .exe extension on OS/2 EMX. + + add .exe extension in Ada95/gen/Makefile.in, + Ada95/samples/Makefile.in, for OS/2 EMX (reported by + ). + + add configure check for filesystems (such as OS/2 EMX) which do not + distinguish between upper/lowercase filenames, use this to fix tags + rules in makefiles. + + initialize fds[] array to 0's in _nc_timed_wait(); apparently poll() + only sets the revents members of that array when there is activity + corresponding to the related file (report by Glenn Cooper + , using Purify on Solaris 5.6). + + change configure script to use AC_CANONICAL_SYSTEM rather than + AC_CANONICAL_HOST, which means that configure --target will set + a default program-prefix. + + add note on cross-compiling to INSTALL (which does not rely on the + AC_CANONICAL_* macros). + +20000819 + + add cases for EMX OS/2 to config.guess, config.sub + + new version of config.guess, config.sub from lynx 2.8.4dev.7 + + add definitions via transform.h to allow tic and tput to check for + the transformed aliases rather than the original infotocap, etc. + + simplify transform-expressions in progs/Makefile.in, make the + uninstall rule work for transformed program names. + + change symbol used by --install-prefix configure option from + INSTALL_PREFIX to DESTDIR (the latter has become common usage + although the name is misleading). + + modify programs to use curses_version() string to report the version + of ncurses with which they are compiled rather than the + NCURSES_VERSION string. The function returns the patch level in + addition to the major and minor version numbers. + +20000812 + + modify CF_MAN_PAGES configure macro to make transformed program names + a parameter to that macro rather than embedding them in the macro. + + newer config.guess, config.sub (reference version used in lynx + 2.8.4dev.7). + + add configure option --with-default-terminfo-dir=DIR to allow + specifying the default terminfo database directory (request by Albert + Chin-A-Young). + + minor updates for terminfo.src from FreeBSD termcap change-history. + + correct notes in README and INSTALL regarding documentation files + that were moved from misc directory to doc (report by Rich Kulawiec + ). + + change most remaining unquoted parameters of 'test' in configure + script to use quotes, for instance fixing a problem in the + --disable-database option (reported by Christian Mondrup + ). + + minor adjustments to work around some of the incompatibilities/bugs + in autoconf 2.29a alpha. + + add -I/usr/local/include when --with-ncurses option is used in + test/configure script. + + correct logic in adjust_cancels(), which did not check both + alternatives when reclassifying an extended name between boolean, + number and string, causing an infinite loop in tic. + +20000730 + + correct a missing backslash in curses.priv.h + +20000729 + + change handling of non_dest_scroll_region in tty_update.c to clear + text after it is shifted in rather than before shifting out. Also + correct row computation (reported by Ruediger Kuhlmann + ). + + add/use new trace function to display chtype values from winch() and + getbkgd(). + + add trace mask TRACE_ATTRS, alter several existing _tracef calls that + trace attribute changes under TRACE_CALLS to use this. + + modify MKlib_gen.sh so that functions returning chtype will call + returnChar(). + + add returnChar() trace, for functions returning chtype. + + change indent.pro to line up parenthesis. + +20000722 + + fix a heap problem with the c++ binding (report by + , patch by Juergen Pfeifer). + + minor adjustment to ClrToEOL() to handle an out-of-bounds parameter. + + modify the check for big-core to force a couple of memory accesses, + which may work as needed for older/less-capable machines (if not, + there's still the explicit configure option). + > fixes based on diff's for Amiga and BeOS found at + http://www.mathematik.uni-karlsruhe.de/~kuhlmann/cross/ncurses/ + + alter definition of NCURSES_CONST to make it non-empty. + + add amiga-vnc terminfo entry. + + redefine 'TEXT' in menu.h for AMIGA, since it is reported to have + an (unspecified) symbol conflict. + + replaced case-statement in _nc_tracebits() for CSIZE with a table to + simplify working around implementations that define random + combinations of the related macros to zero. + + modify configure test for tcgetattr() to allow for old + implementations, e.g., on BeOS, which only defined it as a macro. + > patches by Bruno Haible: + + when checking LC_ALL/LC_CTYPE/LANG environment variables for UTF-8 + locale, ignore those which are set to an empty value, as per SUSV2. + + encode 0xFFFD in UTF-8 with 3 bytes, not 2. + + modify _nc_utf8_outch() to avoid sign-extension when checking for + out-of-range value. + +20000715 + + correct manlinks.sed script to avoid using ERE "\+", which is not + understood by older versions of sed (patch by Albert Chin-A-Young). + + implement configure script options that transform installed program + names, e.g., --program-prefix, including the manpage names and cross + references (patch by Albert Chin-A-Young ). + + correct several mismatches between manpage filename and ".TH" + directives, renaming dft_fgbg.3x to default_colors.3x and + menu_attribs.3x to menu_attributes.3x (report by Todd C Miller). + + correct missing includes for in several places, including + the C++ binding. This is not noted by gcc unless we use the + -fno-builtin option (reported by Igor Schein ). + + modified progs/tset.c and tack/sysdep.c to build with sgttyb + interface if neither termio or termios is available. Tested this + with FreeBSD 2.1.5 (which does have termios - but the sgttyb does + work). + +20000708 5.1 release for upload to ftp.gnu.org + + document configure options in INSTALL. + + add man-page for ncurses trace functions. + + correct return value shown in curs_touch.3x for is_linetouched() and + is_wintouched(), in curs_initscr.3x for isendwin(), and in + curs_termattr.3x for has_ic() and has_il(). + + add prototypes for touchline() and touchwin(), adding them to the + list of generated functions. + + modify fifo_push() to put ERR into the fifo just like other values to + return from wgetch(). It was returning without doing that, making + end-of-file condition incorrectly return a 0 (reported by Todd C + Miller). + + uncomment CC_SHARED_OPTS for progs and tack (see 971115), since they + are needed for SCO OpenServer. + + move _nc_disable_period from free_ttype.c to comp_scan.c to appease + dynamic loaders on SCO and IRIX64. + + add "-a" option to test/ncurses.c to invoke assume_default_colors() + for testing. + + correct assignment in assume_default_colors() which tells ncurses + whether to use default colors, or the assumed ones (reported by Gary + Funck ). + + review/correct logic in mk-1st.awk for making symbolic links for + shared libraries, in particular for FreeBSD, etc. + + regenerate misc/*.def files for OS/2 EMX dll's. + + correct quoting of values for CC_SHARED_OPTS in aclocal.m4 for + cases openbsd2*, openbsd*, freebsd* and netbsd* (patch by Peter + Wemm) (err in 20000610). + + minor updates to release notes, as well as adding/updating URLs for + examples cited in announce.html + > several fixes from Philippe Blain : + + correct placement of ifdef for NCURSES_XNAMES in function + _nc_free_termtype(), fixes a memory leak. + + add a call to _nc_synchook() to the end of function whline() like + that in wvline() (difference was in 1.9.4). + + make ClearScreen() a little faster by moving two instances of + UpdateAttr() out of for-loops. + + simplify ClrBottom() by eliminating the tstLine data, using for-loops + (cf: 960428). + +20000701 pre-release + + change minor version to 1, i.e., ncurses 5.1 + + add experimental configure option --enable-colorfgbg to check for + $COLORTERM variable as set by rxvt/aterm/Eterm. + + add Eterm terminfo entry (Michael Jennings ). + + modify manlinks.sed to pick aliases from the SYNOPSIS section, and + several manpages so manlinks.sed can find aliases for creating + symbolic links. + + add explanation to run_tic.sh regarding extended terminal + capabilities. + + change message format for edit_cfg.sh, since some people interpret + it as a warning. + + correct unescaped '$' in sysv5uw7*|unix_sv* rule for CF_SHARED_OPTS + configure macro (report by Thanh Ma ). + + correct logic in lib_twait.c as used by lib_mouse.c for GPM mouse + support when poll() is used rather than select() (prompted by + discussion with David Allen ). + +20000624 pre-release + + modify TransformLine() to check for cells with different color pairs + that happen to render the same display colors. + + apply $NCURSES_NO_PADDING to cost-computation in mvcur(). + + improve cost computation in PutRange() by accounting for the use + of parm_right_cursor in mvcur(). + + correct cost computation in EmitRange(), which was not using the + normalized value for cursor_address. + + newer config.guess, config.sub (reference version used in TIN 1.5.6). + +20000617 + + update config.guess, config.sub (reference version used in PCRE 3.2). + + resync changes to gnathtml against version 1.22, regenerated html + files under doc/html/ada using this (1.22.1.1). + + regenerated html files under doc/html/man after correcting top and + bottom margin options for man2html in dist.mk + + minor fixes to test programs ncurses 'i' and testcurs program to make + the subwindow's background color cover the subwindow. + + modify configure script so AC_MSG_ERROR is temporarily defined to a + warning in AC_PROG_CXX to make it recover from a missing C++ compiler + without requiring user to add --without-cxx option (from comment by + Akim Demaille to autoconf mailing list). + + modify headers.sh to avoid creating temporary files in the build + directory when installing headers (reported by Sergei Pokrovsky + ) + +20000610 + + regenerated the html files under doc/html/ada/files and + doc/html/ada/funcs with a slightly-improved gnathtml. + + add kmous capability to linux terminfo entry to allow it to use + xterm-style events provided by gpm patch by Joerg Schoen. + + make the configure macro CF_SHARED_OPTS a little smarter by testing + if -fPIC is supported by gcc rather than -fpic. The former option + allows larger symbol tables. + + update config.guess and config.sub (patches by + Kevin Buettner for elf64_ia64 + Bernd Kuemmerlen and MacOS X). + + add warning for 'tic -cv' about use of '^?' in terminfo source, which + is an extension. + +20000527 + + modify echo() behavior of getch() to match Solaris curses for + carriage return and backspace (reported by Neil Zanella). + + change _nc_flush() to a function. + + modify delscreen() to check if the output stream has been closed, and + if so, free the buffer allocated for setbuf (this provides an + ncurses-specific way to avoid a memory leak when repeatedly calling + newterm reported by Chipp C ). + + correct typo in curs_getch.3x manpage regarding noecho (reported by + David Malone ). + + add a "make libs" rule. + + make the Ada95 interface build with configure --enable-widec. + + if the configure --enable-widec option is given, append 'w' to names + of the generated libraries (e.g., libncursesw.so) to avoid conflict + with existing ncurses libraries. + +20000520 + + modify view.c to make a rudimentary viewer of UTF-8 text if ncurses + is configured with the experimental wide-character support. + + add a simple UTF-8 output driver to the experimental wide-character + support. If any of the environment variables LC_ALL, LC_CTYPE or + LANG contain the string "UTF-8", this driver will be used to + translate the output to UTF-8. This works with XFree86 xterm. + + modify configure script to allow building shared libraries on BeOS + (from a patch by by Valeriy E Ushakov). + + modify lib_addch.c to allow repeated update to the lower-right + corner, rather than displaying only the first character written until + the cursor is moved. Recent versions of SVr4 curses can update the + lower-right corner, and behave this way (reported by Neil Zanella). + + add a limit-check in _nc_do_color(), to avoid using invalid color + pair value (from bug report by Brendan O'Dea ). + +20000513 + + the tack program knows how to use smcup and rmcup but the "show caps + that can be tested" feature did not reflect this knowledge. Correct + the display in the menu tack/test/edit/c (patch by Daniel Weaver). + + xterm-16color does allow bold+colors, removed ncv#32 from that + terminfo entry. + +20000506 + + correct assignment to SP->_has_sgr_39_49 in lib_dft_fgbg.c, which + broke check for screen's AX capability (reported by Valeriy E Ushakov + ). + + change man2html rule in dist.mk to workaround bug in some man-programs + that ignores locale when rendering hyphenation. + + change web- and ftp-site to dickey.his.com + +20000429 + + move _nc_curr_token from parse_entry.c to comp_scan.c, to work around + problem linking tack on MacOS X DP3. + + include in lib_napms.c to compile on MacOS X DP3 + (reported by Gerben Wierda ). + + modify lib_vidattr.c to check for ncv fixes when pair-0 is not + default colors. + + add -d option to ncurses.c, to turn on default-colors for testing. + + add a check to _nc_makenew() to ensure that newwin() and newpad() + calls do not silently fail by passing too-large limits. + + add symbol NCURSES_SIZE_T to use rather than explicit 'short' for + internal window and pad sizes. Note that since this is visible in + the WINDOW struct, it would be an ABI change to make this an 'int' + (prompted by a question by Bastian Trompetter + , who attempted to create a 96000-line pad). + +20000422 + + add mgterm terminfo entry from NetBSD, minor adjustments to sun-ss5, + aixterm entries -TD + + modify tack/ansi.c to make it more tolerant of bad ANSI replies. An + example of an illegal ANSI resonse can be found using Microsoft's + Telnet client. A correct display can be found using a VT-4xx + terminal or XFree86 xterm with: + XTerm*VT100*decTerminalID: 450 + (patch by Daniel Weaver). + + modify gdc.c to recognize 'q' for quit, 's' for single-step and ' ' + for resume. Add '-n' option to force gdc's standard input to + /dev/null, to both illustrate the use of newterm() for specifying + alternate inputs as well as for testing signal handling. + + minor fix for configure option --with-manpage-symlinks, for target + directories that contain a period ('.') (reported by Larry Virden). + +20000415 + + minor additions to beterm entry (feedback from Rico Tudor) -TD + + corrections/updates for some IBM terminfo entries -TD + + modify _nc_screen_wrap() so that when exiting curses mode with + non-default colors, the last line on the screen will be cleared to + the screen's default colors (request by Alexander Lukyanov). + + modify ncurses.c 'r' example to set nonl(), allowing control/M to be + read for demonstrating the REQ_NEW_LINE operation (prompted by a + question by Tony L Keith" ). + + modify ncurses.c 'r' example of field_info() to work on Solaris 2.7, + documented extension of ncurses which allows a zero pointer. + + modify fmt_complex() to avoid buffer overflow in case of excess + recursion, and to recognize "%e%?" as a synonym for else-if, which + means that it will not recur for that special case. + + add logic to support $TERMCAP variable in case the USE_GETCAP symbol + is defined (patch by Todd C Miller). + + modify one of the m4 files used to generate the Ada95 sources, + to avoid using the token "symbols" (patch by Juergen Pfeifer). + +20000408 + + add terminfo entries bsdos-pc-m, bsdos-pc-mono (Jeffrey C Honig) + + correct spelling error in terminfo entry name: bq300-rv was given as + bg300-rv in esr's version. + + modify redrawwin() macro so its parameter is fully parenthesized + (fixes Debian bug report #61088). + + correct formatting error in dump_entry() which set incorrect column + value when no newline trimming was needed at the end of an entry, + before appending "use=" clauses (cf: 960406). + +20000401 + + add configure option --with-manpage-symlinks + + change unctrl() to render C1 characters (128-159) as ~@, ~A, etc. + + change makefiles so trace() function is provided only if TRACE is + defined, e.g., in the debug library. Modify related calls to + _tracechar() to use unctrl() instead. + +20000325 + + add screen's AX capability (for ECMA SGR 39 and 49) to applicable + terminfo entries, use presence of this as a check for a small + improvement in setting default colors. + + improve logic in _nc_do_color() implementing assume_default_colors() + by passing in previous color pair info to eliminate redundant call to + set_original_colors(). (Part of this is from a patch by Alexander + Lukyanov). + + modify warning in _nc_trans_string() about a possibly too-long string + to do this once only rather than for each character past the + threshold (600). Change interface of _nc_trans_string() to allow + check for buffer overflow. + + correct use of memset in _nc_read_entry_source() to initialize ENTRY + struct each time before reading new data into it, rather than once + per loop (cf: 990301). This affects multi-entry in-core operations + such as "infocmp -Fa". + +20000319 + + remove a spurious pointer increment in _nc_infotocap() changes from + 20000311. Add check for '.' in format of number, since that also + is not permitted in termcap. + + correct typo in rxvt-basic terminfo from temporary change made while + integrating 20000318. + +20000318 + + revert part of the vt220 change (request by Todd C Miller). + + add ansi-* terminfo entries from Eric's version. + + add -a option to tic and infocmp, which retains commented-out + capabilities during source translation/comparison, e.g., captoinfo + and infotocap. + + modify cardfile.c to display an empty card if no input data file is + found, fixes a core dump in that case (reported by Bruno Haible). + + correct bracketing in CF_MATH_LIB configure macro, which gave wrong + result for OS/2 EMX. + + supply required parameter for _nc_resolve_uses() call in + read_termcap.c, overlooked in 20000311 (reported by Todd C Miller). + > patches by Bruno Haible : + + fix a compiler warning in fty_enum.c + + correct LIB_PREFIX expression for DEPS_CURSES in progs, tack + makefiles, which resulted in redundant linking (cf: 20000122). + +20000311 + + make ifdef's for BROKEN_LINKER consistent (patch by Todd C Miller). + + improved tack/README (patch by Daniel Weaver). + + modify tput.c to ensure that unspecified parameters are passed to + tparm() as 0's. + + add a few checks in infocmp to guard against buffer overflow when + displaying string capabilities. + + add check for zero-uses in infocmp's file_comparison() function + before calling _nc_align_termtype(). Otherwise one parameter is + indexed past the end of the uses-array. + + add an option -q to infocmp to specify the less verbose output, + keeping the existing format as the default, though not retaining the + previous behavior that made the -F option compare each entry to + itself. + + adapted patch by Eric Raymond to make infocmp -F less verbose + (the submitted patch was unusable because it did not compile + properly): + + modify write_entry.c to ensure that absent or cancelled booleans + are written as FALSE, for consistency with infocmp which now + assumes this. Note that for the small-core configuration, tic + may not produce the same result as before. + + change some private library interfaces used by infocmp, e.g., + _nc_resolve_uses(). + + add a check in _nc_infotocap() to ensure that cm-style capabilities + accept only %d codes when converting the format from terminfo to + termcap. + + modify ENTRY struct to separate the data in 'parent' into the name + and link values (the original idea to merge both into 'parent' was + not good). + + discard repair_acsc(tterm); + > patch by Juergen Pfeifer: + + drop support for gnat 3.10 + + move generated documentation and html files under ./doc directory, + adding makefile rules for this to dist.mk + +20000304 + + correct conflicting use of tparm() in 20000226 change to tic, which + made it check only one entry at a time. + + fix errors in ncurses-intro.html and hackguide.html shown by Dave + Raggett's tidy. + + make the example in ncurses-intro.html do something plausible, and + corrected misleading comment (reported by Neil Zanella). + + modify pnoutrefresh() to set newscr->_leaveok as wnoutrefresh() does, + to fix a case where the cursor position was not updated as in + Solaris (patch by David Mosberger ). + + add a limit-check for wresize() to ensure that a subwindow does not + address out of bounds. + + correct offsets used for subwindows in wresize() (patch by Michael + Andres ). + + regenerate html'ized manual pages with man2html 3.0.1 (patch by + Juergen Pfeifer). This generated a file with a space in its name, + which I removed. + + fix a few spelling errors in tack. + + modify tack/Makefile.in to match linker options of progs/Makefile.in; + otherwise it does not build properly for older HPUX shared library + configurations. + + add several terminfo entries from esr's "11.0". + +20000226 + + make 'tput flash' work properly for xterm by flushing output in + delay_output() when using napms(), and modifying xterm's terminfo to + specify no padding character. Otherwise, xterm's reported baud rate + can mislead ncurses into producing too few padding characters + (Debian #58530). + + add a check to tic for consistency between sgr and the separate + capabilities such as smso, use this to check/correct several + terminfo entries (Debian #58530). + + add a check to tic if cvvis is the same as cnorm, adjusted several + terminfo entries to remove the conflict (Debian #58530). + + correct prototype shown in attr_set()/wattr_set() manpages (fixes + Debian #53962). + + minor clarification for curs_set() and leaveok() manpages. + + use mkstemp() for creating temporary file for tic's processing of + $TERMCAP contents (fixes Debian #56465). + + correct two errors from integrating Alexander's changes: did not + handle the non-bce case properly in can_erase_with() (noted by + Alexander), and left fg/bg uninitialized in the pair-zero case of + _nc_do_color() (reported by Dr Werner Fink and + Ismael Cordeiro ). + +20000219 + + store default-color code consistently as C_MASK, even if given as + -1 for convenience (adapted from patches by Alexander Lukyanov). + > patches by Alexander Lukyanov: + + change can_clear_with() macro to accommodate logic for + assume_default_colors(), making most of the FILL_BCE logic + unnecessary. Made can_clear_with() an inline function to make it + simpler to read. + +20000212 + + corrected form of recent copyright dates. + + minor corrections to xterm-xf86-v333 terminfo entry -TD + > patches by Alexander Lukyanov: + + reworded dft_fgbg.3x to avoid assuming that the terminal's default + colors are white on black. + + fix initialization of tstLine so that it is filled with current blank + character in any case. Previously it was possible to have it filled + with old blank. The wrong over-optimization was introduced in 991002 + patch. (it is not very critical as the only bad effect is not using + clr_eos for clearing if blank has changed). + +20000205 + + minor corrections/updates to several terminfo entries: rxvt-basic, + vt520, vt525, ibm5151, xterm-xf86-v40 -TD + + modify ifdef's for poll() to allow it to use , thereby + allowing poll() to be used on Linux. + + add CF_FUNC_POLL macro to check if poll() is able to select from + standard input. If not we will not use it, preferring select() + (adapted from patch by Michael Pakovic ). + + update CF_SHARED_OPTS macro for SCO Unixware 7.1 to allow building + shared libraries (reported/tested by Thanh ). + + override $LANGUAGE in build to avoid incorrect ordering of keynames. + + correct CF_MATH_LIB parameter, must be sin(x), not sqrt(x). + +20000122 + + resync CF_CHECK_ERRNO and CF_LIB_PREFIX macros from tin and xterm. + + modify CF_MATH_LIB configure macro to parameterize the test function + used, for reuse in dialog and similar packages. + + correct tests for file-descriptors in OS/2 EMX mouse support. A + negative value could be used by FD_SET, causing the select() call + to wait indefinitely. + +20000115 + + additional fixes for non-bce terminals (handling of delete_character) + to work when assume_default_colors() is not specified. + + modify warning message from _nc_parse_entry() regarding extended + capability names to print only if tic/infocmp/toe have the -v flag + set, and not at all in ordinary user applications. Otherwise, this + warning would be shown for screen's extended capabilities in programs + that use the termcap interface (reported by Todd C Miller). + + modify use of _nc_tracing from programs such as tic so their debug + level is not in the same range as values set by trace() function. + + small panel header cleanup (patch by Juergen Pfeifer). + + add 'railroad' demo for termcap interface. + + modify 'tic' to write its usage message to stderr (patch by Todd C + Miller). + +20000108 + + add prototype for erase() to curses.h.in, needed to make test + programs build with c++/g++. + + add .c.i and .c.h suffix rules to generated makefiles, for debugging. + + correct install rule for tack.1; it assumed that file was in the + current directory (reported by Mike Castle ). + + modify terminfo/termcap translation to suppress acsc before trying + sgr if the entry would be too large (patch by Todd C Miller). + + document a special case of incompatiblity between ncurses 4.2 and + 5.0, add a section for this in INSTALL. + + add TRACE_DATABASE flag for trace(). + +20000101 + + update mach, add mach-color terminfo entries based on Debian diffs + for ncurses 5.0 -TD + + add entries for xterm-hp, xterm-vt220, xterm-vt52 and xterm-noapp + terminfo entries -TD + + change OTrs capabilities to rs2 in terminfo.src -TD + + add obsolete and extended capabilities to 'screen' terminfo -TD + + corrected conversion from terminfo rs2 to termcap rs (cf: 980704) + + make conversion to termcap ug (underline glitch) more consistently + applied. + + fix out-of-scope use of 'personal[]' buffer in 'toe' (this error + was in the original pre-1.9.7 version, when $HOME/.terminfo was + introduced). + + modify 'toe' to ignore terminfo directories to which it has no + permissions. + + modify read_termtype(), fixing 'toe', which could dump core when it + found an incomplete entry such as "dumb" because it did not + initialize its buffer for _nc_read_file_entry(). + + use -fPIC rather than -fpic for shared libraries on Linux, not + needed for i386 but some ports (from Debian diffs for 5.0). + + use explicit VALID_NUMERIC() checks in a few places that had been + overlooked, and add a check to ensure that init_tabs is nonzero, + to avoid divide-by-zero (reported by Todd C Miller). + + minor fix for CF_ANSI_CC_CHECK configure macro, for HPUX 10.x (from + tin). + +19991218 + + reorder tests during mouse initialization to allow for gpm to run in + xterm, or for xterm to be used under OS/2 EMX. Also drop test for + $DISPLAY in favor of kmous=\E[M or $TERM containing "xterm" (report + by Christian Weisgerber ). + + modify raw() and noraw() to clear/restore IEXTEN flag which affects + stty lnext on systems such as FreeBSD (report by Bruce Evans + , via Jason Evans ). + + fix a potential (but unlikely) buffer overflow in failed() function + of tset.c (reported by Todd C Miller). + + add manual-page for ncurses extensions, documented curses_version(), + use_extended_names(). + +19991211 + + treat as untranslatable to termcap those terminfo strings which + contain non-decimal formatting, e.g., hexadecimal or octal. + + correct commented-out capabilities that cannot be translated to + termcap, which did not check if a colon must be escaped. + + correct termcap translation for "%>" and "%+", which did not check + if a colon must be escaped, for instance. + + use save_string/save_char for _nc_captoinfo() to eliminate fixed + buffer (originally for _nc_infotocap() in 960301 -TD). + + correct expression used for terminfo equivalent of termcap %B, + adjust regent100 entry which uses this. + + some cleanup and commenting of ad hoc cases in _nc_infotocap(). + + eliminate a fixed-buffer in tic, used for translating comments. + + add manpage for infotocap + +19991204 + + add kvt and gnome terminfo entries -TD + + correct translation of "%%" by infotocap, which was emitted as "%". + + add "obsolete" termcap strings to terminfo.src + + modify infocmp to default to showing obsolete capabilities rather + than terminfo only. + + modify write_entry.c so that if extended names (i.e., configure + --enable-tcap-names) are active, then tic will also write "obsolete" + capabilities that are present in the terminfo source. + + modify tic so that when running as captoinfo or infotocap, it + initializes the output format as in -C and -I options, respectively. + + improve infocmp and tic -f option by splitting long strings that do + not have if-then-else construct, but do have parameters, e.g., the + initc for xterm-88color. + + refine MKtermsort.sh slightly by using bool for the *_from_termcap + arrays. + +19991127 + + additional fixes for non-bce terminals (handling of clear_screen, + clr_eol, clr_eos, scrolling) to work when assume_default_colors() is + not specified. + + several small changes to xterm terminfo entries -TD. + + move logic for _nc_windows in lib_freeall.c inside check for nonnull + SP, since it is part of that struct. + + remove obsolete shlib-versions, which was unintentionally re-added + in 970927. + + modify infocmp -e, -E options to ensure that generated fallback.c + type for Booleans agrees with term.h (reported by Eric Norum + ). + + correct configure script's use of $LIB_PREFIX, which did not work + for installing the c++ directory if $libdir did not end with "/lib" + (reported by Huy Le ). + + modify infocmp so -L and -f options work together. + + modify the initialization of SP->_color_table[] in start_color() so + that color_content() will return usable values for COLORS greater + than 8. + + modify ncurses 'd' test in case COLORS is greater than 16, e.g., for + xterm-88color, to limit the displayed/computed colors to 16. + > patch by Juergen Pfeifer: + + simplify coding of the panel library according to suggestions by + Philippe Blain. + + improve macro coding for a few macros in curses.priv.h + +19991113 + + modify treatment of color pair 0 so that if ncurses is configured + to support default colors, and they are not active, then ncurses + will set that explicitly, not relying on orig_colors or orig_pair. + + add new extension, assume_default_colors() to provide better control + over the use of default colors. + + modify test programs to use more-specific ifdef's for existence of + wresize(), resizeterm() and use_default_colors(). + + modify configure script to add specific ifdef's for some functions + that are included when --enable-ext-funcs is in effect, so their + existence can be ifdef'd in the test programs. + + reorder some configure options, moving those extensions that have + evolved from experimental status into a new section. + + change configure --enable-tcap-names to enable this by default. + +19991106 + + install tack's manpage (reported by Robert Weiner + ) + + correct worm.c's handling of KEY_RESIZE (patch by Frank Heckenbach). + + modify curses.h.in, undef'ing some symbols to avoid conflict with C++ + STL (reported by Matt Gerassimoff ) + +19991030 + + modify linux terminfo entry to indicate that dim does not mix with + color (reported by Klaus Weide ). + + correct several typos in terminfo entries related to missing '[' + in CSI's -TD + + fix several compiler warnings in c++ binding (reported by Tim + Mooney for alphaev56-dec-osf4.0f + + rename parameter of _nc_free_entries() to accommodate lint. + + correct lint rule for tack, used incorrect list of source files. + + add case to config.guess, config.sub for Rhapsody. + + improve configure tests for libg++ and libstdc++ by omitting the + math library (which is missing on Rhapsody), and improved test for + the math library itself (adapted from path by Nelson H. F. Beebe). + + explicitly initialize to zero several data items which were + implicitly initialized, e.g., cur_term. If not explicitly + initialized, their storage type is C (common), and causes problems + linking on Rhapsody 5.5 using gcc 2.7.2.1 (reported by Nelson H. F. + Beebe). + + modify Ada95 binding to not include the linker option for Ada + bindings in the Ada headers, but in the Makefiles instead (patch by + Juergen Pfeifer). + +19991023 5.0 release for upload to ftp.gnu.org + + effective with release of 5.0, change NCURSES_VERSION_PATCH to + 4-digit year. + + add function curses_version(), to return ncurses library version + (request by Bob van der Poel). + + remove rmam, smam from cygwin terminfo entry. + + modify FreeBSD cons25 terminfo entry to add cnorm and cvvis, as well + as update ncv to indicate that 'dim' conflicts with colors. + + modify configure script to use symbolic links for FreeBSD shared + libraries by default. + + correct ranf() function in rain and worm programs to ensure it does + not return 1.0 + + hide the cursor in hanoi.c if it is running automatically. + + amend lrtest.c to account for optimizations that exploit margin + wrapping. + + add a simple terminfo demo, dots.c + + modify SIGINT/SIGQUIT handler to set a flag used in _nc_outch() to + tell it to use write() rather than putc(), since the latter is not + safe in a signal handler according to POSIX. + + add/use internal macros _nc_flush() and NC_OUTPUT to hide details + of output-file pointer in ncurses library. + + uncomment CC_SHARED_OPTS (see 971115), since they are needed for SCO + OpenServer. + + correct CC_SHARED_OPTS for building shared libraries for SCO + OpenServer. + + remove usleep() from alternatives in napms(), since it may interact + with alarm(), causing a process to be interrupted by SIGALRM (with + advice from Bela Lubkin). + + modify terminal_interface-curses-forms.ads.m4 to build/work with + GNAT 3.10 (patch by Juergen Pfeifer). + + remove part of CF_GPP_LIBRARY configure-script macro, which did not + work with gcc 2.7.2.3 + + minor fix to test/tclock.c to avoid beeping more than once per second + + add 's' and ' ' decoding to test/rain.c + +991016 pre-release + + corrected BeOS code for lib_twait.c, making nodelay() function work. + +991009 pre-release + + correct ncurses' value for cursor-column in PutCharLR(), which was + off-by-one in one case (patch by Ilya Zakharevich). + + fix some minor errors in position_check() debugging code, found while + using this to validate the PutCharLR() patch. + + modify firework, lrtest, worm examples to be resizable, and to + recognize 'q' for quit, 's' for single-step and ' ' for resume. + + restore reverted change to terminal_interface-curses-forms.ads.m4, + add a note on building with gnat 3.10p to Ada95/TODO. + + add a copy of the standalone configure script for the test-directory + to simplify testing on SCO and Solaris. + +991002 pre-release + + minor fixes for _nc_msec_cost(), color_content(), pair_content(), + _nc_freewin(), ClrBottom() and onscreen_mvcur() (analysis by Philippe + Blain, comments by Alexander Lukyanov). + + simplify definition of PANEL and eliminate internal functions + _nc_calculate_obscure(), _nc_free_obscure() and _nc_override(), + (patch by Juergen Pfeifer, based on analysis by Philippe Blain + )). + + change renaming of dft_fgbg.3x to use_default_colors.3ncurses in + man_db.renames, since Debian is not concerned with 14-character + filename limitation (from Debian bug report by Josip Rodin + ). + + corrected scoansi terminfo entry by testing with scoterm and console. + + revert change from 990614 to terminal_interface-curses-forms.ads.m4, + since this does not work for gnat 3.10p + + modify tclock example to be resizable (if ncurses' sigwinch handler + is used), and in color. + + use $(CC) rather than 'gcc' in MK_SHARED_LIB symbols, used for Linux + shared library rules. + +990925 pre-release + + add newer NetBSD console terminfo entries + + add amiga-8bit terminfo entry (from Henning 'Faroul' Peters + ) + + remove -lcurses -ltermcap from configure script's check for the gpm + library, since they are not really necessary (a properly configured + gpm library has no dependency on any curses library), and if the + curses library is not installed, this would cause the test to fail. + + modify tic's -C option so that terminfo "use=" clauses are translated + to "tc=" clauses even when running it as captoinfo. + + modify CF_STDCPP_LIBRARY configure macro to perform its check only + for GNU C++, since that library conflicts with SGI's libC on IRIX-6.2 + + modify CF_SHARED_OPTS configure macro to support build on NetBSD with + ELF libraries (patch by Bernd Ernesti ). + + correct a problem in libpanel, where the _nc_top_panel variable was + not set properly when bottom_panel() is called to hide a panel which + is the only one on the stack (report/analysis by Michael Andres + , patch by Juergen Pfeifer). + +990918 pre-release + + add acsc string to HP 70092 terminfo entry (patch by Joerg Wunsch + ). + + add top-level uninstall.data and uninstall.man makefile rules. + + correct logic of CF_LINK_FUNCS configure script, from BeOS changes so + that hard-links work on Unix again. + + change default value of cf_cv_builtin_bool to 1 as suggested by + Jeremy Buhler, making it less likely that a conflicting declaration + of bool will be seen when compiling with C++. + +990911 pre-release + + improved configure checks for builtin.h + + minor changes to C++ binding (remove static initializations, and make + configure-test for parameter initializations) for features not + allowed by vendor's C++ compilers (reported by Martin Mokrejs, this + applies to SGI, though I found SCO has the same characteristics). + + corrected quoting of ETIP_xxx definitions which support old versions + of g++, e.g., those using -lg++ + + remove 'L' code from safe_sprintf.c, since 'long double' is not + widely portable. safe_sprintf.c is experimental, however, and + exists mainly as a fallback for systems without snprintf (reported + by Martin Mokrejs , for IRIX 6.2) + + modify definition of _nc_tinfo_fkeys in broken-linker configuration + so that it is not unnecessarily made extern (Jeffrey C Honig). + +990904 pre-release + + move definition for builtin.h in configure tests to specific check + for libg++, since qt uses the same filename incompatibly. + + correct logic of lib_termcap.c tgetstr function, which did not copy + the result to the buffer parameter. Testing shows Solaris does + update this, though of course tgetent's buffer is untouched (from + mpc.lists.freebsd.current newsgroup item by Peter Edwards + ). + + corrected beterm terminfo entry, which lists some capabilities which + are not actually provided by the BeOS Terminal. + + add special logic to replace select() calls on BeOS, whose select() + function works only for sockets. + + correct missing escape in mkterm.h.awk.in, which caused part + of the copyright noticed to be omitted (reported by Peter + Wemm ). + > several small changes to make the c++ binding and demo work on OS/2 + EMX (related to a clean reinstall of EMX): + + correct library-prefix for c++ binding; none is needed. + + add $x suffix to make_hash and make_keys so 'make distclean' works. + + correct missing $x suffix for tack, c++ demo executables. + + split CF_CXX_LIBRARY into CF_GPP_LIBRARY (for -lg++) and + CF_STDCPP_LIBRARY (for -lstdc++) + +990828 pre-release + + add cygwin terminfo entry -TD + + modify CF_PROG_EXT configure macro to set .exe extension for cygwin. + + add configure option --without-cxx-binding, modifying the existing + --without-cxx option to check only for the C++ compiler + characteristics. Whether or not the C++ binding is needed, the + configure script checks for the size/type of bool, to make ncurses + match. Otherwise C++ applications cannot use ncurses. + +990821 pre-release + + updated configure macros CF_MAKEFLAGS, CF_CHECK_ERRNO + + minor corrections to beterm terminfo entry. + + modify lib_setup.c to reject values of $TERM which have a '/' in them. + + add ifdef's to guard against CS5, CS6, CS7, CS8 being zero, as more + than one is on BeOS. That would break a switch statement. + + add configure macro CF_LINK_FUNCS to detect and work around BeOS's + nonfunctional link(). + + improved configure macros CF_BOOL_DECL and CF_BOOL_SIZE to detect + BeOS's bool, which is declared as an unsigned char. + +990814 pre-release + + add ms-vt100 terminfo entry -TD + + minor fixes for misc/emx.src, based on testing with tack. + + minor fix for test/ncurses.c, test 'a', in case ncv is not set. + +990731 pre-release + + minor correction for 'screen' terminfo entry. + + clarify description of errret values for setupterm in manpage. + + modify tput to allow it to emit capabilities for hardcopy terminals + (patch by Goran Uddeborg ). + + modify the 'o' (panel) test in ncurses.c to show the panels in color + or at least in bold, to test Juergen's change to wrefresh(). + > patches by Juergen Pfeifer: + + Fixes a problem using wbkgdset() with panels. It has actually + nothing to with panels but is a problem in the implementation of + wrefresh(). Whenever a window changes its background attribute to + something different than newscr's background attribute, the whole + window is touched to force a copy to newscr. This is an unwanted + side-effect of wrefresh() and it is actually not necessary. A changed + background attribute affects only further outputs of background it + doesn't mean anything to the current content of the window. So there + is no need to force a copy. (reported by Frank Heckenbach + ). + + an upward compatible enhancement of the NCursesPad class in the C++ + binding. It allows one to add a "viewport" window to a pad and then + to use panning to view the pad through the viewport window. + +990724 pre-release + + suppress a call to def_prog_mode() in the SIGTSTP handler if the + signal was received while not in curses mode, e.g., endwin() was + called in preparation for spawning a shell command (reported by Frank + Heckenbach ) + + corrected/enhanced xterm-r5, xterm+sl, xterm+sl-twm terminfo entries. + + change test for xterm mouse capability: it now checks only if the + user's $DISPLAY variable is set in conjunction with the kmous + capability being present in the terminfo. Before, it checked if any + of "xterm", "rxvt" or "kterm" were substrings of the terminal name. + However, some emulators which are incompatible with xterm in other + ways do support the xterm mouse capability. + + reviewed and made minor changes in ncurses to quiet g++ warnings + about shadowed or uninitialized variables. g++ incorrectly warns + about uninitialized variables because it does not take into account + short-circuit expression evaluation. + + change ncurses 'b' test to start in color pair 0 and to show in the + right margin those attributes which are suppressed by no_color_video, + i.e., "(NCV)". + + modify ifdef's in curses.h so that __attribute__ is not redefined + when compiling with g++, but instead disabled the macros derived for + __attribute__ since g++ does not consistently recognize the same + keywords as gcc (reported by Stephan K Zitz ). + + update dependencies for term.h in ncurses/modules (reported by + Ilya Zakharevich). + +990710 pre-release + + modify the form demo in ncurses.c to illustrate how to manipulate the + field appearance, e.g, for highlighting or translating the field + contents. + + correct logic in write_entry from split-out of home_terminfo in + 980919, which prevented update of $HOME/.terminfo (reported by Philip + Spencer ). + +990703 pre-release + + modify linux terminfo description to make use of kernel 2.2.x mods + that support cursor style, e.g., to implement cvvis (patch by Frank + Heckenbach ) + + add special-case in setupterm to retain previously-saved terminal + settings in cur_term, which happens when curses and termcap calls are + mixed (from report by Bjorn Helgaas ). + + suppress initialization of key-tries in _nc_keypad() if we are only + disabling keypad mode, e.g., in endwin() called when keypad() was not. + + modify the Ada95 makefile to ensure that always the Ada files from + the development tree are used for building and not the eventually + installed ones (patch by Juergen Pfeifer). + +990626 pre-release + + use TTY definition in tack/sysdep.c rather than struct termios + (reported by Philippe De Muyter). + + add a fallback for strstr, used in lib_mvcur.c and tack/edit.c, + not present on sysV68 (reported by Philippe De Muyter). + + correct definition in comp_hash.c to build with configure + --with-rcs-ids option. + +990619 pre-release + + modified ifdef's for sigaction and sigvec to ensure we do not try to + handle SIGTSTP if neither is available (from report by Philippe De + Muyter). + > patch by Philippe De Muyter: + + in tic.c, use `unlink' if `remove' is not available. + + use only `unsigned' as fallback value for `speed_t'. Some files used + `short' instead. + +990616 pre-release + + fix some compiler warnings in tack. + + add a check for predefined bool type in CC, based on report that + BeOS predefines a bool type. + + correct logic for infocmp -e option (i.e., the configure + --with-fallbacks option), which I'd not updated when implementing + extended names (cf: 990301). The new implementation adds a -E + option to infocmp. + > patch by Juergen Pfeifer: + + introduce the private type Curses_Bool in the Ada95 binding + implementation. This is to clearly represent the use of "bool" also + in the binding. It should have no effect on the generated code. + + improve the man page for field_buffer() to tell the people, that the + whole buffer including leading/trailing spaces is returned. This is + a common source of confusion, so it's better to document it clearly. + +990614 pre-release + > patch by Juergen Pfeifer: + + use pragma PreElaborate in several places. + + change a few System.Address uses to more specific types. + + change interface version-number to 1.0 + + regenerate Ada95 HTML files. + +990612 pre-release + + modify lib_endwin.c to avoid calling reset_shell_mode(), return ERR + if it appears that curses was never initialized, e.g., by initscr(). + For instance, this guards against setting the terminal modes to + strange values if endwin() is called after setupterm(). In the same + context, Solaris curses will dump core. + + modify logic that avoids a conflict in lib_vidattr.c between sgr0 and + equivalent values in rmso or rmul by ensuring we do not modify the + data which would be returned by the terminfo or termcap interfaces + (reported by Brad Pepers , cf: 960706). + + add a null-pointer check for SP in lib_vidattr.c to logic that checks + for magic cookies. + + improve fallback declaration of 'bool' when the --without-cxx option + is given, by using a 'char' on i386 and related hosts (from discussion + with Alexander Lukyanov). + +990605 pre-release + + include time.h in lib_napms.c if nanosleep is used (patch by + R Lindsay Todd ). + + add an "#undef bool" to curses.h, in case someone tries to define it, + e.g., perl. + + add check to tparm to guard against divide by zero (reported by Aaron + Campbell ). + +990516 pre-release + + minor fix to build tack on CLIX (mismatched const). + > patch by Juergen Pfeifer: + + change Juergen's old email address with new one in the files where it + is referenced. The Ada95 HTML pages are regenerated. + + update MANIFEST to list the tack files. + +990509 pre-release + + minor fixes to make 'tack' build/link on NeXT (reported by Francisco + A. Tomei Torres). + +990417 pre-release + + add 'tack' program (which is GPL'd), updating it to work with the + modified TERMTYPE struct and making a fix to support setaf/setab + capabilities. Note that the tack program is not part of the + ncurses libraries, but an application which can be distributed with + ncurses. The configure script will ignore the directory if it is + omitted, however. + + modify gpm mouse support so that buttons 2 and 3 are used for + select/paste only when shift key is pressed, making them available + for use by an application (patch by Klaus Weide). + + add complete list of function keys to scoansi terminfo entry - TD + +990410 pre-release + + add a simple test program cardfile.c to illustrate how to read form + fields, and showing forms within panels. + + change shared-library versioning for the Hurd to be like Linux rather + than *BSD (patch by Mark Kettenis ). + + add linux-lat terminfo entry. + + back-out _nc_access check in read_termcap.c (both incorrect and + unnecessary, except to guard against a small window where the file's + ownership may change). + +990403 pre-release + + remove conflicting _nc_free_termtype() function from test module + lib_freeall.c + + use _nc_access check in read_termcap.c for termpaths[] array (noted + by Jeremy Buhler, indicating that Alan Cox made a similar patch). + > patch by Juergen Pfeifer: + + modify menu creation to not inherit status flag from the default menu + which says that the associated marker string has been allocated and + should be freed (bug reported by Marek Paliwoda" ) + +990327 pre-release (alpha.gnu.org:/gnu/ncurses-5.0-beta1.tar.gz) + + minor fixes to xterm-xfree86 terminfo entry - TD. + + split up an expression in configure script check for ldconfig to + workaround limitation of BSD/OS sh (reported by Jeff Haas + ). + + correct a typo in man/form_hook.3x (Todd C Miller). + +990318 pre-release + + parenthesize and undef 'index' symbol in c++ binding and demo, to + accommodate its definition on NeXT (reported by Francisco A. Tomei + Torres). + + add sigismember() to base/sigaction.c compatibility to link on NeXT + (reported by Francisco A. Tomei Torres). + + further refinements to inequality in hashmap.c to cover a case with + ^U in nvi (patch by Alexander Lukyanov). + +990316 pre-release + + add fallback definition for getcwd, to link on NeXT. + + add a copy of cur_term to tic.c to make it link properly on NeXT + (reported by Francisco A. Tomei Torres). + + change inequality in hashmap.c which checks the distance traveled by + a chunk so that ^D command in nvi (scrolls 1/2 screen) will use + scrolling logic (patch by Alexander Lukyanov, reported by Jeffrey + C Honig). + +990314 pre-release + + modify lib_color.c to handle a special case where the curscr + attributes have been made obsolete (patch by Alexander Lukyanov). + + update BSD/OS console terminfo entries to use klone+sgr and + klone+color (patch by Jeffrey C Honig). + + update glibc addon configure script for extended capabilities. + + correct a couple of warnings in the --enable-const configuration. + + make comp_hash build properly with _nc_strdup(), on NeXT (reported by + Francisco A. Tomei Torres ). + +990313 pre-release + + correct typos in linux-c initc string - TD + + add 'crt' terminfo entry, update xterm-xfree86 entry - TD + + remove a spurious argument to tparm() in lib_sklrefr.c (patch by + Alexander Lukyanov). + +990307 pre-release + + back-out change to wgetch because it causes a problem with ^Z + handling in lynx (reported by Kim DeVaughn). + +990306 pre-release + + add -G option to tic and infocmp, to reverse the -g option. + + recode functions in name_match.c to avoid use of strncpy, which + caused a 4-fold slowdown in tic (cf: 980530). + + correct a few warnings about sign-extension in recent changes. + > patch by Juergen Pfeifer: + + fixes suggested by Jeff Bradbury : + + improved parameter checking in new_fieldtype(). + + fixed a typo in wgetch() timeout handling. + + allow slk_init() to be called per newterm call. The internal SLK + state is stored in the SCREEN struct after every newterm() and then + reset for the next newterm. + + fix the problem that a slk_refresh() refreshes stdscr if the + terminal has true SLKs. + + update HTML documentation for Ada binding. + +990301 pre-release + + remove 'bool' casts from definitions of TRUE/FALSE so that statements + such as "#if TRUE" work. This was originally done to allow for a C++ + compiler which would warn of implicit conversions between enum and + int, but is not needed for g++ (reported by Kim DeVaughn). + + add use_extended_names() function to allow applications to suppress + read of the extended capabilities. + + add configure option --enable-tcap-names to support logic which + allows ncurses' tic to define new (i.e., extended) terminal + capabilities. This is activated by the tic -x switch. The infocmp + program automatically shows or compares extended capabilities. + Note: This changes the Strings and similar arrays in the TERMTYPE + struct so that applications which manipulate it must be recompiled. + + use macros typeMalloc, typeCalloc and typeRealloc consistently + throughout ncurses library. + + add _nc_strdup() to doalloc.c. + + modify define_key() to allow multiple strings to be bound to the + same keycode. + + correct logic error in _nc_remove_string, from 990220. + > patch by Juergen Pfeifer, for Ada95 binding: + + regenerate some of the html documentation + + minor cleanup in terminal_interface-curses.adb + +990220 pre-release + + resolve ambiguity of kend/kll/kslt and khome/kfnd/kich1 strings in + xterm and ncsa terminfo entries by removing the unneeded ones. Note + that some entries will return kend & khome versus kslt and kfnd, for + PC-style keyboards versus strict vt220 compatiblity - TD + + add function keybound(), which returns the definition associated with + a given keycode. + + modify define_key() to undefine the given string when no keycode is + given. + + modify keyok() so it works properly if there is more than one string + defined for a keycode. + + add check to tic to warn about terminfo descriptions that contain + more than one key assigned to the same string. This is shown only if + the verbose (-v) option is given. Moved related logic (tic -v) from + comp_parse.c into the tic program. + + add/use _nc_trace_tries() to show the function keys that will be + recognized. + + rename init_acs to _nc_init_acs (request by Alexander Lukyanov). + > patch by Juergen Pfeifer, for Ada95 binding: + + remove all the *_adabind.c from ncurses, menu and form projects. + Those little helper routines have all been implemented in Ada and are + no longer required. + + The option handling routines in menu and form have been made more + save. They now make sure that the unused bits in options are always + zero. + + modify configuration scripts to + + use gnatmake as default compiler name. This is a safer choice than + gcc, because some GNAT implementations use other names for the + compilerdriver to avoid conflicts. + + use new default installation locations for the Ada files according + to the proposed GNU Ada filesystem standard (for Linux). + + simplify the Makefiles for the Ada binding + + rename ada_include directory to src. + +990213 + + enable sigwinch handler by default. + + disable logic that allows setbuf to be turned off/on, because some + implementations will overrun the buffer after it has been disabled + once. + +990206 + + suppress sc/rc capabilities from terminal description if they appear + in smcup/rmcup. This affects only scrolling optimization, to fix a + problem reported by several people with xterm's alternate screen, + though the problem is more general. + > patch by Juergen Pfeifer, for Ada95 binding: + + removed all pragma Preelaborate() stuff, because the just released + gnat-3.11p complains on some constructs. + + fixed some upper/lower case notations because gnat-3.11p found + inconsistent use. + + used a new method to generate the HTML documentation of the Ada95 + binding. This invalidates nearly the whole ./Ada95/html subtree. + Nearly all current files in this subtree are removed + +990130 + + cache last result from _nc_baudrate, for performance (suggested by + Alexander Lukyanov). + + modify ClrUpdate() function to workaround a problem in nvi, which + uses redrawwin in SIGTSTP handling. Jeffrey C Honig reported that + ncurses repainted the screen with nulls before resuming normal + operation (patch by Alexander Lukyanov). + + generalize is_xterm() function a little by letting xterm/rxvt/kterm + be any substring rather than the prefix. + + modify lib_data.c to initialize SP. Some linkers, e.g., IBM's, will + not link a module if the only symbols exported from the module are + uninitialized ones (patch by Ilya Zakharevich, who says that he has + seen messages claiming this behaviour conforms to the standard.) + + move call on _nc_signal_handler past _nc_initscr, to avoid a small + window where Nttyb hasn't yet been filled (reported by Klaus Weide). + + modify lib_tstp.c to block SIGTTOU when handling SIGTSTP, fixes a + problem where ncurses applications which were run via a shell script + would hang when given a ^Z. Also, check if the terminal's process + group is consistent, i.e., a shell has not taken ownership of it, + before deciding to save the current terminal settings in the SIGTSTP + handler (patch by Klaus Weide). + + correct spelling of ACS_ names in curs_border.3x (reported by Bob van + der Poel ). + + correct a couple of typos in the macros supporting the configure + --with-shlib-version option. + +990123 + + modify fty_regex.c to compile on HAVE_REGEXPR_H_FUNCS machine (patch + by Kimio Ishii ). + + rename BSDI console terminfo entries: bsdos to bsdos-pc-nobold, and + bsdos-bold to bsdos-pc (patch by Jeffrey C Honig). + + modify tput to accept termcap names as an alternative to terminfo + names (patch by Jeffrey C Honig). + + correct a typo in term.7 (Todd C Miller). + + add configure --with-shlib-version option to allow installing shared + libraries named according to release or ABI versions. This + parameterizes some existing logic in the configure script, and is + intended for compatiblity upgrades on Digital Unix, which used + versioned libraries in ncurses 4.2, but no longer does (cf: 980425). + + resync configure script against autoconf 2.13 + patches + + minor improvements for teraterm terminfo entry based on the program's + source distribution. + +990116 + + change default for configure --enable-big-core to assume machines do + have enough memory to resolve terminfo.src in-memory. + + correct name of ncurses library in TEST_ARGS when configuring with + debug library. + + minor fixes to compile ncurses library with broken-linker with g++. + + add --enable-broken-linker configure option, default to environment + variable $BROKEN_LINKER (request by Jeffrey C Honig). + + change key_names[] array to static since it is not part of the curses + interface (reported by Jeffrey C Honig ). + +990110 + + add Tera Term terminfo entry - TD + +990109 + + reviewed/corrected macros in curses.h as per XSI document. + + provide support for termcap PC variable by copying it from terminfo + data and using it as the padding character in tputs (reported by + Alexander Lukyanov). + + corrected iris-ansi and iris-ansi-ap terminfo entries for kent and + kf9-kf12 capabilities, as well as adding kcbt. + + document the mouse handling mechanism in menu_driver and make a small + change in menu_driver's return codes to provide more consistency + (patch by Juergen Pfeifer). + + add fallback definition for NCURSES_CONST to termcap.h.in (reported + by Uchiyama Yasushi ). + + move lib_restart.c to ncurses/base, since it uses curses functions + directly, and therefore cannot be used in libtinfo.so + + rename micro_char_size to micro_col_size, adding #define to retain + old name. + + add set_a_attributes and set_pglen_inch to terminfo structure, as per + XSI and Solaris 2.5. + + minor makefile files to build ncurses test_progs + + update html files in misc directory to reflect changes since 4.2 + +990102 + + disable scroll hints when hashmap is enabled (patch by Alexander + Lukyanov). + + move logic for tic's verify of -e option versus -I and -C so that the + terminfo data is not processed if we cannot handle -e (reported by + Steven Schwartz . + + add test-driver traces to terminfo and termcap functions. + + provide support for termcap ospeed variable by copying it from the + internal cur_term member, and using ospeed as the baudrate reference + for the delay_output and tputs functions. If an application does not + set ospeed, the library behaves as before, except that _nc_timed_wait + is no longer used, or needed, since ospeed always has a value. But + the application can modify ospeed to adjust the output of padding + characters (from a bug report for screen 3.7.6 and email from Michael + Schroeder ). + + removed some unused ifdef's as part of Alexander's restructuring. + + reviewed/updated curses.h, term.h against X/Open Curses Issue 4 + Version 2. This includes making some parameters NCURSES_CONST + rather than const, e.g., in termcap.h. + + change linux terminfo entry to use ncv#2, since underline does not + work with color + +981226 + + miscellaneous corrections for curses.h to match XSI. + + change --enable-no-padding configure option to be normally enabled. + + add section to ncurses manpage for environment variables. + + investigated Debian bug report that pertains to screen 3.7.4/3.7.6 + changes, found no sign of problems on Linux (or on SunOS, Solaris) + running screen built with ncurses. + + check if tmp_fp is opened in tic.c before closing it (patch by Pavel + Roskin ). + + correct several font specification typos in man-pages. + +981220 + + correct default value for BUILD_CC (reported by Larry Virden). + +981219 + + modify _nc_set_writedir() to set a flag in _nc_tic_dir() to prevent + it from changing the terminfo directory after chdir'ing to it. + Otherwise, a relative path in $TERMINFO would confuse tic (from a + Debian bug report). + + correct/update ncsa terminfo entry (report by Larry Virden). + + update xterm-xfree86 terminfo to current (patch 90), smcur/rmcur changes + + add Mathew Vernon's mach console entries to terminfo.src + + more changes, moving functions, as part of Alexander's restructuring. + + modify configure script for GNU/Hurd share-library support, introduce + BUILD_CC variable for cross compiling (patch by Uchiyama Yasushi + ) + +981212 + + add environment variable NCURSES_NO_SETBUF to allow disabling the + setbuf feature, for testing purposes. + + correct ifdef's for termcap.h versus term.h that suppress redundant + declarations of prototypes (reported by H.J.Lu). + + modify Makefile.os2 to add linker flags which allow multiple copies + of an application to coexist (reported by Ilya Zakharevich). + + update Makefile.glibc and associated configure script so that ncurses + builds as a glibc add-on with the new directory configuration + (reported by H.J.Lu). + +981205 + + modify gen_reps() function in gen.c to work properly on SunOS + (sparc), which is a left-to-right architecture. + + modify relative_move and tputs to avoid an interaction with the + BSD-style padding. The relative_move function could produce a string + to replace on the screen which began with a numeric character, which + was then interpreted by tputs as padding. Now relative_move will not + generate a string with a leading digit in that case (overwrite). + Also, tputs will only interpret padding if the string begins with a + digit; as coded it permitted a string to begin with a decimal point + or asterisk (reported by Larry Virden). + > patches by Juergen Pfeifer: + + fix a typo in m_driver.c mouse handling and improves the error + handling. + + fix broken mouse handling in the Ada95 binding + + make the Ada95 sample application menus work with the new menu mouse + support + + improve the mouse handling introduced by Ilya; it now handles menus + with spacing. + + repair a minor bug in the menu_driver code discovered during this + rework. + + add new function wmouse_trafo() to hide implementation details of + _yoffset member of WINDOW struct needed for mouse coordinate + transformation. + +981128 + + modify Ada95/gen/gen.c to avoid using return-value of sprintf, since + some older implementations (e.g., SunOS 4.x) return the buffer + address rather than its length. + > patch by Rick Ohnemus: + + modify demo.cc to get it to compile with newer versions of egcs. + + trim a space that appears at the end of the table preprocessor lines + ('\" t). This space prevents some versions of man from displaying + the pages - changed to remove all trailing whitespace (TD) + + finally, 'make clean' does not remove panel objects. + > patches by Ilya Zakharevich: + + allow remapping of OS/2 mouse buttons using environment variable + MOUSE_BUTTONS_123 with the default value 132. + + add mouse support to ncurses menus. + +981121 + + modify misc/makedef.cmd to report old-style .def file symbols, and to + generate the .def files sorted by increasing names rather than the + reverse. + + add misc/*.ref which are J.J.G.Ripoll's dll definition files (renamed + from misc/*.old), and updated based on the entrypoint coding he used + for an older version of ncurses. + + add README.emx, to document how to build on OS/2 EMX. + + updates for config.guess, config.sub from Lynx + > patches by Ilya Zakharevich: + + minor fixes for mouse handling mode: + a) Do not initialize mouse if the request is to have no mouse; + b) Allow switching of OS/2 VIO mouse on and off. + + modify Makefile.os2 to support alternative means of generating + configure script, by translating Unix script with Perl. + > patches by Juergen Pfeifer: + + Updates MANIFEST to reflect changes in source structure + + Eliminates a problem introduced with my last patch for the C++ + binding in the panels code. It removes the update() call done in the + panel destructor. + + Changes in the Ada95 binding to better support systems where + sizeof(chtype)!=sizeof(int) (e.g. DEC Alpha). + +981114 + + modify install-script for manpages to skip over .orig and .rej files + (request by Larry Virden). + > patches/discussion by Alexander Lukyanov: + + move base-library sources into ncurses/base and tty (serial terminal) + sources into ncurses/tty, as part of Alexander Lukyanov's proposed + changes to ncurses library. + + copy _tracemouse() into ncurses.c so that lib_tracemse.c need not + be linked into the normal ncurses library. + + move macro winch to a function, to hide details of struct ldat + > patches by Juergen Pfeifer: + + fix a potential compile problem in cursesw.cc + + some Ada95 cosmetics + + fix a gen.c problem when compiling on 64-Bit machines + + fix Ada95/gen/Makefile.in "-L" linker switch + + modify Ada95 makefiles to use the INSTALL_PREFIX setting. + +981107 + + ifdef'd out lib_freeall.c when not configured. + + rename _tracebits() to _nc_tracebits(). + + move terminfo-library sources into ncurses/tinfo, and trace-support + functions into ncurses/trace as part of Alexander Lukyanov's proposed + changes to ncurses library. + + modify generated term.h to always specify its own definitions for + HAVE_TERMIOS_H, etc., to guard against inclusion by programs with + broken configure scripts. + +981031 + + modify terminfo parsing to accept octal and hexadecimal constants, + like Solaris. + + remove an autoconf 2.10 artifact from the configure script's check + for "-g" compiler options. (Though harmless, this confused someone + at Debian, who recently issued a patch that results in the opposite + effect). + + add configure option --with-ada-compiler to accommodate installations + that do not use gcc as the driver for GNAT (patch by Juergen + Pfeifer). + +981017 + + ensure ./man exists in configure script, needed when configuring + with --srcdir option. + + modify infocmp "-r" option to remove limit on formatted termcap + output, which makes it more like Solaris' version. + + modify captoinfo to treat no-argument case more like Solaris' version, + which uses the contents of $TERMCAP as the entry to format. + + modify mk-2nd.awk to handle subdirectories, e.g., ncurses/tty + (patch by Alexander V Lukyanov). + +981010 + + modify --with-terminfo-dirs option so that the default value is the + ${datadir} value, unless $TERMINFO_DIRS is already set. This gets + rid of a hardcoded list of candidate directories in the configure + script. + + add some error-checking to _nc_read_file_entry() to ensure that + strings are properly terminated (Todd C Miller). + + rename manpage file curs_scr_dmp.3x to curs_scr_dump.3x, to + correspond with contents (reported by Neil Zanella + ). + + remove redundant configure check for C++ which did not work when $CXX + was specified with a full pathname (reported by Andreas Jaeger). + + corrected bcopy/memmove check; the macro was not standalone. + +981003 + + remove unnecessary portion of OS/2 EMX mouse change from + check_pending() (reported by Alexander V Lukyanov). + +980926 + + implement mouse support for OS/2 EMX (adapted from patch against + 4.2(?) by Ilya Zakharevich). + + add configure-check for bcopy/memmove, for 980919 changes to hashmap. + + merge Data General terminfo from Hasufin - TD + + merge AIX 3.2.5 terminfo descriptions for IBM terminals, replaces + some older entries - TD + + modify tic to compile into %'char' form in preference to %{number}, + since that is a little more efficient. + + minor correction to infocmp to avoid displaying "difference" between + two capabilities that are rendered in equivalent forms. + + add -g option to tic/infocmp to force character constants to be + displayed in quoted form. Otherwise their decimal values are shown. + + modify setupterm so that cancelled strings are treated the same as + absent strings, cancelled and absent booleans false (does not affect + tic, infocmp). + + modify tic, infocmp to discard redundant i3, r3 strings when output + to termcap format. + > patch by Alexander V Lukyanov: + + improve performance of tparm, now it takes 19% instead of 25% when + profiling worm. + + rename maxlen/minlen to prec/width for better readability. + + use format string for printing strings. + + use len argument correctly in save_text, and pass it to save_number. + +980919 + + make test_progs compile (but hashmap does not function). + + correct NC_BUFFERED macro, used in lib_mvcur test-driver, modify + associated logic to avoid freeing the SP->_setbuf data. + + add modules home_terminfo and getenv_num to libtinfo. + + move write_entry to libtinfo, to work with termcap caching. + + minor fixes to blue.c to build with atac. + + remove softscroll.c module; no longer needed for testing. + > patches by Todd C Miller: + + use strtol(3) instead of atoi(3) when parsing env variables so we can + detect a bogus (non-numeric) value. + + check for terminal names > MAX_NAME_SIZE in a few more places when + dealing with env variables again. + + fix a MAX_NAME_SIZE that should be MAX_NAME_SIZE+1 + + use sizeof instead of strlen(3) on PRIVATE_INFO since it is a fixed + string #define (compile time vs runtime). + + when setting errno to ENOMEM, set it right before the return, not + before code that could, possibly, set errno to a different value. + > patches by Alexander V Lukyanov: + + use default background in update_cost_from_blank() + + disable scroll-hints when hashmap is configured. + + improve integration of hashmap scrolling code, by adding oldhash and + newhash data to SP struct. + + invoke del_curterm from delscreen. + + modify del_curterm to set cur_term to null if it matches the function's + parameter which is deleted. + + modify lib_doupdate to prefer parm_ich to the enter_insert_mode and + exit_insert_mode combination, adjusting InsCharCost to check + enter_insert_mode, exit_insert_mode and insert_padding. Add + insert_padding in insert mode after each char. This adds new costs + to the SP struct. + +980912 + + modify test-driver in lib_mvcur.s to use _nc_setbuffer, for consistent + treatment. + + modify ncurses to restore output to unbuffered on endwin, and resume + buffering in refresh (see lib_set_term.c and NC_BUFFERED macro). + + corrected HTML version numbers (according to the W3C validator, they + never were HTML 2.0-compliant, but are acceptable 3.0). + +980905 + + modify MKterminfo.sh to generate terminfo.5 with tables sorted by + capability name, as in SVr4. + + modified term.h, termcap.h headers to avoid redundant declarations. + + change 'u_int' type in tset.c to unsigned, making this compile on + Sequent PRX 4.1 (reported by Michael Sterrett ). + +980829 + + corrections to mailing addresses, and moving the magic line that + causes the man program to invoke tbl to the first line of each + manpage (patch by Rick Ohnemus ). + + add Makefile.os2 and supporting scripts to generate dll's on OS/2 EMX + (from J.J.G.Ripoll, with further integration by TD). + + correct a typo in icl6404 terminfo entry. + + add xtermm and xtermc terminfo entries. + > from esr's terminfo version: + + Added Francesco Potorti's tuned Wyse 99 entries. + + dtterm enacs correction from Alexander V Lukyanov. + + Add ncsa-ns, ncsa-m-ns and ncsa-m entries from esr version. + +980822 + + document AT&T acs characters in terminfo.5 manpage. + + use EMX _scrsize() function if terminfo and environment do not + declare the screen size (reported by Ilya Zakharevich + ). + + remove spurious '\' characters from eterm and osborne terminfo + entries (prompted by an old Debian bug report). + + correct reversed malloc/realloc calls in _nc_doalloc (reported by + Hans-Joachim Widmaier ). + + correct misplaced parenthesis which caused file-descriptor from + opening termcap to be lost, from 980725 changes (reported by Andreas + Jaeger). + +980815 + + modify lib_setup.c to eliminate unneeded include of when + termios is not used (patch by Todd C Miller). + + add function _nc_doalloc, to ensure that failed realloc calls do not + leak memory (reported by Todd C Miller). + + improved ncsa-telnet terminfo entry. + +980809 + + correct missing braces around a trace statement in read_entry.c, + from 980808 (reported by Kim DeVaughn and Liviu + Daia). + +980808 + + fix missing include in ditto.c (reported by Bernhard + Rosenkraenzer ) + + add NCSA telnet terminfo entries from Francesco Potorti + , from Debian bug reports. + + make handling of $LINES and $COLUMNS variables more compatible with + Solaris by allowing them to individually override the window size + as obtained via ioctl. + +980801 + + modify lib_vidattr.c to allow for terminal types (e.g., xterm-color) + which may reset all attributes in the 'op' capability, so that colors + are set before turning on bold and other attributes, but still after + turning attributes off. + + add 'ditto.c' to test directory to illustrate use of newterm for + initializing multiple screens. + + modify _nc_write_entry() to recover from failed attempt to link alias + for a terminfo on a filesystem which does not preserve character case + (reported by Peter L Jordan ). + +980725 + + updated versions of config.guess and config.sub based on automake 1.3 + + change name-comparisons in lib_termcap to compare no more than 2 + characters (gleaned from Debian distribution of 1.9.9g-8.8, verified + with Solaris curses). + + fix typo in curs_insstr.3x (patch by Todd C Miller) + + use 'access()' to check if ncurses library should be permitted to + open or modify files with fopen/open/link/unlink/remove calls, in + case the calling application is running in setuid mode (request by + Cristian Gafton , responding to Duncan Simpson + ). + + arm100 terminfo entries from Dave Millen ). + + qnxt2 and minitel terminfo entries from esr's version. + +980718 + + use -R option with ldconfig on FreeBSD because otherwise it resets + the search path to /usr/lib (reported by Dan Nelson). + + add -soname option when building shared libraries on OpenBSD 2.x + (request by QingLong). + + add configure options --with-manpage-format and --with-manpage-renames + (request by QingLong). + + correct conversion of CANCELLED_NUMERIC in write_object(), which was + omitting the high-order byte, producing a 254 in the compiled + terminfo. + + modify return-values of tgetflag, tgetnum, tgetstr, tigetflag, + tigetnum and tigetstr to be compatible with Solaris (gleaned from + Debian distribution of 1.9.9g-8.8). + + modify _nc_syserr_abort to abort only when compiled for debugging, + otherwise simply exit with an error. + +980711 + + modify Ada95 'gen' program to use appropriate library suffix (e.g., + "_g" for a debug build). + + update Ada95 'make clean' rule to include generics .ali files + + add a configure test to ensure that if GNAT is found, that it can + compile/link working Ada95 program. + + flush output in beep and flash functions, fixing a problem with + getstr (patch by Alexander V Lukyanov) + + fix egcs 1.0.2 warning for etip.h (patch by Chris Johns). + + correct ifdef/brace nesting in lib_sprintf.c (patch by Bernhard + Rosenkraenzer ). + + correct typo in wattr_get macro from 980509 fixes (patch by Dan + Nelson). + +980704 + + merge changes from current XFree86 xterm terminfo descriptions. + + add configure option '--without-ada'. + + add a smart-default for termcap 'ac' to terminfo 'acs_chars' which + corresponds to vt100. + + change translation for termcap 'rs' to terminfo 'rs2', which is + the documented equivalent, rather than 'rs1'. + +980627 + + slow 'worm' down a little, for very fast machines. + + corrected firstchar/lastchar computation in lib_hline.c + + simplify some expressions with CHANGED_CELL, CHANGED_RANGE and + CHANGED_TO_EOL macros. + + modify init_pair so that if a color-pair is reinitialized, we will + repaint the areas of the screen whose color changes, like SVr4 curses + (reported by Christian Maurer ). + + modify getsyx/setsyx macros to comply with SVr4 man-page which + says that leaveok() affects their behavior (report by Darryl Miles, + patch by Alexander V Lukyanov). + +980620 + + review terminfo.5 against Solaris 2.6 curses version, corrected + several minor errors/omissions. + + implement tparm %l format. + + implement tparm printf-style width and precision for %s, %d, %x, %o + as per XSI. + + implement tparm dynamic variables (reported by Xiaodan Tang). + +980613 + + update man-page for for wattr_set, wattr_get (cf: 980509) + + correct limits in hashtest, which would cause nonprinting characters + to be written to large screens. + + correct configure script, when --without-cxx was specified: the + wrong variable was used for cf_cv_type_of_bool. Compilers up to gcc + 2.8 tolerated the missing 'int'. + + remove the hardcoded name "gcc" for the GNU Ada compiler. The + compiler's name might be something like "egcs" (patch by Juergen + Pfeifer). + + correct curs_addch.3x, which implied that echochar could directly + display control characters (patch by Alexander V Lukyanov). + + fix typos in ncurses-intro.html (patch by Sidik Isani + ) + +980606 + + add configure test for conflicting use of exception in math.h and + other headers. + + minor optimization to 'hash()' function in hashmap.c, reduces its + time by 10%. + + correct form of LD_SHARED_OPTS for HP-UX 10.x (patch by Tim Mooney). + + fix missing quotes for 'print' in MKunctrl.awk script (reported by + Mihai Budiu ). + > patch by Alexander V Lukyanov: + + correct problem on Solaris (with poll() function) where getch could + hang indefinitely even if timeout(x) was called. This turned out to + be because milliseconds was not updated before 'goto retry' in + _nc_timed_wait. + + simplified the function _nc_timed_wait and fixed another bug, which + was the assumption of !GOOD_SELECT && HAVE_GETTIMEOFDAY in *timeleft + assignment. + + removed the cycle on EINTR, as it seems to be useless. + +980530 + + add makefile-rule for test/keynames + + modify run_tic.sh and shlib to ensure that user's .profile does not + override the $PATH used to run tic (patch by Tim Mooney). + + restore LD_SHARED_OPTS to $(LD_SHARED_FLAGS) when linking programs, + needed for HP-UX shared-library path (recommended by Tim Mooney). + + remove special case of HP-UX -L options, use +b options to embed + $(libdir) in the shared libraries (recommended by Tim Mooney). + + add checks for some possible buffer overflows and unchecked + malloc/realloc/calloc/strdup return values (patch by Todd C Miller + ) + +980523 + + correct maxx/maxy expression for num_columns/num_lines in derwin + (patch by Alexander V Lukyanov). + + add /usr/share/lib/terminfo and /usr/lib/terminfo as compatibilty + fallbacks to _nc_read_entry(), along with --with-terminfo-dirs + configure option (suggested by Mike Hopkirk). + + modify config.guess to recognize Unixware 2.1 and 7 (patch by Mike + Hopkirk ). + + suppress definition of CC_SHARED_OPTS in LDFLAGS_SHARED in c++ + Makefile.in, since this conflicts when g++ is used with HP-UX + compiler (reported by Tim Mooney). + + parenthesize 'strcpy' calls in c++ binding to workaround redefinition + in some C++ implementations (reported by several people running + egcs with glibc 2.0.93, analysis by Andreas Jaeger. + +980516 + + modify write_entry.c so that it will not attempt to link aliases + with embedded '/', but give only a warning. + + put -L$(libdir) first when linking programs, except for HP-UX. + + modify comp_scan.c to handle SVr4 terminfo description for att477, + which contains a colon in the description field. + + modify configure script to support SCO osr5.0.5 shared libraries + (from comp.unix.sco.programmer newsgroup item by Mike Hopkirk + ). + + eliminate extra GoTo call in lib_doupdate.c (patch by Alexander V. + Lukyanov). + + minor adjustments of const/NCURSES_CONST from IRIX compile. + + add updates based on esr's 980509 version of terminfo.src. + +980509 + + correct macros for wattr_set, wattr_get, separate wattrset macro from + these to preserve behavior that allows attributes to be combined with + color pair numbers. + + add configure option --enable-no-padding, to allow environment + variable $NCURSES_NO_PADDING to eliminate non-mandatory padding, + thereby making terminal emulators (e.g., for vt100) a little more + efficient (request by Daniel Eisenbud ). + + modify configure script to embed ABI in shared libraries for HP-UX + 10.x (detailed request by Tim Mooney). + + add test/example of the 'filter()' function. + + add nxterm and xterm-color terminfo description (request by Cristian + Gafton ). + + modify rxvt terminfo description to clear alternate screen before + switching back to normal screen, for compatibility with applications + which use xterm (reported by Manoj Kasichainula ). + + modify linux terminfo description to reset color palette (reported + by Telford Tendys ). + + correction to doupdate, for case where terminal does not support + insert/delete character. The logic did not check that there was a + difference in alignment of changes to old/new screens before + repainting the whole non-blank portion of the line. Modified to fall + through into logic that reduces by the portion which does not differ + (reported by Daniel Eisenbud ). + + minor performance improvement to wnoutrefresh by moving some + comparisons out of inner loop. + +980425 + + modify configure script to substitute NCURSES_CONST in curses.h + + updated terminfo entries for xterm-xf86-v40, xterm-16color, + xterm-8bit to correspond to XFree86 3.9Ag. + + remove restriction that forces ncurses to use setaf/setab if the + number of colors is greater than 8. (see 970524 for xterm-16color). + + change order of -L options (so that $(libdir) is searched first) when + linking tic and other programs, to workaround HP's linker. + Otherwise, the -L../lib is embedded when linking against shared + libraries and the installed program does not run (reported by Ralf + Hildebrandt). + + modify configuration of shared libraries on Digital Unix so that + versioning is embedded in the library, rather than implied by + links (patch by Tim Mooney). + +980418 + + modify etip.h to avoid conflict with math.h on HP-UX 9.03 with gcc + 2.8.1 which redefines 'exception' (reported by Ralf Hildebrandt + ). + + correct configure tests in CF_SHARED_OPTS which used $CC value to + check for gcc, rather than autoconf's $GCC value. This did not + work properly if the full pathname of the compiler were given + (reported by Michael Yount ). + + revise check for compiler options to force ANSI mode since repeating + an option such as -Aa causes HP's compiler to fail on its own headers + (reported by Clint Olsen ). + +980411 + + ifdef'd has_key() and mcprint() as extended functions. + + modified several prototypes to correspond with 1997 version of + X/Open Curses (affects ABI since developers have used attr_get). + + remove spurious trailing blanks in glibc addon-scripts (patch by + H.J.Lu). + + insert a few braces at locations where gcc-2.8.x asks to use them to + avoid ambigous else's, use -fpic rather than -fPIC for Linux (patch + by Juergen Pfeifer). + +980404 + + split SHLIB_LIST into SHLIB_DIRS/SHLIB_LIST to keep -L options + before -l to accommodate Solaris' linker (reported by Larry Virden). + +980328 + + modify lib_color.c to eliminate dependency on orig_colors and + orig_pair, since SVr4 curses does not require these either, but + uses them when they are available. + + add detailed usage-message to infocmp. + + correct a typo in att6386 entry (a "%?" which was "?"). + + add -f option to infocmp and tic, which formats the terminfo + if/then/else/endif so that they are readable (with newlines and + tabs). + + fixes for glibc addon scripts (patch by H.J.Lu). + +980321 + + revise configure macro CF_SPEED_TYPE so that termcap.h has speed_t + declared (from Adam J. Richter ) + + remove spurious curs_set() call from leaveok() (J.T.Conklin). + + corrected handling leaveok() in doupdate() (patch by Alexander V. + Lukyanov). + + improved version of wredrawln (patch by Alexander V. Lukyanov). + + correct c++/Makefile.in so install target do not have embedded ../lib + to confuse it (patch by Thomas Graf ). + + add warning to preinstall rule which checks if the installer would + overwrite a curses.h or termcap.h that is not derived from ncurses. + (The recommended configuration for developers who need both is to + use --disable-overwrite). + + modify preinstall rule in top-level Makefile to avoid implicit + use of 'sh', to accommodate Ultrix 4.4 (reported by Joao Palhoto + Matos , patch by Thomas Esser + ) + + refine ifdef's for TRACE so that libncurses has fewer dependencies + on libtinfo when TRACE is disabled. + + modify configure script so that if the --with-termlib option is used + to generate a separate terminfo library, we chain it to the ncurses + library with a "-l" option (reported by Darryl Miles and Ian T. + Zimmerman). + +980314 + + correct limits and window in wredrawln function (reported/analysis by + Alexander V. Lukyanov). + + correct sed expression in configure script for --with-fallback + option (patch by Jesse Thilo). + + correct some places in configure script where $enableval was used + rather than $withval (patch by Darryl Miles ). + + modify some man-pages so no '.' or '..' falls between TH and SH + macros, to accommodate man_db program (reported by Ian T. Zimmerman + ). + + terminfo.src 10.2.1 from Eric's webpage. + > several changes by Juergen Pfeifer: + + add copyright notices (and rcs id's) on remaining man-pages. + + corrected prototypes for slk_* functions, using chtype rather than + attr_t. + + implemented the wcolor_set() and slk_color() functions + + the slk_attr_{set,off,on} functions need an additional void* + parameter according to XSI. + + fix the C++ and Ada95 binding as well as the man pages to + reflect above enhancements. + +980307 + + use 'stat()' rather than 'access()' in toe.c to check for the + existence of $HOME/.terminfo, since it may be a file. + + suppress configure CF_CXX_LIBRARY check if we are not using g++ + 2.7.x, since this is not needed with g++ 2.8 or egcs (patch by + Juergen Pfeifer). + + turn on hashmap scrolling code by default, intend to remedy defects + by 4.3 release. + + minor corrections to terminfo.src changelog. + +980302 4.2 release for upload to prep.ai.mit.edu + + correct Florian's email address in ncurses-intro.html + + terminfo.src 10.2.0 from Eric. + +980228 pre-release + + add linux-koi8r replace linux-koi8, which is not KOI8 (patch by + QingLong ). + + minor documentation fixes (patch by Juergen Pfeifer). + + add setlocale() call to ncurses.c (reported by Claes G. Lindblad + ). + + correct sign-extension in lib_insstr.c (reported by Sotiris + Vassilopoulos ) + +980221 pre-release + + regenerated some documentation overlooked in 980214 patch + (ncurses-intro.doc, curs_outopts.3x.html) + + minor ifdef change to C++ binding to work with gcc 2.8.0 (patch by + Juergen Pfeifer). + + change maintainer's mailing address to florian@gnu.org, change + tentative mailing list address to bug-ncurses-request@gnu.org (patch + by Florian La Roche). + + add definition of $(REL_VERSION) to c++/Makefile.in (reported by Gran + Hasse ). + + restore version numbers to Ada95 binding, accidentally deleted by + copyright patch (patch by Juergen Pfeifer). + +980214 pre-release + + remove ncurses.lsm from MANIFEST so that it won't be used in FSF + distributions, though it is retained in development. + + correct scaling of milliseconds to nanoseconds in lib_napms.c (patch + by Jeremy Buhler). + + update mailing-list information (bug-ncurses@gnu.org). + + update announcement for upcoming 4.2 release. + + modify -lm test to check for 'sin()' rather than 'floor()' + + remove spurious commas from terminfo.src descriptions. + + change copyright notices to Free Software Foundation + +980207 + + minor fixes for autoconf macros CF_ERRNO, CF_HELP_MESSAGE and + CF_SIZECHANGE + + modify Makefile.glibc so that $(objpfx) is defined (H.J.Lu). + + ifdef-out true-return from _nc_mouse_inline() which depends on + merge of QNX patch (pending 4.2 release). + > patch by J.T.Conklin, to split off seldom-used modules in ncurses + (reduces size by up to 2.6kb): + + move functionality of _nc_usleep into napms, add configuration case + for nanosleep(). + + moved wchgat() from lib_addch.c to lib_chgat.c + + moved clearok(), immedok(), leaveok(), and scrollok() from + lib_options.c to lib_clearok.c, lib_immedok.c, lib_leaveok.c and + lib_scrollok.c. + + moved napms() from lib_kernel.c to lib_napms.c + + moved echo() and noecho() from lib_raw.c to lib_echo.c + + moved nl() and nonl() from lib_raw.c to lib_nl.c + +980131 + + corrected conversion in tclock.c (cf: 971018). + + updates to Makefile.glibc and associated Linux configure script + (patch by H.J.Lu). + + workaround a quoting problem on SunOS with tar-copy.sh + + correct init_pair() calls in worm.c to work when use_default_colors() + is not available. + + include in CF_SYS_TIME_SELECT to work with FreeBSD 2.1.5 + + add ncv capability to FreeBSD console (cons25w), making reverse + work with color. + + correct sense of configure-test for sys/time.h inclusion with + sys/select.h + + fixes for Ada95/ada_include/Makefile.in to work with --srcdir option. + + remove unused/obsolete test-program rules from progs/Makefile.in + (the rules in ncurses/Makefile.in work). + + remove shared-library loader flags from test/Makefile.in, etc. + + simplify test/configure.in using new version of autoconf to create + test/ncurses_cfg.h + + suppress suffix rules in test/Makefile.in, provide explicit dependency + to work with --srcdir option and less capable 'make' programs. + > adapted from patch for QNX by Xiaodan Tang: + + initialize %P and %g variables set/used in tparm, and also ensure + that empty strings don't return a null result from tparam_internal + + add QNX-specific prototype for vsscanf() + + move initialization of SP->_keytry from init_keytry() to newterm() to + avoid resetting it via a keyok() call by mouse_activate(). + + reorganized some functions in lib_mouse() to use case-statements. + + remove sgr string from qnx terminfo entry since it is reported to + turn off attributes inconsistently. + +980124 + + add f/F/b/B commands to ncurses 'b' test to toggle colors, providing + test for no_color_video. + + adjusted emx.src to use no_color_video, now works with ncurses 'b' + and 'k' tests. + + implement no_color_video attribute, and as a special case, reverse + colors when the reverse attribute cannot be combined with color. + + check for empty string in $TERM variable (reported by Brett Michaels + ). + > from reports by Fred Fish: + + add configure-test for isascii + + add configure-test for -lm library. + + modify CF_BOOL_SIZE to check if C++ bool types are unsigned. + > patches by J.J.G.Ripoll + + add configure/makefile variables to support .exe extension on + OS/2 EMX (requires additional autoconf patches). + + explicitly initialize variables in lib_data.c to appease OS/2 linker + > patches by Fred Fish + + misc/Makefile.in (install.data): Avoid trying to install the CVS + directory. + + aclocal.m4 (install.includes): Remove files in the include directory + where we are going to install new ones, not the original source + files. + + misc/terminfo.src: Add entry for "beterm", derived from termcap + distributed with BeOS PR2 using captoinfo. + + aclocal.m4: Wrap $cf_cv_type_of_bool with quotes (contains space) + + aclocal.m4: Assume bool types are unsigned. + + progs/infocmp.c: workaround mwcc 32k function data limit + +980117 + + correct initialization of color-pair (from 970524) in xmas.c, which + was using only one color-pair for all colors (reported by + J.J.G.Ripoll). + + add multithread options for objects build on EMX, for compatibility + with XFree86. + + split up an expression in MKlib_gen.sh to work around a problem on + OS/2 EMX, with 'ash' (patch by J.J.G.Ripoll). + + change terminfo entries xterm (xterm-xf86-v40), xterm-8bit rs1 to use + hard reset. + + rename terminfo entry xterm-xf86-v39t to xterm-xf86-v40 + + remove bold/underline from sun console entries since they're not + implemented. + + correct _tracef calls in _tracedump(), which did not separate format + from parameters. + + correct getopt string for tic "-o" option, and add it to man-page + synopsis (reported by Darren Hiebert ). + + correct typo in panel/Makefile.in, reversed if-statement in scrolling + optimization (Alexander V. Lukyanov). + + test for 'remove()', use 'unlink() if not found (patch by Philippe De + Muyter ). + > patches by Juergen Pfeifer: + + Improve a feature of the forms driver. For invisible fields + (O_VISIBLE off) only the contents but not the attributes are cleared. + We now clear both. (Reported by Javier Kohan + ) + + The man page form_field_opts.3x makes now clear, that invisible + fields are also always inactive. + + adjust ifdef's to compile the C++ binding with the just released + gcc-2.8.0 c++ and the corresponding new C++ libraries. + +980110 + + correct "?" command in ncurses.c; it was performing non-screen writes + while the program was in screen mode. (It "worked" in 1.9.9e because + that version sets OPOST and OCRNL incorrectly). + + return error from functions in lib_kernel, lib_raw and lib_ti if + cur_term is null, or if underlying I/O fails. + + amend change to tputs() so that it does not return an error if + cur_term is null, since some applications depend on being able to use + tputs without initializing the terminal (reported by Christian J. + Robinson ). + +980103 + + add a copy of emx.src from J.J.G.Ripoll's OS/2 EMX version of ncurses + 1.9.9e, together with fixes/additions for the "ansi" terminal type. + + add tic check for save/restore cursor if change_scroll_region is + defined (from O'Reilly book). + + modify read_termcap.c to handle EMX-style pathnames (reported by + J.J.G.Ripoll). + + modify lib_raw.c to use EMX's setmode (from J.J.G.Ripoll, who says + EMX's curses does this). + + modify _nc_tic_expand() to generate \0 rather than \200. + + move/revise 'expand()' from dump_entry.c to ncurses library as + _nc_tic_expand(), for use by tack. + + decode \a as \007 for terminfo, as per XSI. + + correct translation of terminfo "^@", to \200, like \0. + + modify next_char() to treat the same as , for + cross-platform compatibility. + + use new version of autoconf (971230) to work around limited + environment on CLIX, due to the way autoconf builds --help message. + > patch by Juergen Pfeifer: + + check that the Ada95 binding runs against the correct version of + ncurses. + + insert constants about the library version into the main spec-file of + the Ada95 binding. + +971227 + + modify open/fopen calls to use binary mode, needed for EMX. + + modify configure script to work with autoconf 2.10 mods for OS/2 + EMX from J.J.G.Ripoll. + + generated ncurses_cfg.h with patch (971222) to autoconf 2.12 which + bypasses limited sed buffer length. + > several changes from Juan Jose Garcia Ripoll + (J.J.G.Ripoll) to support OS/2 EMX: + + add a _scrolling flag to SP, to set when we encounter a terminal + that simply cannot scroll. + + corrected logic in _nc_add_to_try(), by ensuring that strings with + embedded \200 characters are matched. + + don't assume the host has 'link()' function, for linking terminfo + entries. + +971220 + + if there's no ioctl's to support sigwinch handler, disable it. + + add configure option --disable-ext-funcs to remove the extended + functions from the build. + + add configure option --with-termlib to generate the terminfo + functions as a separate library. + + add 'sources' rule to facilitate cross-compiling. + + review/fix order of mostlyclean/clean/distclean rules. + + modify install-rule for headers to first remove old header, in + case there was a symbolic link that confuses the install script. + + corrected substitution for NCURSES_CONST in term.h (cf: 971108) + + add null pointer checks in wnoutrefresh(), overlap() (patch by + Xiaodan Tang ) + + correct tputs(), which could dereference a null cur_term if invoked + before terminal is initialized (patch by Christopher Seawood + ) + > patch by Juergen Pfeifer: + + makes better use of "pragma Inline" in the Ada95 binding + + resynchronizes the generated html manpages + +971213 + + additional fixes for man-pages section-references + + add (for debugging) a check for ich/ich1 conflict with smir/rmir + to tic, etc. + + remove hpa/vpa from rxvt terminal description because they are not + implemented correctly, added sgr0. + + change ncurses 's' to use raw mode, so ^Q works (reported by Rudolf + Leitgeb ) + +971206 + + modify protection when installing libraries to (normally) not + executable. HP-UX shared libraries are an exception. + + add configure check for 'tack'. + + implement script for renaming section-references in man-page install, + for Debian configuration. + + add validity-check for SP in trace code in baudrate() (reported by + Daniel Weaver). + > patch by Alexander V. Lukyanov (fixes to match sol25 curses) + + modify 'overlay()' so that copy applies target window background to + characters. + + correct 'mvwin()' so that it does not clear the previous locations. + + correct lib_acs.c so that 8-bit character is not sign expanded in + case of wide characters in chtype. + + correct control-char test in lib_addch.c for use with wide chars + + use attribute in the chtype when adding a control character in + lib_addch.c control char was added with current attribute + +971129 + + save/restore errno in _tracef() function + + change treatment of initialize_color to use a range of 0..1000 + (recommended by Daniel Weaver). + + set umask in mkinstalldirs, fixing problems reported by users who + have set root's umask to 077. + + correct bug in tic that caused capabilities to be reprinted at the + end of output when they had embedded comments. + + rewrote wredrawln to correspond to XSI, and split-out since it is + not often used (from report by Alexander V. Lukyanov, 970825) + + rewrote Dan Nelson's change to make it portable, as well as to + correct logic for handling backslashes. + + add code to _nc_tgetent() to make it work more like a real tgetent(). + It removes all empty fields, and removes all but the first in a group + of duplicate caps. The code was pulled from the BSD libtermcap code + in termcap.c (patch by Dan Nelson + + don't include --enable-widec in the --with-develop configure option, + since it is not binary-compatible with 4.1 (noted by Alexander V. + Lukyanov) + > patch by Juergen Pfeifer: + + further improvements of the usage of elaboration pragmas in the Ada95 + binding + + enhanced Ada95 sample to use the user_data mechanism for panels. + + a fix for the configuration script to make gnat-3.10 the required + version. + + resync of the html version of the manpages + +971122 + > fixes/updates for terminfo.src: + + add vt220-js, pilot, rbcomm, datapoint entries from esr's 27-jun-97 + version. + + add hds200 description (Walter Skorski) + + add EMX 0.9b descriptions + + correct rmso/smso capabilities in wy30-mc and wy50-mc (Daniel Weaver) + + rename xhpterm back to hpterm. + > patch by Juergen Pfeifer: + + Improves the usage of elaboration pragmas for the Ada95 binding. + + Adds a translation of the test/rain.c into Ada95 to the samples. + This has been contributed to the project by Laurent Pautet + (pautet@gnat.com) + +971115 + + increase MAX_NAME_SIZE to 512 to handle extremely long alias list + in HP-UX terminfo. + + correction & simplification of delay computation in tputs, based on + comments from Daniel Weaver. + + replace test for SCO with more precise header tests. + + add configure test for unsigned literals, use in NCURSES_BITS macro. + + comment-out the -PIC, etc., flags from c++, progs and test makefiles + since they probably are not needed, and are less efficient (noted by. + Ju"rgen Fluk) + + add -L$(libdir) to loader options, after -L../lib so that loaders + that record this information will tend to do the right thing if + the programs are moved around after installing them (suggested by. + Ju"rgen Fluk). + + add -R option to loader options for programs for Solaris if the + --enable-rpath option is specified for the libraries. + +971112 + + correct installed filename for shared libraries on *BSD (reported by + Ju"rgen Fluk). + +971108 + + cleanup logic for deciding when tputs() should call delay_output(), + based on comments from Daniel Weaver. + + modified tputs() to avoid use of float. + + correct use of trailpad in tputs(), which used the wrong variable + in call to delay_output(). + + correct inverted expression for null-count in delay_output() + (analysis by Daniel Weaver). + + apply --enable-rpath option to Solaris (requested by Larry Virden). + + correct substitution of EXTRA_CFLAGS for gcc 2.6.3 + + correct check for error-return by _nc_tgetent(), which returns 0 + for success. + + add configure test for BSD 4.4 cgetent() function, modify + read_termcap.c to use the host's version of that if found, using the + terminal database on FreeBSD (reported by Peter Wemm). + + add u8, u9 strings to sun-il description for Daniel Weaver. + + use NCURSES_CONST in panel's user-pointer. + + modify edit_cfg.sh and MKterm.h.awk.in to substitute NCURSES_CONST + so that will work on NeXT. + + use _nc_set_screen() rather than assignments to SP to fix port to + NeXT (reported by Francisco A. Tomei Torres). + +971101 + + force mandatory padding in bell and flash_screen, as specified in XSI. + + don't allow padding_baud_rate to override mandatory delays (reported + by Daniel Weaver). + + modify delay_output() to use _nc_timed_wait() if no baudrate has been + defined, or if the cur_term pointer is not initialized. XSI treats + this as unspecified. (requested by Daniel Weaver). + + change getcap-cache ifdef's to eliminate unnecessary chdir/mkdir + when that feature is not configured. + + remove _nc_err_abort() calls when write_entry.c finds a directory but + cannot write to it, e.g., when translating part/all of /etc/termcap + (reported by Andreas Jaeger ). + (this dates back to 951102, in 1.9.7a). + + minor ifdef fixes to compile with atac and glibc 2.0.5c + + add check for -lgen when configuring regexpr.h + + modify Solaris shared-library option "-d y" to "-dy" to workaround + incompatibility of gcc 2.7.2 vs vendor's tools. + +971026 + + correct ifdef's for struct winsize vs struct ttysize in lib_setup.c + to compile on SCO. + + remove dangling backslash in panel/Makefile.in + + modify MKkeyname.awk to work with SCO's nawk, which dumps core in the + length() function. + + correct length of allocation in _nc_add_to_try(), to allow for + trailing null. + + correct logic in _nc_remove_key(), which was discarding too many + nodes (patch by Alexander V. Lukyanov) + +971025 + + add definition for $(REL_VERSION) to test/Makefile.in, so *BSD + shared libraries link properly (see 970524). + + modify Linux shared-library generation to include library + dependencies (e.g., -lncurses and -lgpm) in the forms, menu and + panel libraries (suggested by Juergen Pfeifer). + + modify configure script to use config.guess and config.sub rather + than uname, which is unreliable on some systems. + + updated Makefile.glibc, test-built with glibc 2.0.5c + + modify keyname() to return values consistent with SVr4 curses (patch + by Ju"rgen Fluk). + > changes requested by Daniel Weaver: + + modify delay_output() so that it uses the same output function as + tputs() if called from that function. + + move _baudrate from SCREEN to TERMINAL so that low-level use of + tputs works when SP is not set. + > patch by Juergen Pfeifer: + + factor lib_menu and lib_form into smaller modules + + clean up the interface between panel and SCREEN + + minor changes to the Ada95 mouse support implemenation + + minor bugfix in C++ binding to ripoff windows + + fix a few Ada95 html documentation pages + +971018 + + split-out lib_ungetch.c, make runtime link to resizeterm() to + decouple those modules from lib_restart.c + + add xterm-xf86-v39t description to terminfo.src + + reset SP->_endwin in lib_tstp.c cleanup() function after calling + endwin() to avoid unnecessary repainting if the application has + established an atexit function, etc. Encountered this problem in + the c++ demo, whose destructors repaint the screen. + + combine _nc_get_screensize() and resizeterm() calls as new function + _nc_update_screensize(). + + minor fixes to allow compile with g++ (suggested by Nelson H. F. + Beebe). + + implement install-rules for Ada95 makefiles. + + use screen_lines or MAXLINES as needed where LINES was coded, + as well as screen_columns for COLS, in the ncurses library. + > patch by Alexander V. Lukyanov: + + modify logic for ripped-off lines to handle several SCREENs. + > patch by Juergen Pfeifer: + + factors lib_slk.c into some smaller modules + + factors panel.c into some smaller modules + + puts the static information about the current panel stack into the + SCREEN structure to allow different panel stacks on different + screens. + + preliminary fix for an error adjusting LINES to account for + ripped-off lines. + +971011 + + move _nc_max_click_interval and other mouse interface items to SCREEN + struct so that they are associated with a single terminal, and also + save memory when the application does not need a mouse (roughly 3k vs + 0.5k on Linux). + + modify mouseinterval() so that a negative parameter queries the + click-interval without modifying it. + + modify ncurses 'i' test to work with ncurses' apparent extension from + SVr4, i.e., allows nocbreak+noecho (analysis by Alexander V. + Lukyanov). + + add configure options --with-ada-includes and --with-ada-objects, + to drive Ada95 binding install (not yet implemented). + + install C++ binding as -lncurses++ and associated headers with the + other ncurses headers. + + fix header uninstall if configure --srcdir is used. + > minor interface changes (request by Daniel Weaver , + to support 'tack' program): + + export functions _nc_trans_string() and _nc_msec_cost(). + + add variable _nc_nulls_sent, to record the number of padding + characters output in delay_output(). + + move tests for generic_type and hard_copy terminals in setupterm() + to the end of that function so that the library will still be + initialized, though not generally useful for curses programs. + > patches by Alexander V. Lukyanov: + + modify ClrBottom() to avoid using clr_eos if there is only one line + to erase. + + typo in configure --help. + > patch by J.T.Conklin (with minor resync against Juergen's changes) + + split-out lib_flash.c from lib_beep.c + + split-out lib_hline.c and lib_vline.c from lib_box.c + + split-out lib_wattron.c, lib_wattroff.c from lib_addch.c + +971005 + > patch by Juergen Pfeifer: + + correct source/target of c++/edit_cfg.sh + +971004 + + add color, mouse support to kterm terminfo entry. + + modify lib_mouse.c to recognize rxvt, kterm, color_xterm also as + providing "xterm"-style mouse. + + updated rxvt's terminfo description to correspond to 2.21b, with + fixes for the acsc (the box1 capability is incorrect, ech1 does not + work). + + fix logic in parse_entry.c that discarded acsc when 'synthesizing' + an entry from equivalents in XENIX or AIX. This lets ncurses handle + the distribution copy of rxvt's terminfo. + + modify acsc capability for linux and linux-koi8 terminfo descriptions + (from Pavel Roskin ). + + corrected definition in curses.h for ACS_LANTERN, which was 'I' + rather than 'i' (see 970802). + + updated terminfo.src with reformatted acsc entries, and repaired the + trashed entries with spurious '\' characters that this exposed. + + add logic to dump_entry.c to reformat acsc entries into canonical + form (sorted, unique mapping). + + add configure script to generate c++/etip.h + + add configure --with-develop option, to enable by default most of the + experimental options (requested by Alexander V. Lukyanov). + + rename 'deinstall' to 'uninstall', following GNU convention (suggested + by Alexander V. Lukyanov). + > patches by Alexander V. Lukyanov: + + modify tactics 2 and 5 in onscreen_mvcur(), to allow them on the last + line of the screen, since carriage return will not cause a newline. + + remove clause from PutCharLR() that would try to use + eat_newline_glitch since that apparently does not work on some + terminals (e.g., M$ telnet). + + correct a limit check in scroll_csr_backward() + > patches by Juergen Pfeifer: + + adds dummy implementations of methods above() and below() to the + NCursesPanel class. + + fixes missing returncode in NCursesWindow::ripoffline() + + fixes missing returncode in TestApplication::run() in demo.cc + + We should at least give a comment in etip.h why it is currently a + problem to install the C++ binding somewhere + + makes the WINDOW* argument of wenclose() a const. + + modifies several of the routines in lib_adabind.c to use a const + WINDOW* argument. + +970927 + + add 'deinstall' rules. + + use explicit assignments in configure --without-progs option to + work around autoconf bug which doesn't always set $withval. + + check for ldconfig, don't try to run it if not found. + + implement simple/unoptimized case in lib_doupdate.c to handle + display with magic cookie glitch, tested with ncurses.c program. + + correct missing _tracef in getmouse(), to balance the returnCode + macro. + + simplify show_attr() in ncurses.c using termattrs(). + > patches by Juergen Pfeifer: + + provides missing inlines for mvw[hv]line in cursesw.h of the C++ + binding + + fixes a typo in a comment of frm_driver.c + + Enhances Ada95 Makefiles to fulfill the requirement of GNAT-3.10 that + generics should be compiled. Proper fixes to the configuration + scripts are also provided. + +970920 + + several modifications to the configure script (requested by Ward + Horner): + + add configure options --without-progs, to suppress the build of the + utility programs, e.g., for cross-compiling. + + add $(HOSTCCFLAGS) and $(HOSTLDFLAGS) symbols to ncurses + Makefile.in, to simplify setup for cross compiling. + + add logic in configure script to recognize "--target=vxworks", and + generate load/install actions for VxWorks objects. + + move typedef for sigaction_t into SigAction.h to work around problem + generating lint library. + + modify fty_regex.c to reflect renaming of ifdef's for regular + expressions. + + simplify ifdef in lib_setup.c for TIOCGWINSZ since that symbol may + reside in . + + merge testcurs.c with version from PDCurses 2.3, clarifying some of + the more obscure tests, which rely upon color. + + use macros getbegyx() and getmaxyx() in newdemo.c and testcurs.c + + modify ncurses.c to use getbegyx() and getmaxyx() macros to cover up + implementation difference wrt SVr4 curses, allow 's' test to work. + + add missing endwin() to testscanw.c program (reported by Fausto + Saporito ). + + fixes/updates for Makefile.glibc and related files under sysdeps + (patch by H.J.Lu). + > patches by Juergen Pfeifer: + + add checks for null pointers, especially WINDOW's throughout the + ncurses library. + + solve a problem with wrong calculation of panel overlapping (reported + by Ward Horner): + + make sure that a panel's window isn't a pad. + + do more error checking in module lib_touch.c + + missing files for Ada95 binding from the last patch + + synch. of generated html pages (RCS-Id's were wrong in html files) + + support for Key_Resize in Ada binding + + changed documentation style in ./c++/cursesm.h + > patches by Alexander V. Lukyanov: + + undo attempt to do recursive inlining for PutChar(), noting that it + did not improve timing measurably, but inflated the size of + lib_doupdate.o + +970913 + + modify rain.c to use color. + + correct scroll_csr_backward() to match scroll_csr_forward(). + + minor adjustment to llib-lncurses, to work with Solaris 2.5.1 + + minor fixes to sysdeps/unix/sysv/linux/configure to reflect renaming + of configure cache variables in 970906. + + correct logic involving changes to O_VISIBLE option in + Synchronize_Options function in frm_driver.c (Tony Hoffmann + ) + + add $(HOSTCC) symbol to ncurses Makefile.in, to simplify setup for + cross compiling (suggested by Chris Johns). + + modify ifdef in lib_setup.c to only include if we can + use it to support screen-size calculation (reported by Chris Johns). + + #undef unctrl to avoid symbol conflict in port to RTEMS (reported by + Chris Johns ) + > patches by Juergen Pfeifer: + + simplified, made minor corrections to Ada95 binding to form fieldtype. + + The C++ binding has been enhanced: + + Improve NCursesWindow class: added additional methods to cover + more ncurses functionality. Make refresh() and noutrefresh() + virtual members to allow different implementation in the + NCursesPanel class. + + CAUTION: changed order of parameters in vline() and hline() of + NCursesWindow class. + + Make refresh() in NCursesPanel non-static, it is now a + reimplementation of refresh() in the base class. Added + noutrefresh() to NCursesPanel. + + Added NCursesForm and related classes to support libform + functionality. + + Moved most of configuration related stuff from cursesw.h to etip.h + + Added NCursesApplication class to support easy configuration of + menu and forms related attributes as well as ripped of title lines + and Soft-Label-Keys for an application. + + Support of Auto-Cleanup for a menu's fieldlist. + + Change of return type for current_item() and operator[] for menus. + + Enhanced demo. + + Fixed a bug in form/fld_def.c: take into account that copyarg and + freearg for a fieldtype may be NULL, makearg must not be NULL + + Fixed a bug in form/fld_type.c: in set_fieldtype_arg() makearg must + not be NULL, copyarg and freearg may be NULL. + + Fixed a bug in form/frm_def.c: Allow Disconnect_Fields() if it is + already disconnected. + + Enhance form/frm_driver.c: Allow growth of dynamic fields also on + navigation requests. + + Fixed a bug in form/fty_enum.c: wrong position of postincrement in + case-insensitiva comparision routine. + + Enhanced form/lib_adabind.c with function _nc_get_field() to get a + forms field by index. + + Enhanced menu/m_adabind.c with function _nc_get_item() to get a menus + item by index. + + Fixed in curses.h.in: make chtype argument for pechochar() constant. + Mark wbkgdset() as implemented, remove wbkgdset macro, because it was + broken (didn't handle colors correctly). + + Enhanced lib_mouse.c: added _nc_has_mouse() function + + Added _nc_has_mouse() prototype to curses.priv.h + + Modified lib_bkgd.c: hopefully correct implementation of wbkgdset(); + streamlined implementation of wbkgd() + + Modified lib_mvwin.c: Disable move of a pad. Implement (costly) + move of subwindows. Fixed update behaviour of movements of regular + windows. + + Fixed lib_pad.c: make chtype argument of pechochar() const. + + Fixed lib_window.c: dupwin() is not(!) in every bit a really clone + of the original. Subwindows become regular windows by doing a + dupwin(). + + Improved manpage form_fieldtype.3x + > patches by Alexander V. Lukyanov: + + simplify the PutChar() handling of exit_am_mode, because we already + know that auto_right_margin is true. + + add a check in PutChar() for ability to insert to the case of + shifting character to LR corner. + + in terminal initialization by _nc_screen_resume(), make sure that + terminal right margin mode is known. + + move logic that invokes touchline(), or does the equivalent, into + _nc_scroll_window(). + + modify scrolling logic use of insert/delete line capability, assuming + that they affect the screen contents only within the current + scrolling region. + + modify rain.c to demonstrate SIGWINCH handler. + + remove logic from getch() that would return an ERR if the application + called getch() when the cursor was at the lower-right corner of the + physical screen, and the terminal does not have insert-character + ability. + + change view.c so that it breaks out of getch() loop if a KEY_RESIZE + is read, and modify logic in getch() so this fix will yield the + desired behavior, i.e., the screen is repainted automatically when + the terminal window is resized. + +970906 + + add configure option --enable-sigwinch + + modify view.c to test KEY_RESIZE logic, with "-r" option. + + modify testcurs.c to eliminate misleading display wrt cursor type + by testing if the terminal supports cnorm, civis, cvvis. + + several fixes for m68k/NeXT 4.0, to bring cur_term, _nc_curr_line and + _nc_curr_col variables into linked programs: move these variables, + making new modules lib_cur_term and trace_buf (reported by Francisco + Alberto Tomei Torres ). + > patches by Alexander V. Lukyanov: + + add pseudo-functionkey KEY_RESIZE which is returned by getch() when + the SIGWINCH handler has been called since the last call to + doupdate(). + + modify lib_twait.c to hide EINTR only if HIDE_EINTR is defined. + + add SIGWINCH handler to ncurses library which is used if there is no + application SIGWINCH handler in effect when the screen is + initialized. + + make linked list of all SCREEN structures. + + move curses.h include before definition of SCREEN to use types in + that structure. + + correction to ensure that wgetstr uses only a newline to force a + scroll (970831). + +970831 + + add experimental configure option --enable-safe-sprintf; the normal + mode now allocates a buffer as large as the screen for the + lib_printw.c functions. + + modify wgetch to refresh screen when reading ungetch'd characters, + since the application may require this - SVr4 does this. + + refine treatment of newline in wgetstr to echo only when this would + force the screen to scroll. + +970830 + + remove override in wgetstr() that forces keypad(), since SVr4 does + not do this. + + correct y-reference for erasure in wgetstr() when a wrap forces a + scroll. + + correct x-position in waddch() after a wrap forces a scroll. + + echo newline in wgetstr(), making testscanw.c scroll properly when + scanw is done. + + modify vwscanw() to avoid potential buffer overflow. + + rewrote lib_printw.c to eliminate fixed-buffer limits. + > patches by Alexander V. Lukyanov: + + correct an error in handling cooked mode in wgetch(); processing + was in the wrong order. + + simplified logic in wgetch() that handles backspace, etc., by using + wechochar(). + + correct wechochar() so that it interprets the output character as + in waddch(). + + modify pechochar() to use prefresh() rather than doupdate(), since + the latter does not guarantee immediate refresh of the pad. + + modify pechochar() so that if called with a non-pad WINDOW, will + invoke wechochar() instead. + + modify fifo indices to allow fifo to be longer than 127 bytes. + +970823 + + add xterm-8bit to terminfo.src + + moved logic for SP->_fifohold inside check_pending() to make it + work properly when we add calls to that function. + + ensure that bool functions return only TRUE or FALSE, and TRUE/FALSE + are assigned to bool values (patch by H.J.Lu). + > patches by Alexander V. Lukyanov: + + several fixes to getch: + 1. Separate cooked and raw keys in fifo + 2. Fix the case of ungetch'ed KEY_MOUSE + 3. wrap the code for hiding EINTR with ifdef HIDE_EINTR + 4. correctly handle input errors (i.e., EINTR) without loss of raw + keys + 5. recognize ESC KEY_LEFT and similar + 6. correctly handle the case of receiption of KEY_MOUSE from gpm + + correct off-by-one indexing error in _nc_mouse_parse(), that caused + single mouse events (press/release) to be ignored in favor of + composed events (click). Improves on a fix from integrating gpm + support in 961229. + + add another call to check_pending, before scrolling, for + line-breakout optimization + + improve hashmap.c by + 1. fixed loop condition in grow_hunks() + 2. not marking lines with offset 0 + 3. fixed condition of 'too far' criteria, thus one-line hunks are + ignored and two lines interchanged won't pass. + + rewrote/simplified _nc_scroll_optimize() by separating into two + passes, forward/backward, looking for chunks moving only in the given + direction. + + move logic that emits sgr0 when initializing the screen to + _nc_screen_init(), now invoked from newterm. + + move cursor-movement cleanup from endwin() into _nc_mvcur_wrap() + function and screen cleanup (i.e., color) into _nc_screen_wrap() + function. + + add new functions _nc_screen_init(), _nc_screen_resume() and + _nc_screen_wrap(). + + rename _nc_mvcur_scrolln() to _nc_scrolln(). + + add a copy of acs_map[] to the SCREEN structure, where it can be + stored/retrieved via set_term(). + + move variables _nc_idcok, _nc_idlok, _nc_windows into the SCREEN + structure. + +970816 + + implement experimental _nc_perform_scroll(). + + modify newterm (actually _nc_setupscreen()) to emit an sgr0 when + initializing the screen, as does SVr4 (reported by Alexander V. + Lukyanov). + + added test_progs rule to ncurses/Makefile. + + modify test/configure.in to check if initscr is already in $LIBS + before looking for (n)curses library. + + correct version-number in configure script for OSF1 shared-library + options (patch by Tim Mooney). + + add -DNDEBUG to CPPFLAGS for --enable-assertions (as Juergen + originally patched) since the c++ demo files do not necessarily + include ncurses_cfg.h + + supply default value for --enable-assertions option in configure + script (reported by Kriang Lerdsuwanakij ). + > patches by Alexander V. Lukyanov: + + correct/simplify logic of werase(), wclrtoeol() and wclrbot(). See + example firstlast.c + + optimize waddch_literal() and waddch_nosync() by factoring out + common subexpressions. + + correct sense of NDEBUG ifdef for CHECK_POSITION macro. + + corrections to render_char(), to make handling of colored blanks + match SVr4 curses, as well as to correct a bug that xor'd space + against the background character. + + replaced hash function with a faster one (timed it) + + rewrote the hashmap algorithm to be one-pass, this avoids multiple + cost_effective() calls on the same lines. + + modified cost_effective() so it is now slightly more precise. + > patches by H.J.Lu for glibc integration: + + add modules define_key, keyok, name_match, tries + + add makefile rules for some of the unit tests in ncurses (mvcur, + captoinfo, hardscroll, hashmap). + + update Linux configure-script for wide-character definitions. + +970809 + + modify _tracebits() to show the character size (e.g., CS8). + + modify tparm() to emit '\200' where the generated string would have a + null (reported by From: Ian Dall for + terminal type ncr7900). + + modify install process so that ldconfig is not invoked if the + package is built with an install-prefix. + + correct test program for chtype size (reported by Tim Mooney). + + add configure option --disable-scroll-hints, using this to ifdef the + logic that computes indices for _nc_scroll_optimize(). + + add module ncurses/softscroll.c, to perform single-stage computation + of scroll indices used in _nc_scroll_optimize(). This is faster than + the existing scrolling algorithm, but tends to make too-small hunks. + + eliminate fixed buffer size in _nc_linedump(). + + minor fixes to lib_doupdate.c to add tradeoff between clr_eol (el) + and clr_bol (el1), refine logic in ClrUpdate() and ClrBottom() (patch + by Alexander V. Lukyanov). + + add test/testaddch.c, from a pending patch by Alexander V. Lukyanov. + + correct processing of "configure --enable-assertions" option (patch + by Juergen Pfeifer). + +970802 + + add '-s' (single-step) option too test/hashtest.c, correct an error + in loop limit for '-f' (footer option), toggle scrollok() when + writing footer to avoid wrap at lower-right corner. + + correct behavior of clrtoeol() immediately after wrapping cursor, + which was not clearing the line at the cursor position (reported by + Liviu Daia ). + + corrected mapping for ACS_LANTERN, which was 'I' rather than 'i' + (reported by Klaus Weide ). + + many corrections to make progs/capconvert work, as well as make it + reasonably portable and integrated with ncurses 4.1 (reported by Dave + Furstenau ). + +970726 + + add flag SP->_fifohold, corresponding logic to modify the behavior of + the line breakout logic so that if the application does not read + input, refreshes will not be stopped, but only slowed. + + generate slk_attr_off(), slk_attr_on(), slk_attr_set(), vid_attr(), + ifdef'd for wide-character support, since ncurses' WA_xxx attribute + masks are identical with the A_xxx masks. + + modify MKlib_gen.sh to generate ifdef'd functions to support optional + configuration of wide-characters. + + modify tset to behave more like SVr4's tset, which does not modify + the settings of intr, quit or erase unless they are given as command + options (reported by Nelson H. F. Beebe ). + + modify tset to look in /etc/ttys or /etc/ttytype if the configuration + does not have getttynam(). + + extend baudrate table in tset.c to match baudrate() function. + + add table entries for 230400 and 460800 bd to baudrate() function. + + improve breakout logic by allowing it before the first line updated, + which is what SVr4 curses does (patch by Alexander V. Lukyanov). + + correct initialization of vcost in relative_move(), for cursor-down + case (patch by Alexander V. Lukyanov). + > nits gleaned from Debian distribution of 1.9.9g-3: + + install symbolic link for intotocap. + + reference libc directly when making shared libraries. + + correct renaming of curs_scr_dmp.3x in man_db.renames. + + guard tgetflag() and other termcap functions against null cur_term + pointer. + +970719 + + corrected initial state of software echo (error in 970405, reported + by Alexander V. Lukyanov). + + reviewed/added messages to configure script, so that all non-test + options should be accompanied by a message. + + add configure check for long filenames, using this to determine if + it is safe to allow long aliases for terminal descriptions as does + SVr4. + + add configure options for widec (wide character), hashmap (both + experimental). + > patch by Alexander V. Lukyanov: + + hashmap.c - improved by heuristic, so that scroll test works much + better when csr is not available. + + hardscroll.c - patched so that it continues to scroll other chunks + after failure to scroll one. + + lib_doupdate.c - _nc_mvcur_scrolln extended to handle more cases; csr + is avoided as it is relative costly. Fixed wrong coordinates in one + case and wrong string in TRACE. + > patch by Juergen Pfeifer: + + modify C++ binding to compile on AIX 4.x with the IBM C-SET++ + compiler. + +970712 + + remove alternate character set from kterm terminfo entry; it uses the + shift-out control for a purpose incompatible with curses, i.e., font + switching. + + disentangle 'xterm' terminfo entry from some derived entries that + should be based on xterm-r6 instead. + + add cbt to xterm-xf86-xv32 terminfo entry; I added the emulation for + XFree86 3.1.2F, but overlooked its use in terminfo then - T.Dickey. + + correct logic in lib_mvcur.c that uses back_tab. + +970706 + + correct change from 970628 to ClrUpdate() in lib_doupdate.c so that + contents of curscr are saved in newscr before clearing the screen. + This is needed to make repainting work with the present logic of + TransformLine(). + + use napms() rather than sleep() in tset.c to avoid interrupting I/O. + +970705 + + add limit checks to _nc_read_file_entry() to guard against overflow + of buffer when reading incompatible terminfo format, e.g, from OSF/1. + + correct some loop-variable errors in xmc support in lib_doupdate.c + + modify ncurses 'b' test to add gaps, specified by user, to allow + investigation of interaction with xmc (magic cookie) code. + + correct typo in 970524 mods to xmas.c, had omitted empty parameter + list from has_colors(), which gcc ignores, but SVr4 does not + (reported by Larry Virden). + + correct rmso capability in wy50-mc description. + + add configure option "--enable-hard-tabs", renamed TABS_OK ifdef to + USE_HARD_TABS. + > patch by Juergen Pfeifer: + + Add bindings for keyok() and define_key() to the Ada95 packages. + + Improve man pages menu_post.3x and menu_format.3x + + Fix the HTML pages in the Ada95/html directory to reflect the above + changes. + +970628 + + modify change from 970101 to ClrUpdate() in lib_doupdate.c so that + pending changes to both curscr and newscr are flushed properly. + This fixes a case where the first scrolling operation in nvi would + cause the screen to be cleared unnecessarily and repainted before + doing the indexing, i.e., by repeatedly pressing 'j' (reported by + Juergen Pfeifer). + + correct error in trans_string() which added embedded newlines in a + terminfo description to the stored strings. + + remove spurious newlines from sgr in wyse50 (and several other) + terminfo descriptions. + + add configure option for experimental xmc (magic cookie) code, + "--enable-xmc-glitch". When disabled (the default), attributes that + would store a magic cookie are suppressed in vidputs(). The magic + cookie code is far from workable at this stage; the configuration + option is a stopgap. + + move _nc_initscr() from lib_initscr.c to lib_newterm.c + + correct path for invoking make_keys (a missing "./"). + +970621 + + correct sign-extension problem with "infocmp -e", which corrupted + acsc values computed for linux fallback data. + + correct dependency on ncurses/names.c (a missing "./"). + + modify configure script to use '&&' even for cd'ing to existing + directories to work around broken shell interpreters. + + correct a loop-limit in _nc_hash_map() (patch by Alexander V. + Lukyanov). + +970615 + + restore logic in _nc_scroll_optimize() which marks as touched the + lines in curscr that are shifted. + + add new utility 'make_keys' to compute keys.tries as a table rather + than a series of function calls. + + correct include-dependency for tic.h used by name_match + + removed buffer-allocation for name and description from m_item_new.c, + since this might result in incompatibilities with SVr4. Also fixed + the corresponding Ada95 binding module (patch by Juergen Pfeifer, + from report by Avery Pennarun ) + + removed the mechanism to timestamp the generated Ada95 sources. This + resulted always in generating patches for the HTML doc, even when + nothing really changed (patch by Juergen Pfeifer). + + improve man page mitem_new.3x (patch by Juergen Pfeifer). + +970614 + + remove ech capability from rxvt description because it does not work. + + add missing case logic for infocmp -I option (reported by Lorenzo M. + Catucci ) + + correct old bug in pnoutrefresh() unmasked by fix in 970531; this + caused glitches in the ncurses 'p' test since the area outside the + pad was not compared when setting up indices for _nc_scroll_optimize. + + rewrote tracebits() to workaround misdefinition of TOSTOP on Ultrix + 4.4, as well as to eliminate fixed-size buffer (reported by Chris + Tanner ) + + correct prototype for termattrs() as per XPG4 version 2. + + add placeholder prototypes for color_set(), erasewchar(), + term_attrs(), wcolor_set() as per XPG4 version 2. + + correct attribution for progs/progs.priv.h and lib_twait.c + + improve line-breakout logic by checking based on changed lines rather + than total lines (patch by Alexander V. Lukyanov). + + correct loop limits for table-lookup of enumerated value in form + (patch by Juergen Pfeifer). + + improve threshhold computation for determining when to call ClrToEOL + (patch by Alexander V. Lukyanov). + +970531 + + add configure option --disable-database to force the library to + use only the fallback data. + + add configure option --with-fallbacks, to specify list of fallback + terminal descriptions. + + add a symbolic link for ncurses.h during install; too many programs + still assume there's an ncurses.h + + add new terminfo.src entry for xterm-xf86-v33. + + restore terminfo.src entry for emu to using setf/setb, since it is + not, after all, generating ANSI sequences. Corrected missing comma + that caused setf/setb entries to merge. + + modify mousemask() to use keyok() to enable/disable KEY_MOUSE, so + that applications can disable ncurses' mouse and supply their own + handler. + + add extensions keyok() and define_key(). These are designed to allow + the user's application better control over the use of function keys, + e.g., disabling the ncurses KEY_MOUSE. (The define_key idea was from + a mailing-list thread started by kjahds@kjahds.com Nov'1995). + + restore original behavior in ncurses 'g' test, i.e., explicitly + set the keypad mode rather than use the default, since it confuses + people. + + rewrote the newdemo banner so it's readable (reported by Hugh Daniel). + + tidy up exit from hashtest (reported by Hugh Daniel). + + restore check for ^Q in ncurses 'g' test broken in 970510 (reported + by Hugh Daniel) + + correct tput program, checking return-value of setupterm (patch by + Florian La Roche). + + correct logic in pnoutrefresh() and pechochar() functions (reported + by Kriang Lerdsuwanakij ). The computation + of 'wide' date to eric's #283 (1.9.9), and the pechochar bug to the + original implementation (1.9.6). + + correct typo in vt102-w terminfo.src entry (patch by Robert Wuest + ) + + move calls of _nc_background() out of various loops, as its return + value will be the same for the whole window being operated on (patch + by J.T.Conklin). + + add macros getcur[xy] getbeg[xy] getpar[xy], which are defined in + SVr4 headers (patch by J.T.Conklin ) + + modify glibc addon-configure scripts (patch by H.J.Lu). + + correct a bug in hashmap.c: the size used for clearing the hashmap + table was incorrect, causing stack corruption for large values of + LINES, e.g., >MAXLINES/2 (patch by Alexander V. Lukyanov). + + eric's terminfo 9.13.23 & 9.13.24 changes: replaced minitel-2 entry, + added MGR, ansi-nt (note: the changes described for 9.13.24 have not + been applied). + > several changes by Juergen Pfeifer: + + correct a missing error-return in form_driver.c when wrapping of a + field is not possible. + + correct logic in form_driver.c for configurations that do not have + memccpy() (reported by Sidik Isani ) + + change several c++ binding functions to inline. + + modify c++ menu binding to inherit from panels, for proper + initialization. + + correct freeing of menu items in c++ binding. + + modify c++ binding to reflect removal of const from user data pointer + in forms/menus libraries. + +970524 + + add description of xterm-16color. + + modify name of shared-library on *BSD to end with $(REL_VERSION) + rather than $(ABI_VERSION) to match actual convention on FreeBSD + (cf: 960713). + + add OpenBSD to shared-library case, same as NetBSD and FreeBSD + (reported by Hugh Daniel ). + + corrected include-dependency in menu/Makefile so that "make install" + works properly w/o first doing "make". + + add fallback definition for isascii, used in infocmp. + + modify xmas to use color, and to exit right away when a key is + pressed. + + modify gdc so that the scrolled digits function as described (there + was no time delay between the stages, and the digits overwrote the + bounding box without tidying up). + + modify lib_color.c to use setaf/setab only for the ANSI color codes + 0 through 7. Using 16 colors requires setf/setb. + + modify ncurses 'c' test to work with 16 colors, as well as the normal + 8 colors. + + remove const qualifier from user data pointer in forms and menus + libraries (patch by Juergen Pfeifer). + + rewrote 'waddchnstr()' to avoid using the _nc_waddch_nosync() + function, thereby not interpreting tabs, etc., as per spec (patch by + Alexander V. Lukyanov). + +970517 + + suppress check for pre-existing ncurses header if the --prefix + option is specified. + + add configure options "--with-system-type" and "--with-system-release" + to assist in checking the generated makefiles. + + add configure option "--enable-rpath" to allow installers to specify + that programs linked against shared libraries will have their library + path embedded, allowing installs into nonstandard locations. + + add flags to OSF1 shared-library options to specify version and + symbol file (patch by Tim Mooney ) + + add missing definition for ABI_VERSION to c++/Makefile.in (reported + by Satoshi Adachi ). + + modify link flags to accommodate HP-UX linker which embeds absolute + pathnames in executables linked against shared libraries (reported by + Jason Evans , solved by Alan Shutko + ). + + drop unnecessary check for attribute-change in onscreen_mvcur() since + mvcur() is the only caller within the library, and that check in turn + is exercised only from lib_doupdate.c (patch by Alexander V. + Lukyanov). + + add 'blank' parameter to _nc_scroll_window() so _nc_mvcur_scrolln() + can use the background of stdscr as a parameter to that function + (patch by Alexander V. Lukyanov). + + moved _nc_mvcur_scrolln() from lib_mvcur.c to lib_doupdate.c, to use + the latter's internal functions, as well as to eliminate unnecessary + cursor save/restore operations (patch by Alexander V. Lukyanov). + + omit parameter of ClrUpdate(), since it is called only for newscr, + further optimized/reduced by using ClearScreen() and TransformLine() + to get rid of duplicate code (patch by Alexander V. Lukyanov). + + modify scrolling algorithm in _nc_scroll_optimize() to reject hunks + that are smaller than the distance to be moved (patch by Alexander V. + Lukyanov). + + correct a place where the panel library was not ifdef'd in ncurses.c + (Juergen Pfeifer) + + documentation fixes (Juergen Pfeifer) + +970515 4.1 release for upload to prep.ai.mit.edu + + re-tag changes since 970505 as 4.1 release. + +970510 + + modify ncurses 'g' test to allow mouse input + + modify default xterm description to include mouse. + + modify configure script to add -Wwrite-strings if gcc warnings are + enabled while configuring --enable-const (and fixed related warnings). + + add toggle, status display for keypad mode to ncurses 'g' test to + verify that keypad and scrollok are not inherited from parent window + during a call to newwin. + + correction to MKexpanded.sh to make it work when configure --srcdir is + used (reported by H.J.Lu). + + revise test for bool-type, ensuring that it checks if builtin.h is + available before including it, adding test for sizeof(bool) equal + to sizeof(short), and warning user if the size cannot be determined + (reported by Alexander V. Lukyanov). + + add files to support configuration of ncurses as an add-on library + for GNU libc (patch by H.J.Lu ) + +970506 + + correct buffer overrun in lib_traceatr.c + + modify change to lib_vidattr.c to avoid redundant orig_pair. + + turn on 'echo()' in hanoi.c, since it is initially off. + + rename local 'errno' variable in etip.h to avoid conflict with global + (H.J.Lu). + + modify configure script to cache LD, AR, AR_OPTS (patch by H.J.Lu + ) + +970505 4.1 pre-release + + regenerate the misc directory html dumps without the link list, which + is not useful. + + correct dependency in form directory makefile which caused unnecessary + recompiles. + + correct substitution for ABI_VERSION in test-makefile + + modify install rules for shared-library targets to remove the target + before installing, since some install programs do not properly handle + overwrite of symbolic links. + + change order of top-level targets so that 'include' immediate + precedes the 'ncurses' directory, reducing the time between new + headers and new libraries (requested by Larry Virden). + + modify lib_vidattr.c so that colors are turned off only before + modifying other attributes, turned on after others. This makes the + hanoi.c program display correctly on FreeBSD console. + + modify debug code in panel library to print user-data addresses + rather than the strings which they (may) point to. + + add check to ensure that C++ binding and demo are not built with g++ + versions below 2.7, since the binding uses templates. + + modify c++ binding and demo to build and run with SGI's c++ compiler. + (It also compiles with the Sun SparcWorks compiler, but the demo does + not link, due to a vtbl problem). + + corrections to demo.cc, to fix out-of-scope variables (Juergen + Pfeifer). + +970503 + + correct memory leak in _nc_trace_buf(). + + add configure test for regexpr.h, for Unixware 1.x. + + correct missing "./" prefixing names of generated files in ncurses + directory. + + use single-quotes in configure scripts assignments for MK_SHARED_LIB + to workaround shell bug on FreeBSD 2.1.5 + + remove tabs from intermediate #define's for GCC_PRINTF, GCC_SCANF + that caused incorrect result in ncurses_cfg.h + + correct initialization in lib_trace.c, which omitted version info. + + remove ech, el1 attributes from cons25w description; they appear to + malfunction in FreeBSD 2.1.5 + + correct color attributes in terminfo.src and lib_color.c to match + SVr4 behavior by interchanging codes 1,4, 3,6 in the setf/setb + capabilities. + + use curs_set() rather than checks via tigetstr() for test programs + that hide the cursor: firework, rain, worm. + + ensure that if the terminal lacks change_scroll_region, parm_index + and parm_rindex are used only to scroll the whole screen (patch by + Peter Wemm). + + correct curs_set() logic, which did not return ERR if the requested + attributes did not exist, nor did it assume an unknown initial state + for the cursor (patch by Alexander V. Lukyanov). + + combine IDcTransformLine and NoIDcTransformLine to new TransformLine + function in lib_doupdate.c (patch by Alexander V. Lukyanov). + + correct hashmap.c, which did not update index information (patch by + Alexander V. Lukyanov). + + patch by Juergen Pfeifer for C++ binding and demo (see c++/NEWS) + + correct index in lib_instr.c (Juergen Pfeifer). + + correct typo in 970426 patch from Tom's cleanup of lib_overlay.c + (Juergen Pfeifer). + +970426 + + corrected cost computation in PutRange(), which was using + milliseconds compared to characters by adding two new members to the + SCREEN struct, _hpa_ch_cost and _cup_ch_cost. + + drop ncurses/lib_unctrl.c, add ncurses/MKunctrl.awk to generate a + const array of strings (suggested by Alexander V. Lukyanov, though + with a perl script 970118). + + rewrote ncurses 'b' test to better exercise magic-cookie (xmc), as + well as noting the attributes that are not supported by a terminal. + + trace the computation of cost values in lib_mvcur.c + + modify _nc_visbuf() to use octal rather than hex, corrected sign + extension bug in that function that caused buffer overflow. + + modify trace in lib_acs.c to use _nc_visbuf(). + + suppress trace within _traceattr2(). + + correct logic of _tracechtype2(), which did not account for repeats + or redefinition within an acsc string. + + modify debug-library version baudrate() to use environment variable + $BAUDRATE to override speed computation. This is needed for + regression testing. + + correct problems shown by "weblint -pedantic". + + update mailing-list information (now ncurses@bsdi.com). + +970419 + + Improve form_field_validation.3x manpage to better describe the + precision parameter for TYPE_NUMERIC and TYPE_INTEGER. Provide more + precise information how the range checking can be avoided. (patch by + Juergen Pfeifer, reported by Bryan Henderson) + + change type of min/max value of form types TYPE_INTEGER to long to + match SVr4 documentation. + + set the form window to stdscr in set_form_win() so that form_win() + won't return null (patch by Juergen Pfeifer, reported by Bryan + Henderson ). + +970412 + + corrected ifdef'ing of inline (from 970321) for TRACE vs C++. + + corrected toggle_attr_off() macro (patch by Andries.Brouwer). + + modify treatment of empty token in $MANPATH to /usr/man (reported by + ) + + modify traces that record functions-called so that chtype and attr_t + values are expressed symbolically, to simplify reuse of generated + test-scripts on SVr4 regression testing. + + add new trace functions _traceattr2() and _tracechtype2() + +970405 + + add configure option --enable-const, to support the use of 'const' + where XSI should have, but did not, specify. This defines + NCURSES_CONST, which is an empty token otherwise, for strict + compatibility. + + make processing of configure options more verbose by echoing the + --enable/--with values. + + add configure option --enable-big-core + + set initial state of software echo off as per XSI. + + check for C++ builtin.h header + + correct computation of absolute-path for $INSTALL that dropped "-c" + parameter from the expression. + + rename config.h to ncurses_cfg.h to avoid naming-conflict when ncurses + is integrated into larger systems (from diffs by H.J.Lu for libc). + + correct inequality in lib_doupdate.c that caused a single-char to not + be updated when the char on the right-margin was not blank, idcok() + was true (patch by Alexander V. Lukyanov 970124, also reported by + Kriang Lerdsuwanakij 970329). + + modify 'clean' rule in include/Makefile so that files created by + configure script are removed in 'distclean' rule instead. + +970328 + + correct array limit in tparam_internal(), add case to interpret "%x" + (patch by Andreas Schwab) + + rewrote number-parsing in ncurses.c 'd' test; it did not reset the + value properly when non-numeric characters were given (reported by + Andreas Schwab ) + +970321 + + move definition of __INTERNAL_CAPS_VISIBLE before include for + progs.priv.h (patch by David MacKenzie). + + add configuration summary, reordered check for default include + directory to better accommodate a case where installer is configuring + a second copy of ncurses (reported by Klaus Weide + ) + + moved the #define for 'inline' as an empty token from the + $(CFLAGS_DEBUG) symbol into config.h, to avoid redefinition warning + (reported by Ward Horner). + + modify test for bool builtin type to use 'unsigned' rather than + 'unknown' when cross-compiling (reported by Ward Horner). + +970315 + + add header dependencies so that "make install.libs" will succeed + even if "make all" is not done first. + + moved some macros from lib_doupdate.c to curses.priv.h to use in + expanded functions with ATAC. + + correct implementation of lib_instr.c; both XSI and SVr4 agree that + the winnstr functions can return more characters than will fit on one + line. + +970308 + + modify script that generates lib_gen.c to support traces of called & + return. + + add new configure option "--disable-macros", for testing calls within + lib_gen.c + + corrected logic that screens level-checking of called/return traces. + +970301 + + use new configure macro NC_SUBST to replace AC_PATH_PROG, better + addressing request by Ward Horner. + + check for cross-compiling before trying to invoke the autoconf + AC_FUNC_SETVBUF_REVERSED macro (reported by Ward Horner) + + correct/simplify loop in _nc_visbuf(), 970201 changes omitted + a pointer-increment. + + eliminate obsolete symbol SHARED_ABI from dist.mk (noted by + Florian La Roche). + +970215 + + add configure option --enable-expanded, together with code that + implements an expanded form of certain complex macros, for testing + with ATAC. + + disable CHECK_POSITION unless --with-assertions is configured + (Alexander Lukyanov pointed out that this is redundant). + + use keyname() to show traced chtype values where applicable rather + than _tracechar(), which truncates the value to 8-bits. + + minor fixes to TRACE_ICALLS, added T_CREATE, TRACE_CCALLS macros. + + modify makefiles in progs and test directories to avoid using C + preprocessor options on link commands (reported by Ward Horner) + + correct ifdef/include-order for nc_alloc.h vs lib_freeall.c (reported + by Ward Horner) + + modify ifdef's to use configure-defined symbols consistently + (reported by Ward Horner) + + add/use new makefile symbols AR, AR_OPTS and LD to assist in non-UNIX + ports (reported by Ward Horner ) + + rename struct try to struct tries, to avoid name conflict with C++ + (reported by Gary Johnson). + + modify worm.c to hide cursor while running. + + add -Wcast-qual to gcc warnings, fix accordingly. + + use PutChar rather than PutAttrChar in ClrToEOL to properly handle + wrapping (Alexander Lukyanov). + + correct spurious echoing of input in hanoi.c from eric's #291 & #292 + patches (reported by Vernon C. Hoxie ). + + extend IRIX configuration to IRIX64 + + supply missing install.libs rule needed after restructuring + test/Makefile.in + +970208 + + modify "make mostlyclean" to leave automatically-generated source + in the ncurses directory, for use in cross-compiles. + + autogenerated object-dependencies for test directory + + add configure option --with-rcs-ids + + modify configuration scripts to generate major/minor/patch versions + (suggested by Alexander Lukyanov). + + supply missing va_end's in lib_scanw.c + + use stream I/O for trace-output, to eliminate fixed-size buffer + + add TRACE_ICALLS definition/support to lib_trace.c + + modify Ada95 binding to work with GNAT 3.09 (Juergen Pfeifer). + +970201 + + add/modify traces for called/return values to simplify extraction + for test scripts. + + changed _nc_visbuf to quote its result, and to dynamically allocate + the returned buffer. + + invoke ldconfig after installing shared library + + modify install so that overwrite applies to shared library -lcurses + in preference to static library (reported by Zeyd 960928). + + correct missing ';' in 961221 mod to overwrite option use of $(LN_S). + + fixes to allow "make install" to work without first doing a "make + all" (suggested by Larry Virden). + +970125 + + correct order of #ifdef for TABS_OK. + + instrumented toe.c to test memory-leaks. + + correct memory-deallocation in toe.c (patch by Jesse Thilo). + + include in configuration test for regex.h (patch by + Andreas Schwab) + + make infocmp recognize -I option, for SVr4 compatibility (reported by + Andreas Schwab ) + +970118 + + add extension 'use_default_colors()', modified test applications that + use default background (firework, gdc, hanoi, knight, worm) to + demonstrate. + + correct some limit checks in lib_doupdate.c exposed while running + worm. + + use typeCalloc macro for readability. + + add/use definition for CONST to accommodate testing with Solaris + (SVr4) curses, which doesn't use 'const' in its prototypes. + + modify ifdef's in test/hashtest.c and test/view.c to compile with + Solaris curses. + + modify _tracedump() to pad pad colors & attrs lines to match change + in 970101 showing first/last changes. + + corrected location of terminating null on dynamically allocated forms + fields (patch by Per Foreby). + +970111 + + added headers to make view.c compile on SCO with the resizeterm() + code (i.e., struct winsize) - though this compiles, I don't have a + suitable test configuration since SIGWINCH doesn't pass my network to + that machine - T.Dickey. + + update test/configure.in to supply some default substitutions. + + modify configure script to add -lncurses after -lgpm to fix problem + linking against static libraries. + + add a missing noraw() to test/ncurses.c (places noted by Jeremy + Buhler) + + add a missing wclear() to test/testcurs.c (patch by Jeremy Buhler + ) + + modify headers to accommodate compilers that don't allow duplicate + "#define" lines for NCURSES_VERSION (reported by Larry W. Virden + ) + + fix formatting glitch in curs_getch.3x (patch by Jesse Thilo). + + modify lib_doupdate to make el, el1 and ed optimization use the + can_clear_with macro, and change EmitRange to allow leaving cursor at + the middle of interval, rather than always at the end (patch by + Alexander Lukyanov originally 960929, resync 970106). + +970104 + + workaround defect in autoconf 2.12 (which terminates configuration + if no C++ compiler is found) by adding an option --without-cxx. + + modify several man-pages to use tbl, where .nf/.fi was used (reported + by Jesse Thilo). + + correct font-codes in some man-pages (patch by Jesse Thilo + ) + + use configure script's knowledge of existence of g++ library for the + c++ Makefile (reported by Paul Jackson). + + correct misleading description of --datadir configuration option + (reported by Paul Jackson ) + +970101 + + several corrections to _nc_mvcur_scrolln(), prompted by a bug report + from Peter Wemm: + > the logic for non_dest_scroll_region was interchanged between the + forward & reverse scrolling cases. + > multiple returns from the function allowed certain conditions to do + part of an operation before discovering that it couldn't be + completed, returning an error without restoring the cursor. + > some returns were ERR, where the function had completed the + operation, because the insert/delete line logic was improperly + tested (this was probably the case Peter saw). + > contrary to comments, some scrolling cases were tested after the + insert/delete line method. + + modify _tracedump() to show first/last changes. + + modify param of ClrUpdate() in lib_doupdate.c to 'newscr', fixes + refresh problem (reported by Peter Wemm) that caused nvi to not show + result of ":r !ls" until a ^L was typed. + +961229 (internal alpha) + + correct some of the writable-strings warnings (reported by Gary + Johnson ). Note that most of the remaining ones + are part of the XSI specification, and can't be "fixed". + + improve include-dependencies in form, menu, panel directories. + + correct logic of delay_output(), which would return early if + there is data on stdin. + + modify interface & logic of _nc_timed_wait() to support 2 file + descriptors, needed for GPM. + + integrate patch by Andrew Kuchling for GPM (mouse) + support, correcting logic in wgetch() and _nc_mouse_parse() which + prevented patch from working properly. + + improve performance of panel algorithm (Juergen Pfeifer 961203). + + strip RCS id's from generated .html files in Ada95 subtree. + + resync with generated .html files (Juergen Pfeifer 961223). + + terminfo.src 10.1.0 from Eric. + +961224 4.0 release + + release as 4.0 to accommodate Linux ld.so.1.8.5 + + correct syntax/spelling, regenerated .doc files from .html using + lynx 2.5 + + refined forms/menus makefiles (Juergen Pfeifer 961223). + +961221 - snapshot + + remove logic in read_entry.c that attempts to refine errno by using + 'access()' for the directory (from patch by Florian La Roche). + + correct configure test/substitution that inhibits generating + include-path to /usr/include if gcc is used (reported by Florian La + Roche). + + modify setupterm() to allocate new TERMINAL for each call, just as + solaris' curses does (Alexander Lukyanov 960829). + + corrected memory leaks in read_entry.c + + add configure options --with-dbmalloc, --with-dmalloc, and + --disable-leaks, tested by instrumenting infocmp, ncurses programs. + + move #include's for stdlib.h and string.h to *.priv.h to accommodate + use of dbmalloc. + + modify use of $(LN_S) to follow recommendation in autoconf 2.12, + i.e., set current directory before linking. + + split-out panel.priv.h, improve dependencies for forms, menus + (Juergen Pfeifer 961204). + + modify _nc_freewin() to reset globals curscr/newscr/stdscr when + freeing the corresponding WINDOW (Purify). + + modify delwin() to return ERR if the window to be deleted has + subwindows, needed as a side-effect of resizeterm() (Purify). Tested + and found that SVr4 curses behaves this way. + + implement logic for _nc_freeall(), bringing stub up to date. + +961215 + + modify wbkgd() so that it doesn't set nulls in the rendered text, + even if its argument doesn't specify a character (fixes test case by + Juergen Pfeifer for bug-report). + + set window-attributes in wbkgd(), to simplify comparison against + Solaris curses, which does this. + +961214 - snapshot + + replace most constants in ncurses 'o' test by expressions, making it + work with wider range of screen sizes. + + add options to ncurses.c to specify 'e' test softkey format, and the + number of header/footer lines to rip-off. + + add ^R (repaint after resize), ^L (refresh) commands to ncurses 'p' + test. + + add shell-out (!) command to ncurses 'p' test to allow test of + resize between endwin/refresh. + + correct line-wrap case in mvcur() by emitting carriage return, + overlooked in 960928, but needed due to SVr4 compatibility changes to + terminal modes in 960907. + + correct logic in wresize that causes new lines to be allocated, + broken for the special case of increasing rows only in 960907's fix + for subwindows. + + modify configure script to generate $(LDFLAGS) with -L and -l options + in preference to explicit library filenames. (NOTE: this may + require further amending, since I vaguely recall a dynamic loader + that did not work properly without the full names, but it should be + handled as an exception to the rule, since some linkers do bulk + inclusion of libraries when given the full name - T.Dickey). + + modify configure script to allow user-supplied $CFLAGS to set the + debug-option in all libraries (requested by lots of people). + + use return consistently from main(), rather than exit (reported by + Florian La Roche). + + add --enable-getcap-cache option to configure, normally disabled + (requested by Florian La Roche). + + make configure test for gettimeofday() and possibly -lbsd more + efficient (requested by Florian La Roche florian@knorke.saar.de) + + minor adjustments to Ada95 binding (patches by Juergen Pfeifer) + + correct attributes after emitting orig_pair in lib_vidattr.c (patch + by lav@yars.free.net). + +961208 + + corrected README wrt Ada95 (Juergen Pfeifer) + +961207 - snapshot + + integrate resizeterm() into doupdate(), so that if screen size + changes between endwin/refresh, ncurses will resize windows to fit + (this needs additional testing with pads and softkeys). + + add, for memory-leak testing, _nc_freeall() entrypoint to free all + data used in ncurses library. + + initialize _nc_idcok, _nc_idlok statically to resolve discrepancy + between initscr() and newwin() initialization (reported by + lav@yars.free.net). + + test built VERSION=4.0, SHARED_ABI=4 with Linux ld.so.1.8.5 + (set beta versions to those values -- NOTE that subsequent pre-4.0 + beta may not be interchangeable). + + modify configure script to work with autoconf 2.12 + +961130 1.9.9g release + + add copyright notices to configuration scripts (written by Thomas + Dickey). + +961127 + > patch by Juergen Pfeifer (mostly for panel): + + cosmetic improvement for a few routines in the ncurses core library + to avoid warning messages. + + the panel overlap detection was broken + + the panel_window() function was not fool-proof. + + Some inlining... + + Cosmetic changes (also to avoid warning messages when compiling with + -DTRACE). + +961126 + > patch by Juergen Pfeifer: + + eliminates warning messages for the compile of libform. + + inserts Per Foreby's new field type TYPE_IPV4 into libform. + + Updates man page and the Ada95 binding to reflect this. + + Improves inlining in libmenu and libform. + +961120 + + improve the use of the "const" qualifier in the + panel library (Juergen Pfeifer) + + change set_panel_userptr() and panel_userptr() to use void* + (Juergen Pfeifer) + +961119 + + change ABI to 3.4 + + package with 961119 version of Ada95 binding (fixes for gnat-3.07). + (Juergen Pfeifer) + + correct initialization of the stdscr pseudo panel in panel library + (Juergen Pfeifer) + + use MODULE_ID (rcs keywords) in forms and menus libraries (Juergen + Pfeifer). + > patch #324 by Eric. + + typo in curs_termcap man page (reported by Hendrik Reichel + <106065.2344@compuserve.com>) + + change default xterm entry to xterm-r6. + + add entry for color_xterm + +961116 - snapshot + + lint found several functions that had only #define implementations + (e.g., attr_off), modified curses.h.in to generate them as per XSI + Curses requirement that every macro be available as a function. + + add check in infocmp.c to guard against string compare of + CANCELLED_STRING values. + + modify firework.c, rain.c to hide cursor while running. + + correct missing va_end in lib_tparm.c + + modify hanoi.c to work on non-color terminals, and to use timing + delays when in autoplay mode. + + correct 'echochar()' to refresh immediately (reported by Adrian + Garside 94ajg2@eng.cam.ac.uk) + > patch #322 by eric: + + reorganize terminfo.src entries for xterm. + +961109 - snapshot + + corrected error in line-breakout logic (lib_doupdate.c) + + modified newdemo to use wgetch(win) rather than getch() to eliminate + a spurious clear-screen. + + corrected ifdef's for 'poll()' configuration. + + added modules to ncurses, form, menu for Ada95 binding (Juergen + Pfeifer). + + modify set_field_buffer() to allow assignment of string longer than + the initial buffer length, and to return the complete string rather + than only the initial size (Juergen Pfeifer and Per Foreby + ). + +961102 - snapshot + + configure for 'poll()' in preference to 'select()', since older + systems are more likely to have a broken 'select()'. + + modified render_char() to avoid OR'ing colors. + + minor fixes to testcurs.c, newdemo.c test programs: ifdef'd out the + resize test, use wbkgd and corrected box() parameters. + + make flushinp() test work in ncurses.c by using napms() instead of + sleep(). + + undo Eric's changes to xterm-x11r6 (it no longer matched the X11R6.1 + distribution, as stated) + + terminfo 9.13.18 (resync by Eric) + + check for getenv("HOME") returning null (Eric). + + change buffer used to decode xterm-mouse commands to unsigned to + handle displays wider than 128 chars (Juergen Pfeifer). + + correct typo curs_outopts.3x (Juergen Pfeifer). + + correct limit-checking in wenclose() (Juergen Pfeifer). + + correction to Peter Wemm's newwin change (Thomas Fehr ). + + corrections to logic that combines colors and attributes; they must + not be OR'd (Juergen Pfeifer, extending from report/patch by Rick + Marshall). + +961026 - snapshot + + reset flags in 'getwin()' that might cause refresh to attempt to + manipulate the non-existent parent of a window that is read from a + file (lib_screen.c). + + restructure _nc_timed_wait() to log more information, and to try to + recover from badly-behaved 'select()' calls (still testing this). + + move define for GOOD_SELECT into configure script. + + corrected extra '\' character inserted before ',' in comp_scan.c + + corrected expansion of %-format characters in dump_entry.c; some were + rendered as octal constants. + + modify dump_entry.c to make terminfo output more readable and like + SVr4, by using "\s" for spaces (leading/trailing only), "\," for + comma, "\^" and "\:" as well. + + corrected some memory leaks in ncurses.c, and a minor logic error + in the top-level command-parser. + + correction for label format 4 (PC style with info line), a + slk_clear(), slk_restore() sequence didn't redraw the info line + (Juergen Pfeifer). + + modified the slk window (if simulated) to inherit the background and + default character attributes from stdscr (Juergen Pfeifer). + + corrected limit-check in set_top_row (Juergen Pfeifer). + +961019 - snapshot + + correct loop-limit in wnoutrefresh(), bug exposed during pipe-testing + had '.lastchar' entry one beyond '._maxx'. + + modify ncurses test-program to work with data piped to it. + + corrected pathname computation in run_tic.sh, removing extra "../" + (reported by Tim Mooney). + + modified configure script to use previous install's location for + curses.h + + added NetBSD and FreeBSD to platforms that use --prefix=/usr as + a default. + +961013 + + revised xterm terminfo descriptions to reflect the several versions + that are available. + + corrected a pointer reference in dump_entry.c that didn't test if + the pointer was -1. + +961005 - snapshot + + correct _nc_mvcur_scrolln for terminals w/o scrolling region. + + add -x option to hashtest to control whether it allows writes to the + lower-right corner. + + ifdef'd (NCURSES_TEST) the logic for _nc_optimize_enable to make it + simpler to construct tests (for double-check of _nc_hash_map tests). + + correct ifdef's for c++ in curses.h + + change default xterm type to xterm-x11r6. + + correct quoting in configure that made man-pages installed with + $datadir instead of actual terminfo path. + + correct whitespace in include/Caps, which caused kf11, clr_eol and + clr_end to be omitted from terminfo.5 + + fix memory leaks in delscreen() (adapted from Alexander Lukyanov). + + improve appearance of marker in multi-selection menu (Juergen + Pfeifer) + + fix behaviour for forms with all fields inactive (Juergen + Pfeifer) + + document 'field_index()' (Juergen Pfeifer) + > patch #321 by eric: + + add some more XENIX keycap translations to include/Caps. + + modify newwin to set initial state of each line to 'touched' + (from patch by Peter Wemm ) + + in SET_TTY, replace TCSANOW with TCSADRAIN (Alexander Lukyanov). + +960928 - snapshot + + ifdef'd out _nc_hash_map (still slower) + + add graphic characters to vt52 description. + + use PutAttrChar in ClrToEOL to ensure proper background, position. + + simplify/correct logic in 'mvcur()' that does wrapping; it was + updating the position w/o actually moving the cursor, which broke + relative moves. + + ensure that 'doupdate()' sets the .oldindex values back to a sane + state; this was causing a spurious refresh in ncurses 'r'. + + add logic to configure (from vile) to guard against builders who + don't remove config.cache & config.status when doing new builds. + + corrected logic for 'repeat_char' in EmitRange (from #317), which + did not follow the 2-parameter scheme specified in XSI. + + corrected logic of wrefresh, wnoutrefresh broken in #319, making + clearok work properly (from report by Michael Elkins). + + corrected problem with endwin introduced by #314 (removing the + scrolling-region reset) that broke ncurses.c tests. + + corrected order of args in AC_CHECK_LIB (from report by Ami Fischman + ). + + corrected formatting of terminfo.5 tables (Juergen Ehling) + > patch 320 by eric: + + change ABI to 3.3 + + emit a carriage-return in 'endwin()' to workaround a kernel bug in + BSDI. (requested by Mike Karels ) + + reverse the default o configure --enable-termcap (consensus). + > patch 319 by eric: + + modified logic for clearok and related functions (from report by + Michael Elkins) - untested + > patch 318 by eric: + + correction to #317. + > patch 317 by eric: + + re-add _nc_hash_map + + modify EmitRange to maintain position as per original design. + + add hashtest.c, program to time the hashmap optimization. + > patch 316 by eric: + + add logic to deal with magic-cookie (how was this tested?) + (lib_doupdate.c). + + add ncurses.c driver for magic-cookie, some fixes to ncurses.c + > patch 315 by eric: + + merged A. Lukyanov's patch to use ech and rep - untested + (lib_doupdate.c). + + modified handling of interrupted system calls - untested + (lib_getch.c, lib_twait.c). + + new function _nc_mvcur_resume() + + fix return value for 'overlay()', 'overwrite()' + +960914 - snapshot + + implement subwindow-logic in wresize, minor fixes to ncurses 'g' + test. + + corrected bracketing of fallback.c (reported/suggested fix by Juergen + Ehling ). + + update xterm-color to reflect XFree86 3.1.3G release. + + correct broken dtterm description from #314 patch (e.g., spurious + newline. The 'pairs' change might work, but no one's tested it + either ;-) + + clarify the documentation for the builtin form fieldtypes (Juergen + Pfeifer) + > patch 314 by eric: + + Enhancement suggested by A. Lukyanov -- reset scroll region on + startup rather than at wrapup time. + + Fix suggested by A. Lukyanov, make storage of palette tables + and their size counts per-screen for multi-terminal applications. + + Improved error reporting for infotocap translation errors. + + Update terminfo.src to 9.13.14. + +960907 - snapshot + + rewrote wgetstr to make it erase control chars and also fix bogus use + of _nc_outstr which caused the display to not wrap properly (display + problem reported by John M. Flinchbaugh ) + + modify ncurses 'f' test to accommodate terminal responses to C1 codes + (and split up this screen to accommodate non-ANSI terminals). + + test enter_insert_mode and exit_insert_mode in has_ic(). + + removed bogus logic in mvcur that assumes nl/nonl set output modes + (XSI says they are input modes; SVr4 implements this). + + added macros SET_TTY, GET_TTY to term.h + + correct getstr() logic that altered terminal modes w/o restoring. + + disable ICRNL, etc., during initialization to match SVr4, removing + the corresponding logic from raw, cbreak, etc. + + disable ONLCR during initialization, to match SVr4 (this is needed + for cursor optimization when the cursor-down is a newline). + + replaced Eric's imitation of wresize with my original (his didn't + work). + +960831 - snapshot + + memory leaks (Alexander V. Lukyanov). + + modified pnoutrefresh() to be more tolerant of too-large screen + size (reported by Michael Elkins). + + correct handling of terminfo files with no strings (Philippe De + Muyter) + + correct "tic -s" to take into account -I, -C options. + + modify ncurses 'f' test to not print codes 80 through 9F, since they + are considered control codes by ANSI terminals. + +960824 - snapshot + + correct speed variable-type in 'tgetent()' (reported by Peter Wemm) + + make "--enable-getcap" configuration-option work (reported by + Peter Wemm ) + +960820 + + correct err in 960817 that changed return-value of tigetflag() + (reported by Alexander V. Lukyanov). + + modify infocmp to use library default search-path for terminfo + directory (Alexander V. Lukyanov). + +960817 - snapshot + + corrected an err in mvcur that broke resizing-behavior. + + correct fall-thru behavior of _nc_read_entry(), which was not finding + descriptions that existed in directories past the first one searched + (reported by Alexander V. Lukyanov) + + corrected typo in dtterm description. + > patch 313 by eric: + + add dtterm description + + clarify ncurses 'i' test (drop vscanf subtest) + +960810 - snapshot + + correct nl()/nonl() to work as per SVr4 & XSI. + + minor fixes to ncurses.c (use 'noraw()', mvscanw return-code) + + refine configure-test for -g option (Tim Mooney). + + correct interaction between O_BLANK and NEW_LINE request in form + library (Juergen Pfeifer) + +960804 + + revised fix to tparm; previous fix reversed parameter order. + > patch 312 by eric: + correct terminfo.src corrupted by #310 + > patch 311 by eric: + + fix idlok() and idcok() and the default of the idlok switch. + +960803 - snapshot + + corrected tparm to handle capability strings without explicit pop + (reported by William P Setzer) + + add fallback def for GCC_NORETURN, GCC_UNUSED for termcap users + (reported by Tim Mooney). + > patch 310 by eric: + + documentation and prototyping errors for has_color, immedok and idcok + (reported by William P Setzer ) + + updated qnx terminfo entry (by Michael Hunter) + +960730 + + eliminate quoted includes in ncurses subdirectory, ensure config.h + is included first. + + newterm initializes terminal settings the same as initscr (reported + by Tim Mooney). + +960727 - snapshot + + call cbreak() in initscr(), as per XSI & SVr4. + + turn off hardware echo in initscr() as per XSI & SVr4 + > patch 309 by eric: + + terminfo changes (9.3.10), from BRL + + add more checks to terminfo parser. + + add more symbols to infocmp. + +960720 - snapshot + + save previous-attribute in lib_vidattr.c if SP is null (reported by + Ju"rgen Fluk ) + + corrected calls on _nc_render so that background character is set + as per XSI. + + corrected wbkgdset macro (XSI allows background character to be null), + and tests that use it. + + more corrections to terminfo (xterm & rxvt) + + undid change to mcprint prototype (cannot use size_t in curses.h + because not all systems declare it in the headers that we can safely + include therein). + + move the ifdefs for errno into curses.priv.h + > patch 308 by eric: + + terminfo changes (9.3.8) + + modified logic of error-reporting in terminfo parser + +960713 - snapshot + + always check for since ISC needs it to declare + fd_set (Juergen Pfeifer) + + install shared-libraries on NetBSD/FreeBSD with ABI-version (reported + by several people: Juergen Pfeifer, Mike Long) + + add LOCAL_LDFLAGS2 symbol (Juergen Pfeifer) + + corrected prototype for delay_output() -- bump ABI to 3.2 + + terminfo patches #306/307 from Eric. + + moved logic that filters out rmul and rmso from setupterm to newterm + where it is less likely to interfere with termcap applications. + +960707 + + rollback Eric's #305 change to terminfo.src (it breaks existing + applications, e.g., 'less 290'). + + correct path of edit_man.sh, and fix typo that made all man-pages + preformatted. + + restore man/menu_requestname.3x omitted in Zeyd's resync (oops). + + auto-configure the GCC_PRINTFLIKE/GCC_SCANFLIKE macros (reported by + Philippe De Muyter). + +960706 - snapshot + + make lib_vidattr.c more readable using macros. + + filter out rmul, rmso that conflict with sgr0 when reading terminal + descriptions. + + added sanity-checking of various paired string attributes (Eric). + + work around autoconf bug, force $INSTALL to absolute path. + (reported by Zeyd). + + modify man-page install for BSDI to install preformatted .0 files + (reported by David MacKenzie). + + add/use gcc __attribute__ for printf and scanf in curses.h + + added SGR attributes test-case to ncurses + + revised ncurses 't' logic to show trace-disable effect in the menu. + + use getopt in ncurses program to process -s and -t options. + + make ncurses 'p' legend toggle with '?' + + disable scrollok during the ncurses 'p' test; if it is enabled the + stdscr will scroll when putting the box-corners in the lower-right + of the screen. + +960629 - snapshot + + check return code of _nc_mvcur_scrolln() in _nc_scroll_optimize() for + terminals with no scrolling-support (reported by Nikolay Shadrin + ) + + added ^S scrollok-toggle to ncurses 'g' test. + + added ^T trace-toggle to ncurses tests. + + modified ncurses test program to use ^Q or ESC consistently for + terminating tests (rather than ^D), and to use control keys rather + than function keys in 'g' test. + + corrected misplaced wclrtoeol calls in addch to accommodate wrapping + (reported by Philippe De Muyter). + + modify lib_doupdate.c to use effective costs to tradeoff between + delete-character/insert-character vs normal updating (reported by + David MacKenzie). + + compute effective costs for screen update operations (e.g., clr_eos, + delete_character). + + corrected error in knight.c exposed by wrap fixes in 960622; the + msgwin needed scrollok set. + + corrected last change to IDcTransformLine logic to avoid conflict + between PutRange and InsStr + + modified run_tic.sh to not use /usr/tmp (reported by David MacKenzie), + and further revised it and aclocal.m4 to use $TMPDIR if set. + + corrected off-by-one in RoomFor call in read_entry.c + +960622 - snapshot + + modified logic that wraps cursor in addch to follow the XSI spec, + (implemented in SVr4) which states that the cursor position is + updated when wrapping. Renamed _NEED_WRAP to _WRAPPED to reflect the + actual semantics. + + added -s option to tic, to provide better diagnostics in run_tic.sh + + improved error-recovery for tabset install. + + change ABI to 3.1 (dropped tparam, corrected getbkgd(), added + _yoffset to WINDOW). + + modified initialization of SP->_ofp so that init_acs() is called with + the "right" file pointer (reported by Rick Marshall + + documentation fixes (Juergen Pfeifer). + + corrected, using new SCREEN and WINDOW members, the behavior of + ncurses if one uses ripoffline() to remove a line from the top of the + screen (Juergen Pfeifer). + + modified autoconf scripts to prepare for Ada95 (GNAT) binding to + ncurses (Juergen Pfeifer). + + incorrect buffer-size in _nc_read_entry, reported by Eric Raymond. + +960617 + + corrected two logic errors in read_entry.c, write_entry.c (called by + tic, the write/read of terminfo entries used inconsistent rules for + locating the entries; the $TERMINFO_DIRS code would find only the + first entry in a list). + + refined pathname computation in run_tic.sh and shlib. + + corrected initialization of $IP in misc/run_tic.sh + +960615 - snapshot + + ifdef'd out _nc_hash_map() call because it does not improve speed. + + display version of gcc if configure script identifies it. + + modify configure script to use /usr as Linux's default prefix. + + modify run_tic.sh to use shlib script, fixes some problems installing + with a shared-library configuration. + + adjusted configure script so that it doesn't run tests with the + warnings turned on, which makes config.log hard to read. + + added 'lint' rule to top-level Makefile. + + added configure option '--with-install-prefix' for use by system + builders to install into staging locations (from request by + charles@comm.polymtl.ca) + + corrected autoconfigure for Debian man program; it's not installed + as "man_db". + + set noecho in 'worm'; it was ifdef'd for debug only + + updated test/configure.in for timing-display in ncurses 'p' test + + corrected misspelled 'getbkgd()'. + + corrected wbkgdset to work like observed syvr4 (sets A_CHARTEXT part + to blank if no character given, copies attributes to window's + attributes). + + modified lib_doupdate.c to use lower-level SP's current_attr state + instead of curscr's state, since it is redundant. + + correction to IDcTransformLine logic which controls where InsStr is + invoked (refined by lav@yars.free.net). + > patches 303 by eric + + conditionally include Chris Torek's hash function _nc_hash_map(). + + better fix for nvi refresh-bug (Rick Marshall) + + fix for bug in handling of interrupted keystroke waits, + (Werner Fleck). + +960601 - snapshot + + auto-configure man-page compression-format and renames for Debian. + + corrected several typos in curses.h.in (i.e., the mvXXXX macros). + + re-order curses.priv.h for lint. + + added rules for lintlib, lint + + corrected ifdef for BROKEN_LINKER in MKnames.awk.in + + corrected missing INSTALL_DATA in misc/Makefile.in + + flush output when changing cursor-visibility (Rick Marshall) + + fix a minor bug in the _nc_ripoff() routine and improve error checking + when creating the label window (Juergen Pfeifer). + + enhancement to the control over the new PC-style soft key format. + allow caller now to select whether or not one wants to have + the index-line; see curs_slk.3x for documentation (Juergen Pfeifer). + + typos, don't use inline with -g (Philippe De Muyter) + + fixes for menus & wattr-, slk-functions (Juergen Pfeifer) + +960526 - snapshot + + removed --with-ticdir option altogether, maintain compatibility with + existing applications via symbolic link in run_tic.sh + + patch for termio.h, signal (Philippe De Muyter) + + auto-configure gcc warning options rather than infer from version. + + auto-configure __attribute__ for different gcc versions. + + corrected special use of clearok() in hardscroll.c by resetting flag + in wrefresh(). + + include stdlib.h before defs for EXIT_SUCCESS, for OSF/1. + + include sys/types.h in case stdlib.h does not declare size_t. + + fixes for makefile (Tim Mooney) + + fixes for menus & forms (Juergen.Pfeifer@T-Online.de) + +960518 - snapshot + + revised ncurses.c panner test, let pad abut all 4 sides of screen. + + refined case in lib_doupdate.c for ClrToEOL(). + + corrected prior change for PutRange (Alexander V. Lukyanov: + lav@yars.free.net). + + autoconf mods (Tim Mooney: mooney@dogbert.cc.ndsu.NoDak.edu). + + locale fix for forms (Philippe De Muyter: phdemuyt@ulb.ac.be) + + renamed "--with-datadir" option to "--with-ticdir" to avoid + confusion, and made this check for the /usr/lib/terminfo pre-existing + directory. + > patches 299-301 by eric: + + added hashmap.c + + mods to tracing, especially for ACS chars. + + corrected off-by-one in IDCtransform. + + corrected intermittent mouse bug by using return-value from read(). + + mods to parse_entry.c, for smarter defaults. + +960512 + + use getopt in 'tic'; added -L option and modified -e option to allow + list from a file. + +960511 + + don't use fixed buffer-size in tparm(). + + modified tic to create terminfo directory if it doesn't exist. + + added -T options to tic and infocmp (for testing/analysis) + + refined the length criteria for termcap and terminfo + + optimize lib_doupdate with memcpy, PutRange + > patches 297, 298 by eric + + implement TERMINFO_DIRS, and -o option of tic + + added TRACE_IEVENT + + removed boolean version of 'getm' + + added lib_print.c (for Rick Marshall) + + added has_key() + + added 't' to ncurses.c test. + + moved delay_output() to lib_tputs.c + + removed tparam(). + + misc cursor & optimization fixes. + +960504 - snapshot + + modified ncurses 'p' test to allow full-screen range for panner size. + + fixes for locale (phdm@labauto1.ulb.ac.be) + + don't use fixed buffer-size in fmt_entry(). + + added usage-message to 'infocmp'. + + modified install.includes rules to prepend subdirectory-name to + "#include" if needed. + +960430 + + protect wrefresh, wnoutrefresh from invocation with pad argument. + + corrected default CCFLAGS in test/Makefile. + +960428 - snapshot + + implemented logic to support terminals with background color erase + (e.g., rxvt and the newer color xterm). + + improved screen update logic (off-by-one logic error; use clr_eos if + possible) + +960426 - snapshot + + change ncurses 'a' test to run in raw mode. + + make TIOCGWINSZ configure test less stringent, in case user + configures via terminal that cannot get screen size. + > patches 295, 296 by eric: + + new "-e" option of tic. + + fix for "infocmp -e". + + restore working-directory in read_termcap.c + + split lib_kernel.c, lib_setup.c and names.c in order to reduce + overhead for programs that use only termcap features. + +960418 - snapshot + + use autoconf 2.9 + + fix for AIX 3.2.5 (must define _POSIX_SOURCE to get termios struct + definitions via , modified macros in lib_raw.c to avoid + K&R-style substitution) + > patches 293, 294 by eric: + + mods to wgetch() in cooked mode + + corrected askuser() logic in tset + + correct interaction of endwin() with mouse processing + + added trace support for TTY flags + +960406 + + fixes for NeXT, ISC and HPUX auto-configure + + autogenerate development header-dependencies (config.h, *.priv.h) + + corrected single-column formatting of "use=" (e.g., in tic) + + modify tic to read full terminfo-names + + corrected divide-by-zero that caused hang (or worse) when redirecting output + + modify tic to generate directories only as-needed (and corrected + instance of use of data from function that had already returned). + +### ncurses-1.9.8a -> 1.9.9e + +* fixed broken wsyncup()/wysncdown(), as a result wnoutrefresh() now has + copy-changed-lines behavior. +* added and documented wresize() function. +* more fixes to LOWER-RIGHT corner handling. +* changed the line-breakout optimization code to allow some lines to be + emitted before the first check. +* added option for tic to use symbolic instead of hard links (for AFS) +* fix to restore auto-wrap mode. +* trace level can be controlled by environment variable. +* better handling of NULs in terminal descriptions. +* improved compatibility with observed SVR4 behavior. +* the refresh behavior of over-lapping windows is now more efficient and + behaves like SVR4. +* use autoconf 2.7, which results in a working setup for SCO 5.0. +* support for ESCDELAY. +* small fixes for menu/form code. +* the test directory has its own configure. +* fixes to pads when optimizing scrolling. +* fixed several off-by-one bugs. +* fixes for termcap->terminfo translation; less restrictions more correct + behavior. + +### ncurses-1.9.7 -> 1.9.8a + +* teach infocmp -i to recognize ECMA highlight sequences +* infocmp now dumps all SVr4 termcaps (not just the SVr4 ones) on -C +* support infocmp -RBSD. +* satisfy XSI Curses requirement that every macro be available as a function. +* This represents the last big change to the public interface of ncurses. The + ABI_VERSION has now been set at 3.0 and should stay there barring any great + catastrophies or acts of God. +* The C++ has been cleaned up in reaction to the changes to satisfy XSI's + requirements. +* libncurses now gets linked to libcurses to help seamless emulation + (replacement) of a vendor's curses. --disable-overwrite turns this behavior + off. + +### ncurses-1.9.6 -> 1.9.7 + +* corrected return values of setupterm() +* Fixed some bugs in tput (it does padding now) +* fixed a bug in tic that made it do the wrong thing on entries with more than + one `use' capability. +* corrected the screen-size calculation at startup time to alter the + numeric capabilities as per SVr4, not just LINES and COLS. +* toe(1) introduced; does what infocmp -T used to. +* tic(1) can now translate AIX box1 and font[0123] capabilities. +* tic uses much less core, the dotic.sh kluge can go away now. +* fix read_entry() and write_entry() to pass through cancelled capabilities OK. +* Add $HOME/.terminfo as source/target directory for terminfo entries. +* termcap compilation now automatically dumps an entry to $HOME/.terminfo. +* added -h option to toe(1). +* added -R option to tic(1) and infocmp(1). +* added fallback-entry-list feature. +* added -i option to infocmp(1). +* do a better job at detecting if we're on SCO. + +### ncurses-1.9.5 -> 1.9.6 + +* handling of TERMCAP environment variables now works correctly. +* various changes to shorten termcap translations to less that 1024 chars. +* tset(1) added +* mouse support for xterm. +* most data tables are now const and accordingly live in shareable text space. +* Obey the XPG4/SVr4 practice that echo() is initally off. +* tic is much better at translating XENIX and AIX termcap entries now. +* tic can interpret ko capabilities now. +* integrated Juergen Pfeifer's forms library. +* taught write_entry() how not to write more than it needs to; this change + reduces the size of the terminfo tree by a full 26%! +* infocmp -T option added. +* better warnings about historical tic quirks from tic. + +### ncurses 1.9.4 -> 1.9.5 + +* menus library is now included with documentation. +* lib_mvcur has been carefully profiled and tuned. +* Fixed a ^Z-handling bug that was tanking lynx(1). +* HJ Lu's patches for ELF shared libraries under Linux +* terminfo.src 9.8.2 +* tweaks for compiling in seperate directories. +* Thomas Dickey's patches to support NeXT's brain-dead linker +* Eric Raymond's patches to fix problems with long termcap entries. +* more support for shared libraries under SunOS and IRIX. + +### ncurses 1.9.3 -> 1.9.4 + +* fixed an undefined-order-of-evaluation bug in lib_acs.c +* systematically gave non-API public functions and data an _nc_ prefix. +* integrated Juergen Pfeifer's menu code into the distribution. +* totally rewrote the knight test game's interface + +### ncurses 1.9.2c -> 1.9.3 + +* fixed the TERMCAP_FILE Support. +* fixed off-by-one errors in scrolling code +* added tracemunch to the test tools +* took steps to cut the running time of make install.data + +### ncurses 1.9.2c -> 1.9.2d + +* revised 'configure' script to produce libraries for normal, debug, + profile and shared object models. + +### ncurses 1.9.1 -> 1.9.2 + +* use 'autoconf' to implement 'configure' script. +* panels support added +* tic now checks for excessively long termcap entries when doing translation +* first cut at eliminating namespace pollution. + +### ncurses 1.8.9 -> 1.9 + +* cleanup gcc warnings for the following: use size_t where 'int' is not + appropriate, fixed some shadowed variables, change attr_t to compatible with + chtype, use attr_t in some places where it was confused with 'int'. +* use chtype/attr_t casts as appropriate to ensure portability of masking + operations. +* added-back waddchnstr() to lib_addstr.c (it had been deleted). +* supplied missing prototypes in curses.h +* include in lib_termcap.c to ensure that the prototypes + are consistent (they weren't). +* corrected prototype of tputs in +* rewrote varargs parsing in lib_tparm.c (to avoid referencing memory + that may be out of bounds on the stack) -- Purify found this. +* ensure that TRACE is defined in lib_trace.c (to solve prototype + warnings from gcc). +* corrected scrolling-region size in 'mvcur_wrap()' +* more spelling fixes +* use 'calloc()' to allocate WINDOW struct in lib_newwin.c (Purify). +* set default value for SP->_ofp in lib_set_term.c (otherwise SunOS dumps + core in init_acs()). +* include in write_entry.c (most "braindead" includes declare errno + in that file). + +### ncurses 1.8.8 -> 1.8.9 + +* compile (mostly) clean with gcc 2.5.8 -Wall -Wstrict-prototypes + -Wmissing-prototypes -Wconversion and using __attribute__ to flush out + non-portable use of "%x" for pointers, or for chtype data (which is declared + as a long). +* modified doupdate to ensure that typahead was turned on before attempting + select-call (otherwise, some implementations hang). +* added trace mask TRACE_FIFO, use this in lib_getch.c to allow finer + resolution of traces. +* improved bounds checking on several critical functions. +* the data directory has been replaced by the new master terminfo file. +* -F file-comparison option added to infocmp. +* compatibility with XSI Curses is now documented in the man bages. +* wsyncup/wsyncdown functions are reliable now; subwindow code in general + is much less flaky. +* capabilities ~msgr, tilde_glitch, insert_padding, generic_type, no_pad_char, + memory_above, memory_below, and hard_copy are now used properly. +* cursor-movement optimization has been completely rewritten. +* vertical-movement optimization now uses hardware scrolling, il, dl. + +### ncurses 1.8.7 -> 1.8.8 +* untic no longer exists, infocmp replaces it. +* tic can understand termcap now, especially if it is called captoinfo. +* The Linux Standard Console terminfo entry is called linux insead of console. + It also uses the kernel's new method of changing charsets. +* initscr() will EXIT upon error (as the docs say) This wil mostly happen if + you try to run on an undefined terminal. +* I can get things running on AIX but tic can't compile terminfo. I have to + compile entries on another machine. Volunteers to hunt this bug are welcome. +* wbkgd() and wbkgdset() can be used to set a windows background to color. + wclear()/werase() DO NOT use the current attribute to clear the screen. + This is the way SVR4 curses works. PDCurses 2.1 is broken in this respect, + though PDCurses 2.2 has been fixed. +* cleaned up the test/ directory. +* test/worm will segfault after quite a while. +* many spelling corrections courtesy of Thomas E. Dickey + +### ncurses 1.8.6 -> 1.8.7 +* cleaned up programs in test/ directory. +* fixed wbkgdset() macro. +* modified getstr() to stop it from advancing cursor in noecho mode. +* modified linux terminfo entry to work with the latest kernel to get + the correct alternate character set. +* also added a linux-mono entry for those running on monochrome screens. +* changed initscr() so that it behaves like the man page says it does. + this fixes the problem with programs in test/ crashing with SIGSEV if + a terminal is undefined. +* modified addch() to avoid using any term.h #define's +* removed duplicate tgoto() in lib_tparm.c +* modified dump_entry.c so that infocmp deals correctly with ',' in acsc +* modified delwin() to correctly handle deleting subwindows. +* fixed Makefile.dist to stop installing an empty curses.h +* fixed a couple of out-of-date notes in man pages. + +### ncurses 1.8.5 -> 1.8.6 +* Implemented wbkgd(), bkgd(), bkgdset(), and wbkgdset(). +* The handling of attributes has been improved and now does not turn off color + if other attributes are turned off. +* scrolling code is improved. Scrolling in subwindows is still broken. +* Fixes to several bugs that manifest them on platforms other than Linux. +* The default to meta now depends on the status of the terminal when ncurses + is started. +* The interface to the tracing facility has changed. Instead of the pair of + functions traceon() and traceoff(), there is just one function trace() which + takes a trace mask argument. The trace masks, defined in curses.h, are + as follows: + + #define TRACE_DISABLE 0x00 /* turn off tracing */ + #define TRACE_ORDINARY 0x01 /* ordinary trace mode */ + #define TRACE_CHARPUT 0x02 /* also trace all character outputs */ + #define TRACE_MAXIMUM 0x0f /* maximum trace level */ + + More trace masks may be added, or these may be changed, in future releases. +* The pad code has been improved and the pad test code in test/ncurses.c has + been improved. +* The prototype ansi entry has been changed to work with a wider variety + of emulators. +* Fix to the prototype ansi entry that enables it to work with PC emulators + that treat trailing ";m" in a highlight sequence as ";0m"; this doesn't + break operation with any emulators. +* There are now working infocmp, captoinfo, tput, and tclear utilities. +* tic can now compile entries in termcap syntax. +* Core-dump bug in pnoutrefresh fixed. +* We now recognize and compile all the nonstandard capabilities in Ross + Ridge's mytinfo package (rendering it obsolete). +* General cleanup and documentation improvements. +* Fixes and additions to the installation-documentation files. +* Take cursor to normal mode on endwin. + +### ncurses 1.8.4 -> 1.8.5 +* serious bugs in updating screen which caused erratic non-display, + fixed. +* fixed initialization for getch() related variable which cause + unpredictable results. +* fixed another doupdate bug which only appeared if you have + parm_char. +* implemented redrawln() and redrawwin(). +* implemented winsnstr() and related functions. +* cleaned up insertln() and deleteln() and implemented (w)insdeln(). +* changed Makefile.dist so that installation of man pages will + take note of the terminfo directory. +* fixed Configure (removed the mysterious 'X'). +* Eric S. Raymond fixed the script.* files so that they work with + stock awk. + +#### ncurses 1.8.3 -> 1.8.4 #### #### +* fixed bug in refreshing the screen after return from shell_mode. + There are still problems but they don't manifest themselves on + my machine (Linux 0.99.14f). +* added wgetnstr() and modified things accordingly. +* fixed the script.src script.test to work with awk not just gawk. +* Configure can now take an argument of the target system. +* added test/ncurses.c which replaces several other programs and + performs more testing. +[Thanks to Eric S Raymond for the last 4] +* more fixes to lib_overlay.c and added test/over.c to illustrate + how it works. +* fixed ungetch() to take int instead of ch. +* fixes to cure wgetch() if flushinp() is called. + +One note I forgot to mention in 1.8.3 is that tracing is off by +default starting in the version. If you want tracing output, put +traceon(); in your code and link with -ldcurses. + +#### ncurses 1.8.2 -> ncurses 1.8.3 #### #### +MAJOR CHANGES: +1) The order of capabilities has been changed in order to achieve +binary compatibility with SVR4 terminfo database. This has the +unfortunate effect of breaking application currently linked with +ncurses. To ensure correct behavior, recompile all such programs. +Most programs using color or newer capabilities will break, others +will probably continue to work ok. + +2) Pavel Curtis has renounced his copyright to the public domain. +This means that his original sources (posted to comp.sources.unix, +volume 1) are now in the public domain. The current sources are +NOT in the public domain, they are copyrighted by me. I'm +entertaining ideas on what the new terms ncurses is released under. + +3) Eric S. Raymond has supplied a complete set of man pages for +ncurses in ?roff format. They will eventually replace most of the +current docs. Both sets are included in this release. + +Other changes and notes from 1.8.2 include: +* SIGSEGV during scrolling no longer occurs. +* Other problems with scrolling and use of idl have been corrected. +* lib_getch.c has been re-written and should perform flawlessly. + please use test/getch.c and any other programs to test this. +* ripoffline() is implemented (Thanks to Eric) and slk_ functions + changed accordingly. +* I've added support for terminals that scroll if you write in the + bottom-right corner. +* fixed more bugs in pads code. If anybody has a program that uses + pads I'd love a copy. +* correct handling for terminal with back_color_erase capability + (such as Linux console, and most PC terminals) +* ^Z handling apparently didn't work (I should never trust code + sent me to me without extensive testing). It now seems to be + fixed. Let me know if you have problems. +* I've added support for Apollo and NeXT, but it may still be + incomplete, especially when dealing with the lack of POSIX + features. +* scrolling should be more efficient on terminals with idl + capabilities. Please see src/lib_scroll.c for more notes. +* The line drawing routines were offset by 1 at both ends. This + is now fixed. +* added a few missing prototypes and macros (e.g. setterm()) +* fixed code in src/lib_overlay.c which used to crash. +* added a few more programs in test/ The ones from the PDCurses + package are useful, especially if you have SVR4 proper. I'm + interested in the results you get on such a systems (Eric? ;-). + They already exposed certain bugs in ncurses. +* See src/README for porting notes. +* The C++ code should really replace ncurses.h instead of working + around it. It should avoid name-space clashes with nterm.h (use + rows instead of lines, etc.) +* The C++ should compile ok. I've added explicit rules to the + Makefile because no C++ defaults are documented on the suns. +* The docs say that echo() and nocbreak() are mutually exclusive. + At the moment ncurses will switch to cbreak() if the case above + occurs. Should it continue to do so? How about echo() and noraw()? +* PDCurses seem to assume that wclear() will use current attribute + when clearing the screen. According to Eric this is not the case + with SVR4. +* I have discovered, to my chagrin, SunOS 4.x (and probably other systems) + * doesn't have vsscanf and God knows what else! I've will do a vsscanf(). +* I've also found out that the src/script.* rely on gawk and will not + work with stock awk or even with nawk. Any changes are welcome. +* Linux is more tolerant of NULL dereferences than most systems. This + fact was exposed by hanoi. +* ncurses still seems inefficient in drawing the screen on a serial + link between Linux and suns. The padding may be the culprit. +* There seems to be one lingering problem with doupdate() after shelling + out. Despite the fact the it is sending out the correct information + to the terminal, nothing takes effect until you press ^L or another + refresh takes place. And yes, output does get flushed. + +#### ncurses 1.8.1 -> ncurses 1.8.2 #### Nov 28, 1993 #### + +* added support for SVR4 and BSDI's BSD/386. +* major update and fix to scrolling routine. +* MORE fixes to stuff in lib_getch.c. +* cleaned-up configuration options and can now generate + Config.* files through an awk script. +* changed setupterm() so it can be called more than once, + add added set_curterm(), del_curterm(). +* a few minor cleanups. +* added more prototypes in curses.h + +#### ncurses 1.8 -> ncurses 1.8.1 #### Nov 4, 1993 #### + +* added support for NeXTStep 3.0 +* added termcap emulation (not well tested). +* more complete C++ interface to ncurses. +* fixed overlay(), overwrite(), and added copywin(). +* a couple of bug fixes. +* a few code cleanups. + +#### ncurses 0.7.2/0.7.3 -> ncurses 1.8 #### Aug 31, 1993 #### + +* The annoying message "can't open file." was due to missing + terminfo entry for the used terminal. It has now been + replaced by a hopefully more helpful message. +* Problems with running on serial lines are now fixed. +* Added configuration files for SunOS, Linux, HP/UX, Ultrix, + 386bsd/BSDI (if you have others send'em to me) +* Cleaner Makefile. +* The documentation in manual.doc is now more uptodate. +* update optimization and support for hp terminals, and 386bsd + console driver(s). +* mvcur optimization for terminals without cursor addressing + (doesn't work on Linux) +* if cursor moved since last update, getch() will refresh the + screen before working. +* getch() & alarm() can now live together. in 0.7.3 a signal + interrupted getch() (bug or feature?) now the getch is + restarted. +* scanw() et all were sick, now fixed. +* support for 8-bit input (use meta()). +* added default screen size to all terminfos. +* added c++ Ncursesw class. +* several minor bug fixes. + +#### ncurses 0.7.2 -> ncurses 0.7.3 #### May 27, 1993 #### + +* Config file to cope with different platforms (386BSD, BSDI, Ultrix, SunOS) +* more fixes to lib_getch.c +* changes related to Config + +#### ncurses 0.7 -> ncurses 0.7.2 #### May 22, 1993 #### + +* docs updated slightly (color usage is now documented). +* yet another fix for getch(), this one fixes problems with ESC being swallowed + if another character is typed before the 1 second timeout. +* Hopefully, addstr() and addch() are 8-bit clean. +* fixed lib_tparm.c to use stdarg.h (should run on suns now) +* order of capabilities changed to reflect that specified in SYSV + this will allow for binary-compatibility with existing terminfo dbs. +* added halfdelay() +* fixed problems with asc_init() +* added A_PROTECT and A_INVIS +* cleaned up vidputs() +* general cleanup of the code +* more attention to portability to other systems +* added terminfos for hp70092 (wont work until changes to lib_update.c are + made) and 386BSD pcvt drivers. + +Thanks to Hellmuth Michaelis for his help. +optimization code is slated for the next major release, stay tuned! + +#### ncurses 0.6/0.61 -> ncurses 0.7 #### April 1, 1993 +Please note that the next release will be called 1.8. If you want to know about +the rationale drop me a line. + +Included are several test programs in test/. +I've split up the panels library, reversi, tetris, sokoban. They are now +available separately from netcom.com:pub/zmbenhal/ + +* color and ACS support is now fully compatible with SYSV at the terminfo + level. +* Capabilities now includes as many SYSV caps I could find. +* tigetflag,tigetnum,tigetstr functions added. +* boolnames, boolfnames, boolcodes numnames, numfnames, numcodes, + strnames, strfnames, strcodes arrays are now added. +* keyname() is added. +* All function keys can be defined in terminfo entries. +* fixed lin_tparm.c to behave properly. +* terminfo entries for vt* and xterm are included (improvements are welcome) +* more automation in handling caps and keys. +* included fixes from 0.6.1 +* added a few more missing functions. +* fixed a couple of minor bugs. +* updated docs JUST a little (still miles behind in documenting the newer + features). + +#### ncurses 0.6 -> ncurses 0.61 #### + +1) Included the missing data/console. + +2) allow attributes when drawing boxes. + +3) corrected usage of win->_delay value. + +4) fixed a bug in lib_getch.c. if it didn't recognize a sequence it would + simply return the last character in the sequence. The correct + behavior is to return the entire sequence one character at a time. + +#### ncurses0.5 -> ncurses0.6 #### March 1, 1993 #### +* removed _numchngd from struct _win_st and made appropriate changes. +* rewritten kgetch() to remove problems with interaction between alarm and + read(). It caused SIGSEGV every now and then. +* fixed a bug that miscounted the numbers of columns when updating. + (in lib_doupdate.c(ClrUpdate() -- iterate to columns not columns-1) +* fixed a bug that cause the lower-right corner to be incorrect. + (in lib_doupdate.c(putChar() -- check against columns not columns-1) +* made resize() and cleanup() static to lib_newterm.c +* added notimeout(). +* added timeout() define in curses.h +* added more function prototypes and fixed napms. +* added use_env(). +* moved screen size detection to lib_setup.c. +* fixed newterm() to confirm to prototype. +* removed SIGWINCH support as SYSV does not define its semantics. +* cleaned-up lib_touch.c +* added waddnstr() and relatives. +* added slk_* support. +* fixed a bug in wdeleteln(). +* added PANEL library. +* modified Makefile for smoother installation. +* terminfo.h is really term.h + +#### ncurses 0.4 -> ncurses 0.5 #### Feb 14, 1993 #### +* changed _win_st structure to allow support for missing functionality. +* Addition of terminfo support for all KEY_*. +* Support for nodelay(), timeout(), notimeout(). +* fixed a bug with the keypad char reading that did not return ESC until + another key is pressed. +* nl mapping no longer occur on output (as should be) + fixed bug '\n' no causing a LF. +* fixed bug that reset terminal colors regardless of whether we use color + or not. +* Better support for ACS (not quite complete). +* fixed bug in wvline(). +* added curs_set(). +* changed from signal() to sigaction(). +* re-included the contents of important.patch into source. + +#### ncurses 0.3 -> ncurses 0.4 #### Feb 3, 1993 #### +* Addition of more KEY_* definitions. +* Addition of function prototypes. +* Addition of several missing functions. +* No more crashes if screen size is undefined (use SIGWINCH handler). +* added a handler to cleanup after SIGSEGV (hopefully never needed). +* changed SRCDIR from /etc/term to /usr/lib/terminfo. +* renamed compile/dump to tic/untic. +* New scrolling code. +* fixed bug that reversed the sense of nl() and nonl(). + +#### ncurses 0.2 -> ncurses 0.3 #### Jan 20, 1993 #### +* more support for color and graphics see test/ for examples. +* fixed various files to allow correct update after shelling out. +* more fixes for updates. +* no more core dumps if you don't have a terminfo entry. +* support for LINES and COLUMNS environment variables. +* support for SIGWINCH signal. +* added a handler for SIGINT for clean exits. + +#### ncurses 0.1 -> ncurses 0.2 #### Aug 14, 1992 #### +* support for color. +* support for PC graphic characters. +* lib_trace.c updated to use stdarg.h and vprintf routines. +* added gdc.c (Great Digital Clock) as an example of using color. + +#### ncurses -> ncurses 0.1 #### Jul 31, 1992 #### +* replacing sgtty stuff by termios stuff. +* ANSIfication of some functions. +* Disabling cost analysis 'cause it's incorrect. +* A quick hack for a terminfo entry. diff --git a/ncurses-5.2/README b/ncurses-5.2/README new file mode 100644 index 0000000..52aa79d --- /dev/null +++ b/ncurses-5.2/README @@ -0,0 +1,175 @@ +-- $Id$ +------------------------------------------------------------------------------- + README file for the ncurses package + +See the file ANNOUNCE for a summary of ncurses features and ports. +See the file INSTALL for instructions on how to build and install ncurses. +See the file NEWS for a release history and bug-fix notes. +See the file TO-DO for things that still need doing, including known bugs. + +Browse the file misc/ncurses-intro.html for narrative descriptions of how +to use ncurses and the panel, menu, and form libraries. + +Browse the file doc/html/hackguide.html for a tour of the package internals. + +ROADMAP AND PACKAGE OVERVIEW: + +You should be reading this file in a directory called: ncurses-d.d, where d.d +is the current version number (see the dist.mk file in this directory for +that). There should be a number of subdirectories, including `c++', `form', +`man', `menu', `misc', `ncurses', `panel', `progs', `test', 'tack' and `Ada95'. +(The 'tack' program may be distributed separately). + +A full build/install of this package typically installs several libraries, a +handful of utilities, and a database hierarchy. Here is an inventory of the +pieces: + +The libraries are: + + libncurses.a (normal) + libncurses.so (shared) + libncurses_g.a (debug and trace code enabled) + libncurses_p.a (profiling enabled) + + libpanel.a (normal) + libpanel.so (shared) + libpanel_g.a (debug and trace code enabled) + + libmenu.a (normal) + libmenu.so (shared) + libmenu_g.a (debug enabled) + + libform.a (normal) + libform.so (shared) + libform_g.a (debug enabled) + +The ncurses libraries implement the curses API. The panel, menu and forms +libraries implement clones of the SVr4 panel, menu and forms APIs. The source +code for these lives in the `ncurses', `panel', `menu', and `form' directories +respectively. + +In the `c++' directory, you'll find code that defines an interface to the +curses, forms, menus and panels library packaged as C++ classes, and a demo program in C++ +to test it. These class definition modules are not installed by the 'make +install.libs' rule as libncurses++. + +In the `Ada95' directory, you'll find code and documentation for an +Ada95 binding of the curses API, to be used with the GNAT compiler. +This binding is built by a normal top-level `make' if configure detects +an usable version of GNAT (3.10 or above). It is not installed automatically. +See the Ada95 directory for more build and installation instructions and +for documentation of the binding. + +To do its job, the ncurses code needs your terminal type to be set in the +environment variable TERM (normally set by your OS; under UNIX, getty(1) +typically does this, but you can override it in your .profile); and, it needs a +database of terminal descriptions in which to look up your terminal type's +capabilities. + +In older (V7/BSD) versions of curses, the database was a flat text file, +/etc/termcap; in newer (USG/USL) versions, the database is a hierarchy of +fast-loading binary description blocks under /usr/lib/terminfo. These binary +blocks are compiled from an improved editable text representation called +`terminfo' format (documented in man/terminfo.5). The ncurses library can use +either /etc/termcap or the compiled binary terminfo blocks, but prefers the +second form. + +In the `misc' directory, there is a text file terminfo.src, in editable +terminfo format, which can be used to generate the terminfo binaries (that's +what make install.data does). If the package was built with the +--enable-termcap option enabled, and the ncurses library cannot find a terminfo +description for your terminal, it will fall back to the termcap file supplied +with your system (which the ncurses package installation leaves strictly +alone). + +The utilities are as follows: + + tic -- terminfo source to binary compiler + infocmp -- terminfo binary to source decompiler/comparator + clear -- emits clear-screen for current terminal + tput -- shell-script access to terminal capabilities. + toe -- table of entries utility + tset -- terminal-initialization utility + +The first two (tic and infocmp) are used for manipulating terminfo +descriptions; the next two (clear and tput) are for use in shell scripts. The +last (tset) is provided for 4.4BSD compatibility. The source code for all of +these lives in the `progs' directory. + +Detailed documentation for all libraries and utilities can be found in the +`man' and `doc' directories. An HTML introduction to ncurses, panels, and +menus programming lives in the `doc/html' directory. Manpages in HTML format +are under `doc/html/man'. + +The `test' directory contains programs that can be used to verify or +demonstrate the functions of the ncurses libraries. See test/README for +descriptions of these programs. Notably, the `ncurses' utility is designed to +help you systematically exercise the library functions. + +AUTHORS: + +Pavel Curtis: + wrote the original ncurses + +Zeyd M. Ben-Halim: + port of original to Linux and many enhancements. + +Thomas Dickey (maintainer for 1.9.9g through 4.1, resuming with FSF's 5.0): + configuration scripts, porting, mods to adhere to XSI Curses in the + areas of background color, terminal modes. Also memory leak testing, + the wresize, default colors and key definition extensions and numerous + bug fixes (more than half of those enumerated in NEWS beginning with + the internal release 1.8.9). + +Florian La Roche (official maintainer for FSF's ncurses 4.2) + Beginning with release 4.2, ncurses is distributed under an MIT-style + license. + +Eric S. Raymond: + the man pages, infocmp(1), tput(1), clear(1), captoinfo(1), tset(1), + toe(1), most of tic(1), trace levels, the HTML intro, wgetnstr() and + many other entry points, the cursor-movement optimization, the + scroll-pack optimizer for vertical motions, the mouse interface and + xterm mouse support, and the ncurses test program. + +Juergen Pfeifer + The menu and form libraries, C++ bindings for ncurses, menus, forms and + panels, as well as the Ada95 binding. Ongoing support for panel. + +CONTRIBUTORS: + +Alexander V. Lukyanov + for numerous fixes and improvements to the optimization logic. + +David MacKenzie + for first-class bug-chasing and methodical testing. + +Ross Ridge + for the code that hacks termcap parameterized strings into terminfo. + +Warren Tucker and Gerhard Fuernkranz, + for writing and sending the panel library. + +Hellmuth Michaelis, + for many patches and testing the optimization code. + +Eric Newton, Ulrich Drepper, and Anatoly Ivasyuk: + the C++ code. + +Jonathan Ross, + for lessons in using sed. + +Keith Bostic (maintainer of 4.4BSD curses) + for help, criticism, comments, bug-finding, and being willing to + deep-six BSD curses for this one when it grew up. + +Richard Stallman, + for his commitment to making ncurses free software. + +Countless other people have contributed by reporting bugs, sending fixes, +suggesting improvements, and generally whining about ncurses :-) + +BUGS: + See the INSTALL file for bug and developer-list addresses. + The Hacker's Guide in the doc directory includes some guidelines + on how to report bugs in ways that will get them fixed most quickly. diff --git a/ncurses-5.2/README.emx b/ncurses-5.2/README.emx new file mode 100644 index 0000000..7285130 --- /dev/null +++ b/ncurses-5.2/README.emx @@ -0,0 +1,45 @@ +-- $Id$ +-- Author: Thomas Dickey +------------------------------------------------------------------------------- + +You can build ncurses on OS/2 in the EMX environment. But you must build and +acquire tools. Not all of the tools distributed with EMX work properly, and +some additional ones are required. + +First, the configure script distributed with ncurses will not run as-is in EMX. +You can generate a new one if you have autoconf built for EMX. You will need +the EMX development tools, of course. Get these programs to start: + + GNU m4 program (version 1.4) + GNU autoconf (version 2.13). + GNU patch (version 2.5) + +Apply the autoconf patches from + + http://dickey.his.com/autoconf + ftp://dickey.his.com/autoconf + +These are ordered by date: + + autoconf-2.13-20000819.patch.gz + autoconf-2.13-20000819-emx.patch.gz + +I built my development environment for ncurses using EMX 0.9c at the end of +1997. Much of the EMX patch for autoconf was done originally by J.J.G.Ripoll, +using a similar environment (he prefers using the 'ash' shell). Newer versions +may fix these problems: + + + The pdksh program distributed at Hobbes and Leo (with a 1996 date) is + defective. It does not process "here documents" correctly (which + renders it useless for running the autoconf script). I built my own + copy of pdksh 5.2.13, which does have the bug corrected (documented + in the change log for pdksh). + + + I also built from sources (because the distributed binaries did not + work) the cmp, diff programs. + + Other required utilities such as ar, cat, chmod, cp, gawk, grep, mv, + ls, rm, mkdir, sed, sort and tr worked. + +Once you have autoconf patched and installed, run 'autoconf' from the top-level +directory of ncurses to generate the EMX-specific configure script. diff --git a/ncurses-5.2/README.glibc b/ncurses-5.2/README.glibc new file mode 100644 index 0000000..7d52269 --- /dev/null +++ b/ncurses-5.2/README.glibc @@ -0,0 +1,5 @@ +To compile this as an add-on for glibc, unpack it in the glibc source +tree and put ncurses on the add-on list when you do configure. + +hjl@gnu.ai.mit.edu +03/21/1997 diff --git a/ncurses-5.2/TO-DO b/ncurses-5.2/TO-DO new file mode 100644 index 0000000..7465e6f --- /dev/null +++ b/ncurses-5.2/TO-DO @@ -0,0 +1,251 @@ +-- $Id$ + +SHORT-TERM TO-DO ITEMS: + +Known Problems: + +* GNAT does not put libraries in the correct order, so a build only links + properly if you use shared libraries since -lncurses is first. + +* XPG4 specifies that the enhanced features are not available unless the + _XOPEN_SOURCE_EXTENDED test macro is defined by the application. Ncurses uses + this macro (incorrectly) to address a dependency upon wchar_t. The functions + which use wchar_t are not implemented, so the effect of the test macro is + pointless. + +* The screen optimization has been tested only in an ad hoc manner. We should + develop a good set of regression tests to cover lib_doupdate.c and + lib_mvcur.c. + +* Magic cookie support does not work, since the logic does not take into account + refresh. Also, the initial optimize does not adjust the current location + when a cookie is emitted. + +* Scrolling optimization has holes: for example, it forces repaints of the + screen between calls to refresh(). + +* SVr4 uses slightly different rules for determining when softkeys are shown. + For example, they are initially displayed (before the ncurses 'e' test + activates them), and a touchwin can apparently also force them to be + displayed. + ++ The code departs from perfect 8-bit cleanness in one respect; you cannot + specify a character \200 as part of a capability string, because the terminfo + library interprets \200 as a request to embed NUL (\000) at that point. This + is a legacy terminfo property we can't mess with. + +* The window classes defined in the c++ subdirectory need documentation. + Some C++ programmer could earn a lot of good karma by doing this... + +Portability (or lack thereof): + +* Users of older System V UNIXes (but not Solaris, and probably not SVr4) + may trip over a known problem with the signal-handling code which causes + abrupt termination of ncurses applications following resume from a ^Z + suspend (this problem was first seen running lynx). You will not see + this problem if you are running Linux or one of the 4.4BSD derivatives + like FreeBSD, NetBSD, or BSDI. For details, see the analysis in the + header comment of ncurses/lib_tstp.c. + +* In theory, vwprintw and vwscanf are supposed to use the older varargs.h + interface for handling variadic argument lists. Linux doesn't have + varargs.h, it has the newer X/Open-standard stdargs.h equivalent. So + these functions use stdargs instead. This is unlikely to be a problem + unless you're building ncurses on a System V old enough to only have + varargs.h. (Solaris 2.5.1 uses the stdarg.h binding as well). + +* If you're using a BSD earlier than 4.4BSD, or a Linux old enough not to + have a native vsscanf(3) in its library, vwscanw() will not work. You lose. + (It should work on any System V, however). If you want to fix this, add + an implementation to ncurses/vsscanf.c. + +* The demo build for the c++ library craps out with many link errors under gcc + 2.6.3. We're told the C++ support in 2.6.3 is broken and that the right + fix is to upgrade to 2.7.0. This demo is also known to not build with + the Sun SPARCworks 4.1 C++ compiler, due to a problem resolving templates. + +* Under Ultrix, configure craps out (Ultrix sh is lame). Run it under ksh. + +* We've not tested the configure script with cross-compilers. The autoconf + tests are supposed to be able to support this (please report bugs). You will + have to configure and build in two steps. The first step must create the + automatically-generated sources (e.g., comp_captab.c) on your host machine. + Then, run "make mostlyclean", remove config.* from the top-level directory + and configure for the cross-compiler. + ++ terminfo.5 does not format with the SunOS (and most other platform's) tbl + utility because it relies on a diversion for each table entry. Get the groff + package. + +Untested features: + +* The code for the HP color model using set_color_pair is untested. + +* The code for handling soft labels on a terminal type with built-in support + for them (num_labels > 0, label_height, label_width, label_format, label_off, + label_on, plab_norm, lab_f*) has not been tested. The label_format and + lab_f* capabilities aren't presently used. + +LONGER-TERM TO-DO ITEMS: + +1. Extended COSE conformance + +There is an XPG4 standard recently released which describes a superset +of the SVr4 API. The library is BASE conformant with this standard. +We would like to make ncurses fully conformant at the EXTENDED level +supporting internationalization. + +Here are page references to all material involving wide or multi-byte +characters in Issue 4 of the XSI Curses standard, with notes on their +status in this implementation: + + Page 1 (1.1.2) New Features discussion of internationalization. + Page 12 (2.4): Definition of cchar_t, wchar_t. + Page 16 (3.3.2): Introduction of multi-column characters. + Page 17-18 (3.3.5): Description of non-spacing characters. + Page 19-21 (3.4.2): Basic character operations. + Page 34 (addnstr): These should now call underlying wide- +character functions, and do (through waddnstr) if _XOPEN_SOURCE_EXTENDED is on). + Page 35 (addnwstr): wide-character add-string functions. All macros +except waddnwstr() which is not yet defined. + Page 36 (add_wch): wide-character add-char functions. All macros +except wadd_wch() which is not yet defined. + Page 39 (attr_get): implemented -- we've just made the current- +attributes field of the window an attr_t. + Page 43 (bkgrnd): None of these are implemented. + Page 45 (border_set): Neither of these is implemented. + Page 47 (box_set): box_set implemented as macro, but the underlying +wborder_set() is not yet defined. + Page 78 (echo_wchar): echo_wchar() implemented as macro, underlying +wecho_wchar() not yet implemented. + Page 81 (erasechar): Neither entry point is implemented. + Page 87 (getbkgrnd): Not implemented. + Page 88 (getcchar): Not implemented. + Page 93 (getn_wstr): All implemented (as macros) except the +underlying wgetn_wstr(). + Page 97 (get_wch): All implemented (as macros) except the +underlying wget_wch(). + Page 99 (get_wstr): Xref to page 93. + Page 105 (hline_set): All implemented (as macros) except the +underlying whline_set(), wvline_set(). + Page 114 (innstr): Multi-byte character-completeness check is +not implemented. + Page 115 (innwstr): All implemented (as macros) except the +underlying winnw_str(). + Page 119 (insnstr): Implementation may not be correct for multi-byte +characters. + Page 120 (ins_nwstr): Not implemented. + Page 121 (insstr): Xref to page 119. + Page 122 (instr): Xref to page 119. + Page 123 (ins_wch): Not implemented. + Page 124 (ins_wstr): Xref to page 120. + Page 126 (in_wch): Not implemented. + Page 127 (in_wchnstr): Not implemented. + Page 128 (inwstr): Xref to page 115. + Page 133 (killwchar): killwchar not implemented. + Page 158 (pechochar): pecho_wchar() not implemented. + Page 176 (setcchar): Not implemented. + Page 181 (slk_attroff): slk_wset not implemented. + Page 200 (ungetch): unget_wch() not implemented. + Page 203 (vidattr): vid_attr() and vid_puts() not implemented. + Page 206 (vline_set): Xref to page 105. + Page 214 (wunctrl): Not implemented. + Page 216 (curses.h): cchar_t, wint_t, wchar_t references. + Page 220 (curses.h): KEY_CODE_YES + +Basically, the macro superstructure is there but the core is absent. We +need better multi-locale support guarantees from the OS to finish this. +If you are working on internationalization support, please contact us so +we can cooperate. + +2. DOS port + +Only 16 of the 55 files in the library depend on the terminfo format. +It should be possible to further kernelize the package, then rewrite +a small number of core files to produce a functionally-compatible +port that would do updates to a memory-mapped screen area. The first +result of this would be a DOS port. + +3. X port + +It would be nice if ncurses could recognize when it was running under X and +maintain its own window. With this feature, all ncurses programs would +automatically become X programs. The challenge is to handle resize events +properly. + +4. Unused capabilities + +The currently unused capabilities fall naturally into several groups: + +A. Status-line capabilities: + + Booleans: has_status_line, status_line_esc_ok. + Numerics: width_status_line. + Strings: dis_status_line, from_status_line, to_status_line. + +System V Release 1 curses made no use of these at all. SVr4's use, if +any, is unknown. From the AT&T termcap file it looks like curses, in general, +shouldn't use them; terminal variants with status lines have their line count +decremented by 1, suggesting that curses is supposed to leave the status line +alone. + +B. Printer capabilities: + + Boolean: col_addr_glitch, cr_cancels_micro_mode, has_print_wheel, + row_addr_glitch, semi_auto_right_margin, cpi_changes_res, + lpi_changes_res. + Numeric: buffer_capacity, dot_horz_spacing, dot_vert_spacing, + max_micro_address, max_micro_jump, micro_col_size, + micro_line_size, number_of_pins, output_res_char, + output_res_line, output_res_horz_inch, print_rate, + wide_char_size, bit_image_entwining, bit_image_type. + String: down_half_line, form_feed, up_half_line, set_left_margin, + set_right_margin, clear_margins, change_char_pitch + ... set_page_length (all the SVr4 printer caps), + +Curses doesn't use these. + +C. Printer-control capabilities: + + Boolean: prtr_silent. + Strings: print_screen, prtr_on, prtr_off, prtr_non. + +Curses doesn't use these. + +D. Dialer strings: + + Strings: hangup, dial_phone, quick_dial, tone, pulse, flash_hook, + fixed_pause, wait_tone. + +Curses doesn't use these. + +E. Window and virtual-terminal capabilities: + + Numerics: maximum_windows, virtual_terminal. + Strings: req_for_input, create_window, goto_window, set_window. + +These seem to be fossils from some AT&T experiments on character-based +window systems that never escaped the lab. The virtual_terminal cap had +something to do with building terminal emulations into tty line disciplines. + +F. Unused VDT capabilities: + + Booleans: erase_overstrike, has_meta_key, insert_null_glitch, + move_insert, dest_tabs_magic_smso, transparent_underline, + needs_xon_xoff, hard_cursor. + Numerics: lines_of_memory, buttons. + Strings: pkey_key, pkey_local, pkey_xmit, underline_char, + enter_xon_mode, exit_xon_mode, xon_character, xoff_character, + display_clock, remove_clock, user[0-5], display_pc_char, + enter_scancode_mode, exit_scancode_mode, pc_term_options, + scancode_escape, alt_scancode_esc. + +These are the potentially important ones for ncurses. Notes: + + i) ncurses doesn't need move_insert; it never uses cup/hpa/vpa while + insert_mode is on. + + ii) We probably don't care about dest_tabs_magic_smso; only + Telerays used it and they're all long obsolete. + + diff --git a/ncurses-5.2/aclocal.m4 b/ncurses-5.2/aclocal.m4 new file mode 100644 index 0000000..73f2dbd --- /dev/null +++ b/ncurses-5.2/aclocal.m4 @@ -0,0 +1,2573 @@ +dnl*************************************************************************** +dnl Copyright (c) 1998-2000 Free Software Foundation, Inc. * +dnl * +dnl Permission is hereby granted, free of charge, to any person obtaining a * +dnl copy of this software and associated documentation files (the * +dnl "Software"), to deal in the Software without restriction, including * +dnl without limitation the rights to use, copy, modify, merge, publish, * +dnl distribute, distribute with modifications, sublicense, and/or sell * +dnl copies of the Software, and to permit persons to whom the Software is * +dnl furnished to do so, subject to the following conditions: * +dnl * +dnl The above copyright notice and this permission notice shall be included * +dnl in all copies or substantial portions of the Software. * +dnl * +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * +dnl IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * +dnl THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +dnl * +dnl Except as contained in this notice, the name(s) of the above copyright * +dnl holders shall not be used in advertising or otherwise to promote the * +dnl sale, use or other dealings in this Software without prior written * +dnl authorization. * +dnl*************************************************************************** +dnl +dnl Author: Thomas E. Dickey 1996,1997,1998,1999,2000 +dnl +dnl $Id$ +dnl Macros used in NCURSES auto-configuration script. +dnl +dnl See http://dickey.his.com/autoconf/ for additional information. +dnl +dnl --------------------------------------------------------------------------- +dnl --------------------------------------------------------------------------- +dnl Construct the list of include-options for the C programs in the Ada95 +dnl binding. +AC_DEFUN([CF_ADA_INCLUDE_DIRS], +[ +ACPPFLAGS="$ACPPFLAGS -I. -I../../include" +if test "$srcdir" != "."; then + ACPPFLAGS="$ACPPFLAGS -I\$(srcdir)/../../include" +fi +if test "$GCC" != yes; then + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" +elif test "$includedir" != "/usr/include"; then + if test "$includedir" = '${prefix}/include' ; then + if test $prefix != /usr ; then + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" + fi + else + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" + fi +fi +AC_SUBST(ACPPFLAGS) +])dnl +dnl --------------------------------------------------------------------------- +dnl This is adapted from the macros 'fp_PROG_CC_STDC' and 'fp_C_PROTOTYPES' +dnl in the sharutils 4.2 distribution. +AC_DEFUN([CF_ANSI_CC_CHECK], +[ +AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C) +AC_CACHE_VAL(cf_cv_ansi_cc,[ +cf_cv_ansi_cc=no +cf_save_CFLAGS="$CFLAGS" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc +# UnixWare 1.2 (cannot use -Xc, since ANSI/POSIX clashes) +for cf_arg in "-DCC_HAS_PROTOS" \ + "" \ + -qlanglvl=ansi \ + -std1 \ + -Ae \ + "-Aa -D_HPUX_SOURCE" \ + -Xc +do + CFLAGS="$cf_save_CFLAGS $cf_arg" + AC_TRY_COMPILE( +[ +#ifndef CC_HAS_PROTOS +#if !defined(__STDC__) || (__STDC__ != 1) +choke me +#endif +#endif +],[ + int test (int i, double x); + struct s1 {int (*f) (int a);}; + struct s2 {int (*f) (double a);};], + [cf_cv_ansi_cc="$cf_arg"; break]) +done +CFLAGS="$cf_save_CFLAGS" +]) +AC_MSG_RESULT($cf_cv_ansi_cc) + +if test "$cf_cv_ansi_cc" != "no"; then +if test ".$cf_cv_ansi_cc" != ".-DCC_HAS_PROTOS"; then + CFLAGS="$CFLAGS $cf_cv_ansi_cc" +else + AC_DEFINE(CC_HAS_PROTOS) +fi +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl For programs that must use an ANSI compiler, obtain compiler options that +dnl will make it recognize prototypes. We'll do preprocessor checks in other +dnl macros, since tools such as unproto can fake prototypes, but only part of +dnl the preprocessor. +AC_DEFUN([CF_ANSI_CC_REQD], +[AC_REQUIRE([CF_ANSI_CC_CHECK]) +if test "$cf_cv_ansi_cc" = "no"; then + AC_ERROR( +[Your compiler does not appear to recognize prototypes. +You have the following choices: + a. adjust your compiler options + b. get an up-to-date compiler + c. use a wrapper such as unproto]) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Test if 'bool' is a builtin type in the configured C++ compiler. Some +dnl older compilers (e.g., gcc 2.5.8) don't support 'bool' directly; gcc +dnl 2.6.3 does, in anticipation of the ANSI C++ standard. +dnl +dnl Treat the configuration-variable specially here, since we're directly +dnl substituting its value (i.e., 1/0). +AC_DEFUN([CF_BOOL_DECL], +[ +AC_MSG_CHECKING([for builtin bool type]) +AC_CACHE_VAL(ifelse($1,,cf_cv_builtin_bool,[$1]),[ + AC_TRY_COMPILE([ +#include +#include +],[bool x = false], + [ifelse($1,,cf_cv_builtin_bool,[$1])=1], + [ifelse($1,,cf_cv_builtin_bool,[$1])=0]) + ]) +if test "$ifelse($1,,cf_cv_builtin_bool,[$1])" = 1 +then AC_MSG_RESULT(yes) +else AC_MSG_RESULT(no) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Test for the size of 'bool' in the configured C++ compiler (e.g., a type). +dnl Don't bother looking for bool.h, since it's been deprecated. +AC_DEFUN([CF_BOOL_SIZE], +[ +AC_MSG_CHECKING([for size of bool]) +AC_CACHE_VAL(cf_cv_type_of_bool,[ + rm -f cf_test.out + AC_TRY_RUN([ +#include +#include +#ifdef HAVE_GXX_BUILTIN_H +#include +#elif HAVE_GPP_BUILTIN_H +#include +#elif HAVE_BUILTIN_H +#include +#endif +main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + bool x = true; + if ((bool)(-x) >= 0) + fputs("unsigned ", fp); + if (sizeof(x) == sizeof(int)) fputs("int", fp); + else if (sizeof(x) == sizeof(char)) fputs("char", fp); + else if (sizeof(x) == sizeof(short))fputs("short",fp); + else if (sizeof(x) == sizeof(long)) fputs("long", fp); + fclose(fp); + } + exit(0); +} + ], + [cf_cv_type_of_bool=`cat cf_test.out`], + [cf_cv_type_of_bool=unknown], + [cf_cv_type_of_bool=unknown]) + ]) + rm -f cf_test.out +AC_MSG_RESULT($cf_cv_type_of_bool) +if test "$cf_cv_type_of_bool" = unknown ; then + AC_MSG_WARN(Assuming unsigned for type of bool) + cf_cv_type_of_bool=unsigned +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Determine the default configuration into which we'll install ncurses. This +dnl can be overridden by the user's command-line options. There's two items to +dnl look for: +dnl 1. the prefix (e.g., /usr) +dnl 2. the header files (e.g., /usr/include/ncurses) +dnl We'll look for a previous installation of ncurses and use the same defaults. +dnl +dnl We don't use AC_PREFIX_DEFAULT, because it gets evaluated too soon, and +dnl we don't use AC_PREFIX_PROGRAM, because we cannot distinguish ncurses's +dnl programs from a vendor's. +AC_DEFUN([CF_CFG_DEFAULTS], +[ +AC_MSG_CHECKING(for prefix) +if test "x$prefix" = "xNONE" ; then + case "$cf_cv_system_name" in + # non-vendor systems don't have a conflict + openbsd*|netbsd*|freebsd*|linux*) + prefix=/usr + ;; + *) prefix=$ac_default_prefix + ;; + esac +fi +AC_MSG_RESULT($prefix) + +if test "x$prefix" = "xNONE" ; then +AC_MSG_CHECKING(for default include-directory) +test -n "$verbose" && echo 1>&AC_FD_MSG +for cf_symbol in \ + $includedir \ + $includedir/ncurses \ + $prefix/include \ + $prefix/include/ncurses \ + /usr/local/include \ + /usr/local/include/ncurses \ + /usr/include \ + /usr/include/ncurses +do + cf_dir=`eval echo $cf_symbol` + if test -f $cf_dir/curses.h ; then + if ( fgrep NCURSES_VERSION $cf_dir/curses.h 2>&1 >/dev/null ) ; then + includedir="$cf_symbol" + test -n "$verbose" && echo $ac_n " found " 1>&AC_FD_MSG + break + fi + fi + test -n "$verbose" && echo " tested $cf_dir" 1>&AC_FD_MSG +done +AC_MSG_RESULT($includedir) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if the terminal-capability database functions are available. If not, +dnl ncurses has a much-reduced version. +AC_DEFUN([CF_CGETENT],[ +AC_MSG_CHECKING(for terminal-capability database functions) +AC_CACHE_VAL(cf_cv_cgetent,[ +AC_TRY_LINK([ +#include ],[ + char temp[128]; + char *buf = temp; + char *db_array = temp; + cgetent(&buf, /* int *, */ &db_array, "vt100"); + cgetcap(buf, "tc", '='); + cgetmatch(buf, "tc"); + ], + [cf_cv_cgetent=yes], + [cf_cv_cgetent=no]) +]) +AC_MSG_RESULT($cf_cv_cgetent) +test "$cf_cv_cgetent" = yes && AC_DEFINE(HAVE_BSD_CGETENT) +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if we're accidentally using a cache from a different machine. +dnl Derive the system name, as a check for reusing the autoconf cache. +dnl +dnl If we've packaged config.guess and config.sub, run that (since it does a +dnl better job than uname). Normally we'll use AC_CANONICAL_HOST, but allow +dnl an extra parameter that we may override, e.g., for AC_CANONICAL_SYSTEM +dnl which is useful in cross-compiles. +AC_DEFUN([CF_CHECK_CACHE], +[ +if test -f $srcdir/config.guess ; then + ifelse([$1],,[AC_CANONICAL_HOST],[$1]) + system_name="$host_os" +else + system_name="`(uname -s -r) 2>/dev/null`" + if test -z "$system_name" ; then + system_name="`(hostname) 2>/dev/null`" + fi +fi +test -n "$system_name" && AC_DEFINE_UNQUOTED(SYSTEM_NAME,"$system_name") +AC_CACHE_VAL(cf_cv_system_name,[cf_cv_system_name="$system_name"]) + +test -z "$system_name" && system_name="$cf_cv_system_name" +test -n "$cf_cv_system_name" && AC_MSG_RESULT("Configuring for $cf_cv_system_name") + +if test ".$system_name" != ".$cf_cv_system_name" ; then + AC_MSG_RESULT(Cached system name ($system_name) does not agree with actual ($cf_cv_system_name)) + AC_ERROR("Please remove config.cache and try again.") +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Check for data that is usually declared in or , e.g., +dnl the 'errno' variable. Define a DECL_xxx symbol if we must declare it +dnl ourselves. +dnl +dnl (I would use AC_CACHE_CHECK here, but it will not work when called in a +dnl loop from CF_SYS_ERRLIST). +dnl +dnl $1 = the name to check +AC_DEFUN([CF_CHECK_ERRNO], +[ +AC_MSG_CHECKING(if external $1 is declared) +AC_CACHE_VAL(cf_cv_dcl_$1,[ + AC_TRY_COMPILE([ +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include ], + [long x = (long) $1], + [eval 'cf_cv_dcl_'$1'=yes'], + [eval 'cf_cv_dcl_'$1'=no']) +]) + +eval 'cf_result=$cf_cv_dcl_'$1 +AC_MSG_RESULT($cf_result) + +if test "$cf_result" = no ; then + eval 'cf_result=DECL_'$1 + CF_UPPER(cf_result,$cf_result) + AC_DEFINE_UNQUOTED($cf_result) +fi + +# It's possible (for near-UNIX clones) that the data doesn't exist +CF_CHECK_EXTERN_DATA($1,int) +])dnl +dnl --------------------------------------------------------------------------- +dnl Check for existence of external data in the current set of libraries. If +dnl we can modify it, it's real enough. +dnl $1 = the name to check +dnl $2 = its type +AC_DEFUN([CF_CHECK_EXTERN_DATA], +[ +AC_MSG_CHECKING(if external $1 exists) +AC_CACHE_VAL(cf_cv_have_$1,[ + AC_TRY_LINK([ +#undef $1 +extern $2 $1; +], + [$1 = 2], + [eval 'cf_cv_have_'$1'=yes'], + [eval 'cf_cv_have_'$1'=no'])]) + +eval 'cf_result=$cf_cv_have_'$1 +AC_MSG_RESULT($cf_result) + +if test "$cf_result" = yes ; then + eval 'cf_result=HAVE_'$1 + CF_UPPER(cf_result,$cf_result) + AC_DEFINE_UNQUOTED($cf_result) +fi + +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if the C++ compiler accepts duplicate parameter initialization. This +dnl is a late feature for the standard and is not in some recent compilers +dnl (1999/9/11). +AC_DEFUN([CF_CPP_PARAM_INIT], +[ +if test "$CXX" = yes ; then +AC_CACHE_CHECK(if $CXX accepts parameter initialization,cf_cv_cpp_param_init,[ + AC_LANG_CPLUSPLUS + AC_TRY_RUN([ +class TEST { +private: + int value; +public: + TEST(int x = 1); + ~TEST(); +}; + +TEST::TEST(int x = 1) // some compilers do not like second initializer +{ + value = x; +} +void main() { } +], + [cf_cv_cpp_param_init=yes], + [cf_cv_cpp_param_init=no], + [cf_cv_cpp_param_init=unknown]) +]) +fi +test "$cf_cv_cpp_param_init" = yes && AC_DEFINE(CPP_HAS_PARAM_INIT) +])dnl +dnl --------------------------------------------------------------------------- +AC_DEFUN([CF_DIRS_TO_MAKE], +[ +DIRS_TO_MAKE="lib" +for cf_item in $cf_list_models +do + CF_OBJ_SUBDIR($cf_item,cf_subdir) + DIRS_TO_MAKE="$DIRS_TO_MAKE $cf_subdir" +done +for cf_dir in $DIRS_TO_MAKE +do + test ! -d $cf_dir && mkdir $cf_dir +done +AC_SUBST(DIRS_TO_MAKE) +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if 'errno' is declared in +AC_DEFUN([CF_ERRNO], +[ +CF_CHECK_ERRNO(errno) +])dnl +dnl --------------------------------------------------------------------------- +dnl Test for conflicting definitions of exception in gcc 2.8.0, etc., between +dnl math.h and builtin.h, only for ncurses +AC_DEFUN([CF_ETIP_DEFINES], +[ +AC_MSG_CHECKING(for special defines needed for etip.h) +cf_save_CXXFLAGS="$CXXFLAGS" +cf_result="none" +for cf_math in "" MATH_H +do +for cf_excp in "" MATH_EXCEPTION +do + CXXFLAGS="$cf_save_CXXFLAGS -I${srcdir}/c++ -I${srcdir}/menu" + test -n "$cf_math" && CXXFLAGS="$CXXFLAGS -DETIP_NEEDS_${cf_math}" + test -n "$cf_excp" && CXXFLAGS="$CXXFLAGS -DETIP_NEEDS_${cf_excp}" +AC_TRY_COMPILE([ +#include +],[],[ + test -n "$cf_math" && AC_DEFINE_UNQUOTED(ETIP_NEEDS_${cf_math}) + test -n "$cf_excp" && AC_DEFINE_UNQUOTED(ETIP_NEEDS_${cf_excp}) + cf_result="$cf_math $cf_excp" + break +],[]) +done +done +AC_MSG_RESULT($cf_result) +CXXFLAGS="$cf_save_CXXFLAGS" +]) +dnl --------------------------------------------------------------------------- +dnl Check for memmove, or a bcopy that can handle overlapping copy. If neither +dnl is found, add our own version of memmove to the list of objects. +AC_DEFUN([CF_FUNC_MEMMOVE], +[ +AC_CHECK_FUNC(memmove,,[ +AC_CHECK_FUNC(bcopy,[ + AC_CACHE_CHECK(if bcopy does overlapping moves,cf_cv_good_bcopy,[ + AC_TRY_RUN([ +int main() { + static char data[] = "abcdefghijklmnopqrstuwwxyz"; + char temp[40]; + bcopy(data, temp, sizeof(data)); + bcopy(temp+10, temp, 15); + bcopy(temp+5, temp+15, 10); + exit (strcmp(temp, "klmnopqrstuwwxypqrstuwwxyz")); +} + ], + [cf_cv_good_bcopy=yes], + [cf_cv_good_bcopy=no], + [cf_cv_good_bcopy=unknown]) + ]) + ],[cf_cv_good_bcopy=no]) + if test "$cf_cv_good_bcopy" = yes ; then + AC_DEFINE(USE_OK_BCOPY) + else + AC_DEFINE(USE_MY_MEMMOVE) + fi +])])dnl +dnl --------------------------------------------------------------------------- +dnl See if the poll function really works. Some platforms have poll(), but +dnl it does not work for terminals or files. +AC_DEFUN([CF_FUNC_POLL],[ +AC_CACHE_CHECK(if poll really works,cf_cv_working_poll,[ +AC_TRY_RUN([ +#include +#ifdef HAVE_POLL_H +#include +#else +#include +#endif +int main() { + struct pollfd myfds; + int ret; + + myfds.fd = 0; + myfds.events = POLLIN; + + ret = poll(&myfds, 1, 100); + exit(ret != 0); +}], + [cf_cv_working_poll=yes], + [cf_cv_working_poll=no], + [cf_cv_working_poll=unknown])]) +test "$cf_cv_working_poll" = "yes" && AC_DEFINE(HAVE_WORKING_POLL) +])dnl +dnl --------------------------------------------------------------------------- +dnl Some old/broken variations define tcgetattr() only as a macro in +dnl termio(s).h +AC_DEFUN([CF_FUNC_TERMIOS],[ +AC_REQUIRE([CF_STRUCT_TERMIOS]) +AC_CACHE_CHECK(for tcgetattr, cf_cv_have_tcgetattr,[ +AC_TRY_LINK([ +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_TERMIOS_H +#include +#define TTY struct termios +#else +#ifdef HAVE_TERMIO_H +#include +#define TTY struct termio +#endif +#endif +],[ +TTY foo; +tcgetattr(1, &foo);], +[cf_cv_have_tcgetattr=yes], +[cf_cv_have_tcgetattr=no])]) +test "$cf_cv_have_tcgetattr" = yes && AC_DEFINE(HAVE_TCGETATTR) +])dnl +dnl --------------------------------------------------------------------------- +dnl Test for availability of useful gcc __attribute__ directives to quiet +dnl compiler warnings. Though useful, not all are supported -- and contrary +dnl to documentation, unrecognized directives cause older compilers to barf. +AC_DEFUN([CF_GCC_ATTRIBUTES], +[ +if test "$GCC" = yes +then +cat > conftest.i < conftest.$ac_ext <&AC_FD_CC + case $cf_attribute in + scanf|printf) + cat >conftest.h <conftest.h <>confdefs.h +# else +# sed -e 's/__attr.*/\/*nothing*\//' conftest.h >>confdefs.h + fi + done +else + fgrep define conftest.i >>confdefs.h +fi +rm -rf conftest* +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if the compiler supports useful warning options. There's a few that +dnl we don't use, simply because they're too noisy: +dnl +dnl -Wconversion (useful in older versions of gcc, but not in gcc 2.7.x) +dnl -Wredundant-decls (system headers make this too noisy) +dnl -Wtraditional (combines too many unrelated messages, only a few useful) +dnl -Wwrite-strings (too noisy, but should review occasionally) +dnl -pedantic +dnl +AC_DEFUN([CF_GCC_WARNINGS], +[ +if test "$GCC" = yes +then + changequote(,)dnl + cat > conftest.$ac_ext <>conftest.ads <>conftest.adb <&AC_FD_CC 2>&1 ) ; then + if ( ./conftest 1>&AC_FD_CC 2>&1 ) ; then +ifelse($3,, :,[ $3]) +ifelse($4,,,[ else + $4]) + fi +ifelse($4,,,[else + $4]) +fi +rm -f conftest* +])dnl +dnl --------------------------------------------------------------------------- +dnl Verify Version of GNAT. +AC_DEFUN([CF_GNAT_VERSION], +[ +changequote(<<, >>)dnl +cf_cv_gnat_version=`$cf_ada_make -v 2>&1 | grep '[0-9].[0-9][0-9]*' |\ + sed -e 's/[^0-9 \.]//g' | $AWK '{print $<<1>>;}'` +case $cf_cv_gnat_version in + 3.1[1-9]*|3.[2-9]*|[4-9].*) + cf_cv_prog_gnat_correct=yes + ;; + *) echo Unsupported GNAT version $cf_cv_gnat_version. Required is 3.11 or better. Disabling Ada95 binding. + cf_cv_prog_gnat_correct=no + ;; +esac +case $cf_cv_gnat_version in + 3.1*|[4-9].*) + cf_compile_generics=generics + cf_generic_objects="\$(GENOBJS)" + ;; + *) cf_compile_generics= + cf_generic_objects= + ;; +esac +changequote([, ])dnl +]) +dnl --------------------------------------------------------------------------- +dnl If we're trying to use g++, test if libg++ is installed (a rather common +dnl problem :-). If we have the compiler but no library, we'll be able to +dnl configure, but won't be able to build the c++ demo program. +AC_DEFUN([CF_GPP_LIBRARY], +[ +cf_cxx_library=unknown +case $cf_cv_system_name in #(vi +os2*) #(vi + cf_gpp_libname=gpp + ;; +*) + cf_gpp_libname=g++ + ;; +esac +if test "$ac_cv_prog_gxx" = yes; then + AC_MSG_CHECKING([for lib$cf_gpp_libname]) + cf_save="$LIBS" + LIBS="$LIBS -l$cf_gpp_libname" + AC_TRY_LINK([ +#include <$cf_gpp_libname/builtin.h> + ], + [two_arg_error_handler_t foo2 = lib_error_handler], + [cf_cxx_library=yes + CXXLIBS="$CXXLIBS -l$cf_gpp_libname" + if test "$cf_gpp_libname" = cpp ; then + AC_DEFINE(HAVE_GPP_BUILTIN_H) + else + AC_DEFINE(HAVE_GXX_BUILTIN_H) + fi], + [AC_TRY_LINK([ +#include + ], + [two_arg_error_handler_t foo2 = lib_error_handler], + [cf_cxx_library=yes + CXXLIBS="$CXXLIBS -l$cf_gpp_libname" + AC_DEFINE(HAVE_BUILTIN_H)], + [cf_cxx_library=no])]) + LIBS="$cf_save" + AC_MSG_RESULT($cf_cxx_library) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Insert text into the help-message, for readability, from AC_ARG_WITH. +AC_DEFUN([CF_HELP_MESSAGE], +[AC_DIVERT_HELP([$1])dnl +])dnl +dnl --------------------------------------------------------------------------- +dnl Construct the list of include-options according to whether we're building +dnl in the source directory or using '--srcdir=DIR' option. If we're building +dnl with gcc, don't append the includedir if it happens to be /usr/include, +dnl since that usually breaks gcc's shadow-includes. +AC_DEFUN([CF_INCLUDE_DIRS], +[ +CPPFLAGS="$CPPFLAGS -I. -I../include" +if test "$srcdir" != "."; then + CPPFLAGS="$CPPFLAGS -I\$(srcdir)/../include" +fi +if test "$GCC" != yes; then + CPPFLAGS="$CPPFLAGS -I\$(includedir)" +elif test "$includedir" != "/usr/include"; then + if test "$includedir" = '${prefix}/include' ; then + if test $prefix != /usr ; then + CPPFLAGS="$CPPFLAGS -I\$(includedir)" + fi + else + CPPFLAGS="$CPPFLAGS -I\$(includedir)" + fi +fi +AC_SUBST(CPPFLAGS) +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if we have either a function or macro for 'isascii()'. +AC_DEFUN([CF_ISASCII], +[ +AC_MSG_CHECKING(for isascii) +AC_CACHE_VAL(cf_cv_have_isascii,[ + AC_TRY_LINK([#include ],[int x = isascii(' ')], + [cf_cv_have_isascii=yes], + [cf_cv_have_isascii=no]) +])dnl +AC_MSG_RESULT($cf_cv_have_isascii) +test "$cf_cv_have_isascii" = yes && AC_DEFINE(HAVE_ISASCII) +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute the library-prefix for the given host system +dnl $1 = variable to set +AC_DEFUN([CF_LIB_PREFIX], +[ + case $cf_cv_system_name in + os2) LIB_PREFIX='' ;; + *) LIB_PREFIX='lib' ;; + esac +ifelse($1,,,[$1=$LIB_PREFIX]) + AC_SUBST(LIB_PREFIX) +])dnl +dnl --------------------------------------------------------------------------- +dnl Append definitions and rules for the given models to the subdirectory +dnl Makefiles, and the recursion rule for the top-level Makefile. If the +dnl subdirectory is a library-source directory, modify the LIBRARIES list in +dnl the corresponding makefile to list the models that we'll generate. +dnl +dnl For shared libraries, make a list of symbolic links to construct when +dnl generating each library. The convention used for Linux is the simplest +dnl one: +dnl lib.so -> +dnl lib.so. -> +dnl lib.so.. +AC_DEFUN([CF_LIB_RULES], +[ +CF_LIB_PREFIX(cf_prefix) +AC_REQUIRE([CF_SUBST_NCURSES_VERSION]) +for cf_dir in $SRC_SUBDIRS +do + if test -f $srcdir/$cf_dir/modules; then + + cf_libs_to_make= + for cf_item in $CF_LIST_MODELS + do + CF_LIB_SUFFIX($cf_item,cf_suffix) + if test $cf_item = shared ; then + if test "$cf_cv_do_symlinks" = yes ; then + case "$cf_cv_shlib_version" in #(vi + rel) cf_suffix="$cf_suffix"'.$(REL_VERSION)' ;; #(vi + abi) cf_suffix="$cf_suffix"'.$(ABI_VERSION)' ;; + esac + fi + fi + cf_libs_to_make="$cf_libs_to_make ../lib/${cf_prefix}${cf_dir}${cf_suffix}" + done + + if test $cf_dir = ncurses ; then + case "$LIB_SUBSETS" in #(vi + termlib+*) #(vi + ;; + *) #(vi + cf_item=`echo $cf_libs_to_make |sed -e s/$LIB_NAME/$TINFO_NAME/g` + cf_libs_to_make="$cf_item $cf_libs_to_make" + ;; + esac + fi + + sed -e "s@\@LIBS_TO_MAKE\@@$cf_libs_to_make@" \ + $cf_dir/Makefile >$cf_dir/Makefile.out + mv $cf_dir/Makefile.out $cf_dir/Makefile + + $AWK -f $srcdir/mk-0th.awk \ + name=$cf_dir \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + + for cf_item in $CF_LIST_MODELS + do + echo 'Appending rules for '$cf_item' model ('$cf_dir')' + CF_UPPER(CF_ITEM,$cf_item) + CF_LIB_SUFFIX($cf_item,cf_suffix) + CF_OBJ_SUBDIR($cf_item,cf_subdir) + + # These dependencies really are for development, not + # builds, but they are useful in porting, too. + cf_depend="../include/ncurses_cfg.h" + if test "$srcdir" = "."; then + cf_reldir="." + else + cf_reldir="\$(srcdir)" + fi + + if test -f $srcdir/$cf_dir/$cf_dir.priv.h; then + cf_depend="$cf_depend $cf_reldir/$cf_dir.priv.h" + elif test -f $srcdir/$cf_dir/curses.priv.h; then + cf_depend="$cf_depend $cf_reldir/curses.priv.h" + fi + + for cf_subset in $LIB_SUBSETS + do + $AWK -f $srcdir/mk-1st.awk \ + name=$cf_dir \ + traces=$LIB_TRACING \ + MODEL=$CF_ITEM \ + model=$cf_subdir \ + prefix=$cf_prefix \ + suffix=$cf_suffix \ + subset=$cf_subset \ + ShlibVer=$cf_cv_shlib_version \ + DoLinks=$cf_cv_do_symlinks \ + rmSoLocs=$cf_cv_rm_so_locs \ + ldconfig="$LDCONFIG" \ + overwrite=$WITH_OVERWRITE \ + depend="$cf_depend" \ + target="$target" \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + test $cf_dir = ncurses && WITH_OVERWRITE=no + $AWK -f $srcdir/mk-2nd.awk \ + name=$cf_dir \ + traces=$LIB_TRACING \ + MODEL=$CF_ITEM \ + model=$cf_subdir \ + subset=$cf_subset \ + srcdir=$srcdir \ + echo=$WITH_ECHO \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + done + done + fi + + echo ' cd '$cf_dir' && $(MAKE) $(CF_MFLAGS) [$]@' >>Makefile +done + +for cf_dir in $SRC_SUBDIRS +do + if test -f $cf_dir/Makefile ; then + case "$cf_dir" in + Ada95) #(vi + echo 'libs \' >> Makefile + echo 'install.libs \' >> Makefile + echo 'uninstall.libs ::' >> Makefile + echo ' cd '$cf_dir' && $(MAKE) $(CF_MFLAGS) [$]@' >> Makefile + ;; + esac + fi + + if test -f $srcdir/$cf_dir/modules; then + echo >> Makefile + if test -f $srcdir/$cf_dir/headers; then +cat >> Makefile <> Makefile +fi +cat >> Makefile <> Makefile <> Makefile <> Makefile <headers.sh <>headers.sh </<\$END\/\$NAME>/" >> \$TMPSED + done + ;; +*) + echo "" >> \$TMPSED + ;; +esac +CF_EOF +else + cat >>headers.sh <//" >> \$TMPSED + NAME=ncurses.h + fi + echo "s/<\$NAME>/<\$END\/\$NAME>/" >> \$TMPSED + done + ;; +*) + echo "s///" >> \$TMPSED + ;; +esac +CF_EOF +fi +cat >>headers.sh < \$TMPSRC +NAME=\`basename \$SRC\` +CF_EOF +if test $WITH_CURSES_H != yes; then + cat >>headers.sh <>headers.sh <>$cf_dir/Makefile <>$cf_dir/Makefile + j=$i + done + echo " $j" >>$cf_dir/Makefile + for i in `cat $srcdir/$cf_dir/headers |fgrep -v "#"` + do + echo " @ (cd \$(DESTDIR)\$(includedir) && rm -f `basename $i`) ; ../headers.sh \$(INSTALL_DATA) \$(DESTDIR)\$(includedir) \$(srcdir) $i" >>$cf_dir/Makefile + test $i = curses.h && test $WITH_CURSES_H = yes && echo " @ (cd \$(DESTDIR)\$(includedir) && rm -f ncurses.h && \$(LN_S) curses.h ncurses.h)" >>$cf_dir/Makefile + done + + cat >>$cf_dir/Makefile <>$cf_dir/Makefile + test $i = curses.h && echo " -@ (cd \$(DESTDIR)\$(includedir) && rm -f ncurses.h)" >>$cf_dir/Makefile + done + fi +done + +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute the library file-suffix from the given model name +dnl $1 = model name +dnl $2 = variable to set +dnl The variable $LIB_SUFFIX, if set, prepends the variable to set. +AC_DEFUN([CF_LIB_SUFFIX], +[ + AC_REQUIRE([CF_SUBST_NCURSES_VERSION]) + case $1 in + libtool) $2='.la' ;; + normal) $2='.a' ;; + debug) $2='_g.a' ;; + profile) $2='_p.a' ;; + shared) + case $cf_cv_system_name in + hpux*) $2='.sl' ;; + *) $2='.so' ;; + esac + esac + test -n "$LIB_SUFFIX" && $2="${LIB_SUFFIX}[$]{$2}" +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute the string to append to -library from the given model name +dnl $1 = model name +dnl $2 = variable to set +dnl The variable $LIB_SUFFIX, if set, prepends the variable to set. +AC_DEFUN([CF_LIB_TYPE], +[ + case $1 in + libtool) $2='' ;; + normal) $2='' ;; + debug) $2='_g' ;; + profile) $2='_p' ;; + shared) $2='' ;; + esac + test -n "$LIB_SUFFIX" && $2="${LIB_SUFFIX}[$]{$2}" +])dnl +dnl --------------------------------------------------------------------------- +dnl Some systems have a non-ANSI linker that doesn't pull in modules that have +dnl only data (i.e., no functions), for example NeXT. On those systems we'll +dnl have to provide wrappers for global tables to ensure they're linked +dnl properly. +AC_DEFUN([CF_LINK_DATAONLY], +[ +AC_MSG_CHECKING([if data-only library module links]) +AC_CACHE_VAL(cf_cv_link_dataonly,[ + rm -f conftest.a + changequote(,)dnl + cat >conftest.$ac_ext <&5 1>/dev/null + fi + rm -f conftest.$ac_ext data.o + changequote(,)dnl + cat >conftest.$ac_ext <&5 1>/dev/null + fi + rm -f conftest.$ac_ext func.o + ( eval $ac_cv_prog_RANLIB conftest.a ) 2>&5 >/dev/null + cf_saveLIBS="$LIBS" + LIBS="conftest.a $LIBS" + AC_TRY_RUN([ + int main() + { + extern int testfunc(); + exit (!testfunc()); + } + ], + [cf_cv_link_dataonly=yes], + [cf_cv_link_dataonly=no], + [cf_cv_link_dataonly=unknown]) + LIBS="$cf_saveLIBS" + ]) +AC_MSG_RESULT($cf_cv_link_dataonly) +test "$cf_cv_link_dataonly" = no && AC_DEFINE(BROKEN_LINKER) +])dnl +dnl --------------------------------------------------------------------------- +dnl Most Unix systems have both link and symlink, a few don't have symlink. +dnl A few non-Unix systems implement symlink, but not link. +dnl A few non-systems implement neither (or have nonfunctional versions). +AC_DEFUN([CF_LINK_FUNCS], +[ +AC_CHECK_FUNCS( \ + remove \ + unlink ) + +if test "$ac_cv_prog_cc_cross" = yes ; then + AC_CHECK_FUNCS( \ + link \ + symlink ) +else + AC_CACHE_CHECK(if link/symlink functions work,cf_cv_link_funcs,[ + cf_cv_link_funcs= + for cf_func in link symlink ; do + AC_TRY_RUN([ +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +int main() +{ + int fail = 0; + char *src = "config.log"; + char *dst = "conftest.chk"; + struct stat src_sb; + struct stat dst_sb; + + stat(src, &src_sb); + fail = ($cf_func("config.log", "conftest.chk") < 0) + || (stat(dst, &dst_sb) < 0) + || (dst_sb.st_mtime != src_sb.st_mtime); +#ifdef HAVE_UNLINK + unlink(dst); +#else + remove(dst); +#endif + exit (fail); +} + ],[ + cf_cv_link_funcs="$cf_cv_link_funcs $cf_func" + eval 'ac_cv_func_'$cf_func'=yes'],[ + eval 'ac_cv_func_'$cf_func'=no'],[ + eval 'ac_cv_func_'$cf_func'=error']) + done + test -z "$cf_cv_link_funcs" && cf_cv_link_funcs=no + ]) + test "$ac_cv_func_link" = yes && AC_DEFINE(HAVE_LINK) + test "$ac_cv_func_symlink" = yes && AC_DEFINE(HAVE_SYMLINK) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Some 'make' programs support $(MAKEFLAGS), some $(MFLAGS), to pass 'make' +dnl options to lower-levels. It's very useful for "make -n" -- if we have it. +dnl (GNU 'make' does both, something POSIX 'make', which happens to make the +dnl $(MAKEFLAGS) variable incompatible because it adds the assignments :-) +AC_DEFUN([CF_MAKEFLAGS], +[ +AC_MSG_CHECKING([for makeflags variable]) +AC_CACHE_VAL(cf_cv_makeflags,[ + cf_cv_makeflags='' + for cf_option in '-$(MAKEFLAGS)' '$(MFLAGS)' + do + cat >cf_makeflags.tmp </dev/null` + case "$cf_result" in + .*k) + cf_result=`${MAKE-make} -k -f cf_makeflags.tmp CC=cc 2>/dev/null` + case "$cf_result" in + .*CC=*) cf_cv_makeflags= + ;; + *) cf_cv_makeflags=$cf_option + ;; + esac + break + ;; + *) echo no match "$cf_result" + ;; + esac + done + rm -f cf_makeflags.tmp]) +AC_MSG_RESULT($cf_cv_makeflags) +AC_SUBST(cf_cv_makeflags) +])dnl +dnl --------------------------------------------------------------------------- +dnl Generate tags/TAGS targets for makefiles. Do not generate TAGS if we have +dnl a monocase filesystem. +AC_DEFUN([CF_MAKE_TAGS],[ +AC_REQUIRE([CF_MIXEDCASE_FILENAMES]) +AC_CHECK_PROG(MAKE_LOWER_TAGS, ctags, yes, no) + +if test "$cf_cv_mixedcase" = yes ; then + AC_CHECK_PROG(MAKE_UPPER_TAGS, etags, yes, no) +else + MAKE_UPPER_TAGS=no +fi + +if test "$MAKE_UPPER_TAGS" = yes ; then + MAKE_UPPER_TAGS= +else + MAKE_UPPER_TAGS="#" +fi +AC_SUBST(MAKE_UPPER_TAGS) + +if test "$MAKE_LOWER_TAGS" = yes ; then + MAKE_LOWER_TAGS= +else + MAKE_LOWER_TAGS="#" +fi +AC_SUBST(MAKE_LOWER_TAGS) +])dnl +dnl --------------------------------------------------------------------------- +dnl Option to allow user to override automatic configuration of manpage format. +dnl There are several special cases. +AC_DEFUN([CF_MANPAGE_FORMAT], +[ AC_MSG_CHECKING(format of man-pages) + +AC_ARG_WITH(manpage-format, + [ --with-manpage-format specify manpage-format: gzip/compress/BSDI/normal and + optionally formatted, e.g., gzip,formatted], + [cf_manpage_form=$withval], + [cf_manpage_form=unknown]) + +case ".$cf_manpage_form" in +.gzip|.compress|.BSDI|.normal|.formatted) # (vi + ;; +.unknown|.) # (vi + if test -z "$MANPATH" ; then + MANPATH="/usr/man:/usr/share/man" + fi + # look for the 'date' man-page (it's most likely to be installed!) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + cf_manpage_form=unknown + for cf_dir in $MANPATH; do + test -z "$cf_dir" && cf_dir=/usr/man +changequote({{,}})dnl + for cf_name in $cf_dir/*/date.[01]* $cf_dir/*/date +changequote([,])dnl + do + cf_test=`echo $cf_name | sed -e 's/*//'` + if test "x$cf_test" = "x$cf_name" ; then + case "$cf_name" in + *.gz) cf_manpage_form=gzip;; + *.Z) cf_manpage_form=compress;; + *.0) cf_manpage_form=BSDI,formatted;; + *) cf_manpage_form=normal;; + esac + break + fi + done + if test "$cf_manpage_form" != "unknown" ; then + break + fi + done + IFS="$ac_save_ifs" + ;; +.*) # (vi + AC_MSG_WARN(Unexpected manpage-format) + ;; +esac + +AC_MSG_RESULT($cf_manpage_form) +])dnl +dnl --------------------------------------------------------------------------- +dnl The Debian people have their own naming convention for manpages. This +dnl option lets us override the name of the file containing renaming, or +dnl disable it altogether. +AC_DEFUN([CF_MANPAGE_RENAMES], +[ +AC_MSG_CHECKING(for manpage renaming) + +AC_ARG_WITH(manpage-renames, + [ --with-manpage-renames specify manpage-renaming], + [cf_manpage_renames=$withval], + [cf_manpage_renames=yes]) + +case ".$cf_manpage_renames" in #(vi +.no) #(vi + ;; +.|.yes) + # Debian 'man' program? + if test -f /etc/debian_version ; then + cf_manpage_renames=`cd $srcdir && pwd`/man/man_db.renames + else + cf_manpage_renames=no + fi + ;; +esac + +if test "$cf_manpage_renames" != no ; then + if test ! -f $cf_manpage_renames ; then + AC_MSG_ERROR(not a filename: $cf_manpage_renames) + fi + + test ! -d man && mkdir man + + # Construct a sed-script to perform renaming within man-pages + if test -n "$cf_manpage_renames" ; then + test ! -d man && mkdir man + $srcdir/man/make_sed.sh $cf_manpage_renames >man/edit_man.sed + fi +fi + +AC_MSG_RESULT($cf_manpage_renames) +])dnl +dnl --------------------------------------------------------------------------- +dnl Some people expect each tool to make all aliases for manpages in the +dnl man-directory. This accommodates the older, less-capable implementations +dnl of 'man', and is optional. +AC_DEFUN([CF_MANPAGE_SYMLINKS], +[ +AC_MSG_CHECKING(for manpage symlinks) + +AC_ARG_WITH(manpage-symlinks, + [ --with-manpage-symlinks specify manpage-symlinks], + [cf_manpage_symlinks=$withval], + [cf_manpage_symlinks=yes]) + +AC_MSG_RESULT($cf_manpage_symlinks) +])dnl +dnl --------------------------------------------------------------------------- +dnl This option causes manpages to be run through tbl(1) to generate tables +dnl correctly. +AC_DEFUN([CF_MANPAGE_TBL], +[ +AC_MSG_CHECKING(for manpage tbl) + +AC_ARG_WITH(manpage-tbl, + [ --with-manpage-tbl specify manpage processing with tbl], + [cf_manpage_tbl=$withval], + [cf_manpage_tbl=no]) + +AC_MSG_RESULT($cf_manpage_tbl) +])dnl +dnl --------------------------------------------------------------------------- +dnl Try to determine if the man-pages on the system are compressed, and if +dnl so, what format is used. Use this information to construct a script that +dnl will install man-pages. +AC_DEFUN([CF_MAN_PAGES], +[ +CF_HELP_MESSAGE(Options to Specify How Manpages are Installed:) +CF_MANPAGE_FORMAT +CF_MANPAGE_RENAMES +CF_MANPAGE_SYMLINKS +CF_MANPAGE_TBL + + if test "$prefix" = "NONE" ; then + cf_prefix="$ac_default_prefix" + else + cf_prefix="$prefix" + fi + + case "$cf_manpage_form" in # (vi + *formatted*) # (vi + cf_subdir='$mandir/cat' + cf_format=yes + ;; + *) + cf_subdir='$mandir/man' + cf_format=no + ;; + esac + +test ! -d man && mkdir man +cat >man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <\$TMP +CF_EOF +else +cat >>man/edit_man.sh <\$TMP +CF_EOF +fi +if test $cf_manpage_tbl = yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +if test $with_curses_h != yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +if test $cf_format = yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +case "$cf_manpage_form" in #(vi +*compress*) #(vi +cat >>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh < + #include + ], + [double x = rand(); printf("result = %g\n", ]ifelse($2,,sin(x),$2)[)], + [cf_cv_need_libm=no], + [cf_cv_need_libm=yes])]) +if test "$cf_cv_need_libm" = yes +then +ifelse($1,,[ + LIBS="$LIBS -lm" +],[$1=-lm]) +fi +]) +dnl --------------------------------------------------------------------------- +dnl Check if the file-system supports mixed-case filenames. If we're able to +dnl create a lowercase name and see it as uppercase, it doesn't support that. +AC_DEFUN([CF_MIXEDCASE_FILENAMES], +[ +AC_CACHE_CHECK(if filesystem supports mixed-case filenames,cf_cv_mixedcase,[ + rm -f conftest CONFTEST + echo test >conftest + if test -f CONFTEST ; then + cf_cv_mixedcase=no + else + cf_cv_mixedcase=yes + fi + rm -f conftest CONFTEST +]) +test "$cf_cv_mixedcase" = yes && AC_DEFINE(MIXEDCASE_FILENAMES) +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute the object-directory name from the given model name +AC_DEFUN([CF_OBJ_SUBDIR], +[ + case $1 in + libtool) $2='obj_lo' ;; + normal) $2='objects' ;; + debug) $2='obj_g' ;; + profile) $2='obj_p' ;; + shared) $2='obj_s' ;; + esac +])dnl +dnl --------------------------------------------------------------------------- +dnl Check the argument to see that it looks like a pathname. Rewrite it if it +dnl begins with one of the prefix/exec_prefix variables, and then again if the +dnl result begins with 'NONE'. This is necessary to workaround autoconf's +dnl delayed evaluation of those symbols. +AC_DEFUN([CF_PATH_SYNTAX],[ +case ".[$]$1" in #(vi +./*) #(vi + ;; +.[a-zA-Z]:[\\/]*) #(vi OS/2 EMX + ;; +.\[$]{*prefix}*) #(vi + eval $1="[$]$1" + case ".[$]$1" in #(vi + .NONE/*) + $1=`echo [$]$1 | sed -e s@NONE@$ac_default_prefix@` + ;; + esac + ;; #(vi +.NONE/*) + $1=`echo [$]$1 | sed -e s@NONE@$ac_default_prefix@` + ;; +*) + AC_ERROR(expected a pathname) + ;; +esac +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute $PROG_EXT, used for non-Unix ports, such as OS/2 EMX. +AC_DEFUN([CF_PROG_EXT], +[ +AC_REQUIRE([CF_CHECK_CACHE]) +PROG_EXT= +case $cf_cv_system_name in +os2*) + # We make sure -Zexe is not used -- it would interfere with @PROG_EXT@ + CFLAGS="$CFLAGS -Zmt -D__ST_MT_ERRNO__" + CXXFLAGS="$CXXFLAGS -Zmt -D__ST_MT_ERRNO__" + LDFLAGS=`echo "$LDFLAGS -Zmt -Zcrtdll" | sed "s/-Zexe//g"` + PROG_EXT=".exe" + ;; +cygwin*) + PROG_EXT=".exe" + ;; +esac +AC_SUBST(PROG_EXT) +])dnl +dnl --------------------------------------------------------------------------- +dnl Force $INSTALL to be an absolute-path. Otherwise, edit_man.sh and the +dnl misc/tabset install won't work properly. Usually this happens only when +dnl using the fallback mkinstalldirs script +AC_DEFUN([CF_PROG_INSTALL], +[AC_PROG_INSTALL +case $INSTALL in +/*) + ;; +*) +changequote({{,}})dnl + cf_dir=`echo $INSTALL|sed -e 's%/[^/]*$%%'` + test -z "$cf_dir" && cf_dir=. +changequote([,])dnl + INSTALL=`cd $cf_dir && pwd`/`echo $INSTALL | sed -e 's:^.*/::'` + ;; +esac +])dnl +dnl --------------------------------------------------------------------------- +dnl Attempt to determine if we've got one of the flavors of regular-expression +dnl code that we can support. +AC_DEFUN([CF_REGEX], +[ +AC_MSG_CHECKING([for regular-expression headers]) +AC_CACHE_VAL(cf_cv_regex,[ +AC_TRY_LINK([#include +#include ],[ + regex_t *p; + int x = regcomp(p, "", 0); + int y = regexec(p, "", 0, 0, 0); + regfree(p); + ],[cf_cv_regex="regex.h"],[ + AC_TRY_LINK([#include ],[ + char *p = compile("", "", "", 0); + int x = step("", ""); + ],[cf_cv_regex="regexp.h"],[ + cf_save_LIBS="$LIBS" + LIBS="-lgen $LIBS" + AC_TRY_LINK([#include ],[ + char *p = compile("", "", ""); + int x = step("", ""); + ],[cf_cv_regex="regexpr.h"],[LIBS="$cf_save_LIBS"])])]) +]) +AC_MSG_RESULT($cf_cv_regex) +case $cf_cv_regex in + regex.h) AC_DEFINE(HAVE_REGEX_H_FUNCS) ;; + regexp.h) AC_DEFINE(HAVE_REGEXP_H_FUNCS) ;; + regexpr.h) AC_DEFINE(HAVE_REGEXPR_H_FUNCS) ;; +esac +])dnl +dnl --------------------------------------------------------------------------- +dnl Attempt to determine the appropriate CC/LD options for creating a shared +dnl library. +dnl +dnl Note: $(LOCAL_LDFLAGS) is used to link executables that will run within the +dnl build-tree, i.e., by making use of the libraries that are compiled in ../lib +dnl We avoid compiling-in a ../lib path for the shared library since that can +dnl lead to unexpected results at runtime. +dnl $(LOCAL_LDFLAGS2) has the same intention but assumes that the shared libraries +dnl are compiled in ../../lib +dnl +dnl The variable 'cf_cv_do_symlinks' is used to control whether we configure +dnl to install symbolic links to the rel/abi versions of shared libraries. +dnl +dnl The variable 'cf_cv_shlib_version' controls whether we use the rel or abi +dnl version when making symbolic links. +dnl +dnl Some loaders leave 'so_locations' lying around. It's nice to clean up. +AC_DEFUN([CF_SHARED_OPTS], +[ + AC_REQUIRE([CF_SUBST_NCURSES_VERSION]) + LOCAL_LDFLAGS= + LOCAL_LDFLAGS2= + LD_SHARED_OPTS= + INSTALL_LIB="-m 644" + + cf_cv_do_symlinks=no + + AC_MSG_CHECKING(if release/abi version should be used for shared libs) + AC_ARG_WITH(shlib-version, + [ --with-shlib-version=X Specify rel or abi version for shared libs], + [test -z "$withval" && withval=auto + case $withval in #(vi + yes) #(vi + cf_cv_shlib_version=auto + ;; + rel|abi|auto|no) #(vi + cf_cv_shlib_version=$withval + ;; + *) + AC_ERROR([option value must be one of: rel, abi, auto or no]) + ;; + esac + ],[cf_cv_shlib_version=auto]) + AC_MSG_RESULT($cf_cv_shlib_version) + + cf_cv_rm_so_locs=no + + # Some less-capable ports of gcc support only -fpic + CC_SHARED_OPTS= + if test "$GCC" = yes + then + AC_MSG_CHECKING(which $CC option to use) + cf_save_CFLAGS="$CFLAGS" + for CC_SHARED_OPTS in -fPIC -fpic '' + do + CFLAGS="$cf_save_CFLAGS $CC_SHARED_OPTS" + AC_TRY_COMPILE([#include ],[int x = 1],[break],[]) + done + AC_MSG_RESULT($CC_SHARED_OPTS) + CFLAGS="$cf_save_CFLAGS" + fi + + case $cf_cv_system_name in + beos*) + MK_SHARED_LIB='$(CC) -o $[@] -Xlinker -soname=`basename $[@]` -nostart -e 0' + ;; + hpux*) + # (tested with gcc 2.7.2 -- I don't have c89) + if test "$GCC" = yes; then + LD_SHARED_OPTS='-Xlinker +b -Xlinker $(libdir)' + else + CC_SHARED_OPTS='+Z' + LD_SHARED_OPTS='-Wl,+b,$(libdir)' + fi + MK_SHARED_LIB='$(LD) +b $(libdir) -b -o $[@]' + # HP-UX shared libraries must be executable, and should be + # readonly to exploit a quirk in the memory manager. + INSTALL_LIB="-m 555" + ;; + irix*) + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-Wl,-rpath," + EXTRA_LDFLAGS="-Wl,-rpath,\$(libdir) $EXTRA_LDFLAGS" + fi + # tested with IRIX 5.2 and 'cc'. + if test "$GCC" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -shared -rdata_shared -soname `basename $[@]` -o $[@]' + cf_cv_rm_so_locs=yes + ;; + linux*|gnu*) + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-Wl,-rpath," + EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + MK_SHARED_LIB='$(CC) -shared -Wl,-soname,`basename $[@] .$(REL_VERSION)`.$(ABI_VERSION),-stats,-lc -o $[@]' + ;; + openbsd2*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + MK_SHARED_LIB='$(LD) -Bshareable -soname,`basename $[@].$(ABI_VERSION)` -o $[@]' + ;; + openbsd*|freebsd*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + MK_SHARED_LIB='$(LD) -Bshareable -o $[@]' + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + netbsd*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + test "$cf_cv_ld_rpath" = yes && cf_ld_rpath_opt="-Wl,-rpath," + if test "$DFT_LWR_MODEL" = "shared" && test "$cf_cv_ld_rpath" = yes ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + EXTRA_LDFLAGS="-Wl,-rpath,\$(libdir) $EXTRA_LDFLAGS" + MK_SHARED_LIB='$(CC) -shared -Wl,-soname,`basename $[@] .$(REL_VERSION)`.$(ABI_VERSION) -o $[@]' + if test "$cf_cv_shlib_version" = auto; then + if test ! -f /usr/libexec/ld.elf_so; then + cf_cv_shlib_version=rel + fi + fi + else + MK_SHARED_LIB='$(LD) -Bshareable -o $[@]' + fi + ;; + osf*|mls+*) + # tested with OSF/1 V3.2 and 'cc' + # tested with OSF/1 V3.2 and gcc 2.6.3 (but the c++ demo didn't + # link with shared libs). + MK_SHARED_LIB='$(LD) -set_version $(REL_VERSION):$(ABI_VERSION) -expect_unresolved "*" -shared -soname `basename $[@]`' + case $host_os in + osf4*) + MK_SHARED_LIB="${MK_SHARED_LIB} -msym" + ;; + esac + MK_SHARED_LIB="${MK_SHARED_LIB}"' -o $[@]' + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-rpath" + # EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + cf_cv_rm_so_locs=yes + ;; + sco3.2v5*) # (also uw2* and UW7) hops 13-Apr-98 + # tested with osr5.0.5 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-belf -KPIC' + fi + MK_SHARED_LIB='$(LD) -dy -G -h `basename $[@] .$(REL_VERSION)`.$(ABI_VERSION) -o [$]@' + if test "$cf_cv_ld_rpath" = yes ; then + # only way is to set LD_RUN_PATH but no switch for it + RUN_PATH=$libdir + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + LINK_PROGS='LD_RUN_PATH=$(libdir)' + LINK_TESTS='Pwd=`pwd`;LD_RUN_PATH=`dirname $${Pwd}`/lib' + ;; + sunos4*) + # tested with SunOS 4.1.1 and gcc 2.7.0 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -assert pure-text -o $[@]' + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + solaris2*) + # tested with SunOS 5.5.1 (solaris 2.5.1) and gcc 2.7.2 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -dy -G -h `basename $[@] .$(REL_VERSION)`.$(ABI_VERSION) -o $[@]' + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-R `pwd`/lib:\$(libdir)" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-R" + EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + sysv5uw7*|unix_sv*) + # tested with UnixWare 7.1.0 (gcc 2.95.2 and cc) + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -d y -G -o [$]@' + ;; + *) + CC_SHARED_OPTS='unknown' + MK_SHARED_LIB='echo unknown' + ;; + esac + + # This works if the last tokens in $MK_SHARED_LIB are the -o target. + case "$cf_cv_shlib_version" in #(vi + rel|abi) + case "$MK_SHARED_LIB" in #(vi + *'-o $[@]') + test "$cf_cv_do_symlinks" = no && cf_cv_do_symlinks=yes + ;; + *) + AC_MSG_WARN(ignored --with-shlib-version) + ;; + esac + ;; + esac + + if test -n "$cf_ld_rpath_opt" ; then + AC_MSG_CHECKING(if we need a space after rpath option) + cf_save_LIBS="$LIBS" + LIBS="$LIBS ${cf_ld_rpath_opt}$libdir" + AC_TRY_LINK(, , cf_rpath_space=no, cf_rpath_space=yes) + LIBS="$cf_save_LIBS" + AC_MSG_RESULT($cf_rpath_space) + test "$cf_rpath_space" = yes && cf_ld_rpath_opt="$cf_ld_rpath_opt " + MK_SHARED_LIB="$MK_SHARED_LIB $cf_ld_rpath_opt\$(libdir)" + fi + + AC_SUBST(CC_SHARED_OPTS) + AC_SUBST(LD_SHARED_OPTS) + AC_SUBST(MK_SHARED_LIB) + AC_SUBST(LINK_PROGS) + AC_SUBST(LINK_TESTS) + AC_SUBST(EXTRA_LDFLAGS) + AC_SUBST(LOCAL_LDFLAGS) + AC_SUBST(LOCAL_LDFLAGS2) + AC_SUBST(INSTALL_LIB) +])dnl +dnl --------------------------------------------------------------------------- +dnl Check for definitions & structures needed for window size-changing +dnl FIXME: check that this works with "snake" (HP-UX 10.x) +AC_DEFUN([CF_SIZECHANGE], +[ +AC_REQUIRE([CF_STRUCT_TERMIOS]) +AC_CACHE_CHECK(declaration of size-change, cf_cv_sizechange,[ + cf_cv_sizechange=unknown + cf_save_CFLAGS="$CFLAGS" + +for cf_opts in "" "NEED_PTEM_H" +do + + CFLAGS="$cf_save_CFLAGS" + test -n "$cf_opts" && CFLAGS="$CFLAGS -D$cf_opts" + AC_TRY_COMPILE([#include +#ifdef HAVE_TERMIOS_H +#include +#else +#ifdef HAVE_TERMIO_H +#include +#endif +#endif +#ifdef NEED_PTEM_H +/* This is a workaround for SCO: they neglected to define struct winsize in + * termios.h -- it's only in termio.h and ptem.h + */ +#include +#include +#endif +#if !defined(sun) || !defined(HAVE_TERMIOS_H) +#include +#endif +],[ +#ifdef TIOCGSIZE + struct ttysize win; /* FIXME: what system is this? */ + int y = win.ts_lines; + int x = win.ts_cols; +#else +#ifdef TIOCGWINSZ + struct winsize win; + int y = win.ws_row; + int x = win.ws_col; +#else + no TIOCGSIZE or TIOCGWINSZ +#endif /* TIOCGWINSZ */ +#endif /* TIOCGSIZE */ + ], + [cf_cv_sizechange=yes], + [cf_cv_sizechange=no]) + + CFLAGS="$cf_save_CFLAGS" + if test "$cf_cv_sizechange" = yes ; then + echo "size-change succeeded ($cf_opts)" >&AC_FD_CC + test -n "$cf_opts" && cf_cv_sizechange="$cf_opts" + break + fi +done +]) +if test "$cf_cv_sizechange" != no ; then + AC_DEFINE(HAVE_SIZECHANGE) + case $cf_cv_sizechange in #(vi + NEED*) + AC_DEFINE_UNQUOTED($cf_cv_sizechange ) + ;; + esac +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl For each parameter, test if the source-directory exists, and if it contains +dnl a 'modules' file. If so, add to the list $cf_cv_src_modules which we'll +dnl use in CF_LIB_RULES. +dnl +dnl This uses the configured value to make the lists SRC_SUBDIRS and +dnl SUB_MAKEFILES which are used in the makefile-generation scheme. +AC_DEFUN([CF_SRC_MODULES], +[ +AC_MSG_CHECKING(for src modules) + +# dependencies and linker-arguments for test-programs +TEST_DEPS="${LIB_DIR}/${LIB_PREFIX}${LIB_NAME}${DFT_DEP_SUFFIX} $TEST_DEPS" +if test "$DFT_LWR_MODEL" = "libtool"; then + TEST_ARGS="${TEST_DEPS}" +else + TEST_ARGS="-l${LIB_NAME}${DFT_ARG_SUFFIX} $TEST_ARGS" +fi + +# dependencies and linker-arguments for utility-programs +PROG_ARGS="$TEST_ARGS" + +cf_cv_src_modules= +for cf_dir in $1 +do + if test -f $srcdir/$cf_dir/modules; then + + # We may/may not have tack in the distribution, though the + # makefile is. + if test $cf_dir = tack ; then + if test ! -f $srcdir/${cf_dir}/${cf_dir}.h; then + continue + fi + fi + + if test -z "$cf_cv_src_modules"; then + cf_cv_src_modules=$cf_dir + else + cf_cv_src_modules="$cf_cv_src_modules $cf_dir" + fi + + # Make the ncurses_cfg.h file record the library interface files as + # well. These are header files that are the same name as their + # directory. Ncurses is the only library that does not follow + # that pattern. + if test $cf_dir = tack ; then + continue + elif test -f $srcdir/${cf_dir}/${cf_dir}.h; then + CF_UPPER(cf_have_include,$cf_dir) + AC_DEFINE_UNQUOTED(HAVE_${cf_have_include}_H) + AC_DEFINE_UNQUOTED(HAVE_LIB${cf_have_include}) + TEST_DEPS="${LIB_DIR}/${LIB_PREFIX}${cf_dir}${DFT_DEP_SUFFIX} $TEST_DEPS" + if test "$DFT_LWR_MODEL" = "libtool"; then + TEST_ARGS="${TEST_DEPS}" + else + TEST_ARGS="-l${cf_dir}${DFT_ARG_SUFFIX} $TEST_ARGS" + fi + fi + fi +done +AC_MSG_RESULT($cf_cv_src_modules) +TEST_ARGS="-L${LIB_DIR} -L\$(libdir) $TEST_ARGS" +AC_SUBST(TEST_DEPS) +AC_SUBST(TEST_ARGS) + +PROG_ARGS="-L${LIB_DIR} -L\$(libdir) $PROG_ARGS" +AC_SUBST(PROG_ARGS) + +SRC_SUBDIRS="man include" +for cf_dir in $cf_cv_src_modules +do + SRC_SUBDIRS="$SRC_SUBDIRS $cf_dir" +done +SRC_SUBDIRS="$SRC_SUBDIRS misc test" +test "$cf_with_cxx_binding" != no && SRC_SUBDIRS="$SRC_SUBDIRS c++" + +ADA_SUBDIRS= +if test "$cf_cv_prog_gnat_correct" = yes && test -f $srcdir/Ada95/Makefile.in; then + SRC_SUBDIRS="$SRC_SUBDIRS Ada95" + ADA_SUBDIRS="gen src samples" +fi + +SUB_MAKEFILES= +for cf_dir in $SRC_SUBDIRS +do + SUB_MAKEFILES="$SUB_MAKEFILES $cf_dir/Makefile" +done + +if test -n "$ADA_SUBDIRS"; then + for cf_dir in $ADA_SUBDIRS + do + SUB_MAKEFILES="$SUB_MAKEFILES Ada95/$cf_dir/Makefile" + done + AC_SUBST(ADA_SUBDIRS) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Check for -lstdc++, which is GNU's standard C++ library. +AC_DEFUN([CF_STDCPP_LIBRARY], +[ +if test -n "$GXX" ; then +case $cf_cv_system_name in #(vi +os2*) #(vi + cf_stdcpp_libname=stdcpp + ;; +*) + cf_stdcpp_libname=stdc++ + ;; +esac +AC_CACHE_CHECK(for library $cf_stdcpp_libname,cf_cv_libstdcpp,[ + cf_save="$LIBS" + LIBS="$LIBS -l$cf_stdcpp_libname" +AC_TRY_LINK([ +#include ],[ +char buf[80]; +strstreambuf foo(buf, sizeof(buf)) +], + [cf_cv_libstdcpp=yes], + [cf_cv_libstdcpp=no]) + LIBS="$cf_save" +]) +test "$cf_cv_libstdcpp" = yes && CXXLIBS="$CXXLIBS -l$cf_stdcpp_libname" +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Remove "-g" option from the compiler options +AC_DEFUN([CF_STRIP_G_OPT], +[$1=`echo ${$1} | sed -e 's/-g //' -e 's/-g$//'`])dnl +dnl --------------------------------------------------------------------------- +dnl Check if we need _POSIX_SOURCE defined to use struct sigaction. We'll only +dnl do this if we've found the sigaction function. +dnl +dnl If needed, define SVR4_ACTION. +AC_DEFUN([CF_STRUCT_SIGACTION],[ +if test "$ac_cv_func_sigaction" = yes; then +AC_MSG_CHECKING(whether sigaction needs _POSIX_SOURCE) +AC_TRY_COMPILE([ +#include +#include ], + [struct sigaction act], + [sigact_bad=no], + [ +AC_TRY_COMPILE([ +#define _POSIX_SOURCE +#include +#include ], + [struct sigaction act], + [sigact_bad=yes + AC_DEFINE(SVR4_ACTION)], + [sigact_bad=unknown])]) +AC_MSG_RESULT($sigact_bad) +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Some machines require _POSIX_SOURCE to completely define struct termios. +dnl If so, define SVR4_TERMIO +AC_DEFUN([CF_STRUCT_TERMIOS],[ +AC_CHECK_HEADERS( \ +termio.h \ +termios.h \ +unistd.h \ +) +if test "$ISC" = yes ; then + AC_CHECK_HEADERS( sys/termio.h ) +fi +if test "$ac_cv_header_termios_h" = yes ; then + case "$CFLAGS" in + *-D_POSIX_SOURCE*) + termios_bad=dunno ;; + *) termios_bad=maybe ;; + esac + if test "$termios_bad" = maybe ; then + AC_MSG_CHECKING(whether termios.h needs _POSIX_SOURCE) + AC_TRY_COMPILE([#include ], + [struct termios foo; int x = foo.c_iflag], + termios_bad=no, [ + AC_TRY_COMPILE([ +#define _POSIX_SOURCE +#include ], + [struct termios foo; int x = foo.c_iflag], + termios_bad=unknown, + termios_bad=yes AC_DEFINE(SVR4_TERMIO)) + ]) + AC_MSG_RESULT($termios_bad) + fi +fi +])dnl +dnl --------------------------------------------------------------------------- +dnl Shorthand macro for substituting things that the user may override +dnl with an environment variable. +dnl +dnl $1 = long/descriptive name +dnl $2 = environment variable +dnl $3 = default value +AC_DEFUN([CF_SUBST], +[AC_CACHE_VAL(cf_cv_subst_$2,[ +AC_MSG_CHECKING(for $1 (symbol $2)) +test -z "[$]$2" && $2=$3 +AC_MSG_RESULT([$]$2) +AC_SUBST($2) +cf_cv_subst_$2=[$]$2]) +$2=${cf_cv_subst_$2} +])dnl +dnl --------------------------------------------------------------------------- +dnl Get the version-number for use in shared-library naming, etc. +AC_DEFUN([CF_SUBST_NCURSES_VERSION], +[ +changequote(,)dnl +NCURSES_MAJOR="`egrep '^NCURSES_MAJOR[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +NCURSES_MINOR="`egrep '^NCURSES_MINOR[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +NCURSES_PATCH="`egrep '^NCURSES_PATCH[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +changequote([,])dnl +cf_cv_abi_version=${NCURSES_MAJOR} +cf_cv_rel_version=${NCURSES_MAJOR}.${NCURSES_MINOR} +dnl Show the computed version, for logging +AC_MSG_RESULT(Configuring NCURSES $cf_cv_rel_version ABI $cf_cv_abi_version (`date`)) +dnl We need these values in the generated headers +AC_SUBST(NCURSES_MAJOR) +AC_SUBST(NCURSES_MINOR) +AC_SUBST(NCURSES_PATCH) +dnl We need these values in the generated makefiles +AC_SUBST(cf_cv_rel_version) +AC_SUBST(cf_cv_abi_version) +AC_SUBST(cf_cv_cc_bool_type) +AC_SUBST(cf_cv_builtin_bool) +AC_SUBST(cf_cv_type_of_bool)dnl +])dnl +dnl --------------------------------------------------------------------------- +dnl Check if we can include with ; this breaks on +dnl older SCO configurations. +AC_DEFUN([CF_SYS_TIME_SELECT], +[ +AC_MSG_CHECKING(if sys/time.h works with sys/select.h) +AC_CACHE_VAL(cf_cv_sys_time_select,[ +AC_TRY_COMPILE([ +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif +],[],[cf_cv_sys_time_select=yes], + [cf_cv_sys_time_select=no]) + ]) +AC_MSG_RESULT($cf_cv_sys_time_select) +test "$cf_cv_sys_time_select" = yes && AC_DEFINE(HAVE_SYS_TIME_SELECT) +])dnl +dnl --------------------------------------------------------------------------- +dnl Determine the type we should use for chtype (and attr_t, which is treated +dnl as the same thing). We want around 32 bits, so on most machines want a +dnl long, but on newer 64-bit machines, probably want an int. If we're using +dnl wide characters, we have to have a type compatible with that, as well. +AC_DEFUN([CF_TYPEOF_CHTYPE], +[ +AC_REQUIRE([CF_UNSIGNED_LITERALS]) +AC_MSG_CHECKING([for type of chtype]) +AC_CACHE_VAL(cf_cv_typeof_chtype,[ + AC_TRY_RUN([ +#ifdef USE_WIDEC_SUPPORT +#include /* we want wchar_t */ +#define WANT_BITS 39 +#else +#define WANT_BITS 31 +#endif +#include +int main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + char *result = "long"; +#ifdef USE_WIDEC_SUPPORT + /* + * If wchar_t is smaller than a long, it must be an int or a + * short. We prefer not to use a short anyway. + */ + if (sizeof(unsigned long) > sizeof(wchar_t)) + result = "int"; +#endif + if (sizeof(unsigned long) > sizeof(unsigned int)) { + int n; + unsigned int x; + for (n = 0; n < WANT_BITS; n++) { + unsigned int y = (x >> n); + if (y != 1 || x == 0) { + x = 0; + break; + } + } + /* + * If x is nonzero, an int is big enough for the bits + * that we want. + */ + result = (x != 0) ? "int" : "long"; + } + fputs(result, fp); + fclose(fp); + } + exit(0); +} + ], + [cf_cv_typeof_chtype=`cat cf_test.out`], + [cf_cv_typeof_chtype=long], + [cf_cv_typeof_chtype=long]) + rm -f cf_test.out + ]) +AC_MSG_RESULT($cf_cv_typeof_chtype) + +AC_SUBST(cf_cv_typeof_chtype) +AC_DEFINE_UNQUOTED(TYPEOF_CHTYPE,$cf_cv_typeof_chtype) + +cf_cv_1UL="1" +test "$cf_cv_unsigned_literals" = yes && cf_cv_1UL="${cf_cv_1UL}U" +test "$cf_cv_typeof_chtype" = long && cf_cv_1UL="${cf_cv_1UL}L" +AC_SUBST(cf_cv_1UL) + +])dnl +dnl --------------------------------------------------------------------------- +dnl +AC_DEFUN([CF_TYPE_SIGACTION], +[ +AC_MSG_CHECKING([for type sigaction_t]) +AC_CACHE_VAL(cf_cv_type_sigaction,[ + AC_TRY_COMPILE([ +#include ], + [sigaction_t x], + [cf_cv_type_sigaction=yes], + [cf_cv_type_sigaction=no])]) +AC_MSG_RESULT($cf_cv_type_sigaction) +test "$cf_cv_type_sigaction" = yes && AC_DEFINE(HAVE_TYPE_SIGACTION) +])dnl +dnl --------------------------------------------------------------------------- +dnl Test if the compiler supports 'U' and 'L' suffixes. Only old compilers +dnl won't, but they're still there. +AC_DEFUN([CF_UNSIGNED_LITERALS], +[ +AC_MSG_CHECKING([if unsigned literals are legal]) +AC_CACHE_VAL(cf_cv_unsigned_literals,[ + AC_TRY_COMPILE([],[long x = 1L + 1UL + 1U + 1], + [cf_cv_unsigned_literals=yes], + [cf_cv_unsigned_literals=no]) + ]) +AC_MSG_RESULT($cf_cv_unsigned_literals) +])dnl +dnl --------------------------------------------------------------------------- +dnl Make an uppercase version of a variable +dnl $1=uppercase($2) +AC_DEFUN([CF_UPPER], +[ +changequote(,)dnl +$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` +changequote([,])dnl +])dnl +dnl --------------------------------------------------------------------------- +dnl Compute the shift-mask that we'll use for wide-character indices. We use +dnl all but the index portion of chtype for storing attributes. +AC_DEFUN([CF_WIDEC_SHIFT], +[ +AC_REQUIRE([CF_TYPEOF_CHTYPE]) +AC_MSG_CHECKING([for number of bits in chtype]) +AC_CACHE_VAL(cf_cv_shift_limit,[ + AC_TRY_RUN([ +#include +int main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + int n; + unsigned TYPEOF_CHTYPE x = 1L; + for (n = 0; ; n++) { + unsigned long y = (x >> n); + if (y != 1 || x == 0) + break; + x <<= 1; + } + fprintf(fp, "%d", n); + fclose(fp); + } + exit(0); +} + ], + [cf_cv_shift_limit=`cat cf_test.out`], + [cf_cv_shift_limit=32], + [cf_cv_shift_limit=32]) + rm -f cf_test.out + ]) +AC_MSG_RESULT($cf_cv_shift_limit) +AC_SUBST(cf_cv_shift_limit) + +AC_MSG_CHECKING([for width of character-index]) +AC_CACHE_VAL(cf_cv_widec_shift,[ +if test ".$with_widec" = ".yes" ; then + cf_attrs_width=39 + if ( expr $cf_cv_shift_limit \> $cf_attrs_width >/dev/null ) + then + cf_cv_widec_shift=`expr 16 + $cf_cv_shift_limit - $cf_attrs_width` + else + cf_cv_widec_shift=16 + fi +else + cf_cv_widec_shift=8 +fi +]) +AC_MSG_RESULT($cf_cv_widec_shift) +AC_SUBST(cf_cv_widec_shift) +])dnl +dnl --------------------------------------------------------------------------- +dnl Wrapper for AC_ARG_WITH to ensure that user supplies a pathname, not just +dnl defaulting to yes/no. +dnl +dnl $1 = option name +dnl $2 = help-text +dnl $3 = environment variable to set +dnl $4 = default value, shown in the help-message, must be a constant +dnl $5 = default value, if it's an expression & cannot be in the help-message +dnl +AC_DEFUN([CF_WITH_PATH], +[AC_ARG_WITH($1,[$2 ](default: ifelse($4,,empty,$4)),, +ifelse($4,,[withval="${$3}"],[withval="${$3-ifelse($5,,$4,$5)}"]))dnl +CF_PATH_SYNTAX(withval) +eval $3="$withval" +AC_SUBST($3)dnl +])dnl +dnl --------------------------------------------------------------------------- +dnl Process an option specifying a list of colon-separated paths. +dnl +dnl $1 = option name +dnl $2 = help-text +dnl $3 = environment variable to set +dnl $4 = default value, shown in the help-message, must be a constant +dnl $5 = default value, if it's an expression & cannot be in the help-message +dnl +AC_DEFUN([CF_WITH_PATHLIST],[ +AC_ARG_WITH($1,[$2 ](default: ifelse($4,,empty,$4)),, +ifelse($4,,[withval="${$3}"],[withval="${$3-ifelse($5,,$4,$5)}"]))dnl + +IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" +cf_dst_path= +for cf_src_path in $withval +do + CF_PATH_SYNTAX(cf_src_path) + test -n "$cf_dst_path" && cf_dst_path="${cf_dst_path}:" + cf_dst_path="${cf_dst_path}${cf_src_path}" +done +IFS="$ac_save_ifs" + +eval $3="$cf_dst_path" +AC_SUBST($3)dnl +])dnl diff --git a/ncurses-5.2/announce.html.in b/ncurses-5.2/announce.html.in new file mode 100644 index 0000000..c8cd852 --- /dev/null +++ b/ncurses-5.2/announce.html.in @@ -0,0 +1,593 @@ + + + + +Announcing ncurses @VERSION@ + + + + +

    Announcing ncurses @VERSION@

    + +The ncurses (new curses) library is a free software emulation of +curses in System V Release 4.0, and more. It uses terminfo format, +supports pads and color +and multiple highlights and forms characters and function-key mapping, +and has all the other SYSV-curses enhancements over BSD curses.

    + +In mid-June 1995, the maintainer of 4.4BSD curses declared that he +considered 4.4BSD curses obsolete, and is encouraging the keepers of +Unix releases such as BSD/OS, freeBSD and netBSD to switch over to +ncurses.

    + +The ncurses code was developed under GNU/Linux. It should port easily to +any ANSI/POSIX-conforming UNIX. It has even been ported to OS/2 Warp!

    + +The distribution includes the library and support utilities, including a +terminfo compiler tic(1), a decompiler infocmp(1), clear(1), tput(1), tset(1), +and a termcap conversion tool captoinfo(1). Full manual pages are provided for +the library and tools.

    + +The ncurses distribution is available via anonymous FTP at +the GNU distribution site +ftp://ftp.gnu.org/pub/gnu/ncurses. +
    It is also available at +ftp://dickey.his.com/ncurses. + +

    Release Notes

    + +This release is designed to be upward compatible from ncurses 5.0 and 5.1; +very few applications will require recompilation, depending on the platform. +These are the highlights from the change-log since ncurses 5.1 release. +

    +Interface changes: +

      +
    • change type of ospeed variable back to + short to match its use in legacy applications. It was + altered after ncurses 4.2 to speed_t to repair a type + mismatch which was introduced after 1.9.4 in 1995. The principal + users of termcap continued to use short, which is + not the same size. +

      + NOTE: A few applications will have to be recompiled + (about 1% of the programs in a typical Linux distribution, + 10% of the programs that use ncurses). These are easy to + identify with nm or strings. + +

    • remove a private function _nc_can_clear_with(), which + was built with the configure --enable-expanded option but not used. + +
    • add several private functions (prefixed with "_nc_") for tracing + chtype values in the debug library, and for better + access and buffer limit checking. +
    +New features and improvements: +
      +
    • rewrote tgoto() to make it better support existing + termcap applications which use hardcoded strings rather than obtain + all of their information from the termcap file. If the string does + not appear to be a terminfo string (i.e., does not refer to a "%p" + parameter, or terminfo-style padding), and termcap support is configured, tgoto() + will interpret it as termcap. Otherwise, as before, it will use + tparm(). + +
    • to ensure that the tgoto() changes work properly, + added checks to tic which report capabilities that do + not reference the expected number of parameters. + +
    • new configure script options: +
        +
      • option --disable-root-environ adds runtime checks + which tell ncurses to disregard $TERMINFO and similar environment + variables if the current user is root, or running setuid/setgid. + +
      • option --disable-assumed-color allows you to use the + pre-5.1 convention of default colors used for color-pair 0 to be + configured (see assume_default_colors()). + +
      • implement configure script options that transform installed + program names, e.g., --program-prefix, including the + manpage names and cross references. + +
      • option --with-database allows you to specify a + different terminfo source-file to install. On OS/2 EMX, the + default is misc/emx.src, otherwise misc/terminfo.src + +
      • option --with-default-terminfo-dir allows you to + specify the default terminfo database directory. + +
      • option --with-libtool allows you to build with + libtool.

        NOTE: libtool + uses a different notation for numbering shared library versions + from the existing ncurses configuration. + +

      • option --with-manpage-tbl causes the manpages to be + preprocessed by tbl(1) prior to installation, + +
      • option --without-curses-h causes the installation + process to install curses.h as ncurses.h and make appropriate + changes to headers and manpages. +
      + +
    • modified configure script options: +
        +
      • change symbol used by the --install-prefix configure + option from INSTALL_PREFIX to DESTDIR + (the latter has become common usage although the name is + misleading). + +
      • modify ld -rpath options (e.g., Linux, and Solaris) + to use an absolute pathname for the build tree's lib directory, + avoiding confusion with directories relative to the current one + with the installed programs. + +
      • modified misc/run_tic.in to use + tic -o, to eliminate dependency on + $TERMINFO variable for installs. +
      + +
    • terminfo database: +
        +
      • updated xterm terminfo entries to match XFree86 xterm patch #146. + +
      • added amiga-vnc, + Matrix Orbital, and + QNX qansi to misc/terminfo.src. + +
      • added os2 entry to misc/emx.src. + +
      • add S0 and E0 extensions to screen's terminfo entry + since otherwise the FreeBSD port makes it pass termcap equivalents + to tgoto, which would be misinterpreted by older + versions of ncurses. +
      + +
    • improvements to program usability: +
        +
      • modify programs to use curses_version() string to + report the version of ncurses with which they are compiled rather + than the NCURSES_VERSION string. The function returns the patch + level in addition to the major and minor version numbers. + +
      • modify tput program so it can be renamed or invoked via a link as + 'reset' or 'init', producing the same effect as tput reset or tput init. + +
      • add error checking to infocmp's -v and -m options to ensure that + the option value is indeed a number. +
      + +
    • improved performance: +
        +
      • replace a lookup table in lib_vidattr.c used to decode + no_color_video with a logic expression which is faster. +
      + +
    +Major bug fixes: +
      +
    • correct manlinks.sed script introduced in ncurses 5.1 + to avoid using ERE "\+", which is not understood by standard versions + of sed. This happens to work with GNU sed, + but is not portable, and was the initial motivation for this release. + +
    • remove "hpux10.*" case from CF_SHARED_OPTS configure script macro. + This differed from the "hpux*" case by using reversed symbolic + links, which made the 5.1 version not match the configuration of + 5.0 shared libraries. + +
    • guard against corrupt terminfo data: +
        +
      • modify tparm() to disallow arithmetic on strings, + analyze the varargs list to read strings as strings and numbers as + numbers. + +
      • modify tparm()'s internal function + spop() to treat a null pointer as an empty string. + +
      • modify parse_format() in lib_tparm.c to ignore + precision if it is longer than 10000. + +
      • rewrote limit checks in lib_mvcur.c using new functions + _nc_safe_strcat(), etc. Made other related changes to + check lengths used for strcat() and + strcpy(). +
      + +
    • corrections to screen optimization: +
        +
      • added special case in lib_vidattr.c to reset underline and + standout for devices that have no sgr0 defined. + +
      • change handling of non_dest_scroll_region in + tty_update.c to clear text after it is shifted in rather than before + shifting out. Also correct row computation. + +
      • modify rs2 capability in xterm-r6 and similar entries + where cursor save/restore bracketed the sequence for resetting video + attributes. The cursor restore would undo that. +
      + +
    • UTF-8 support: +
        +
      • when checking LC_ALL, LC_CTYPE, and LANG environment variables + for UTF-8 locale, ignore those which are set to an empty value, as + per SUSV2. + +
      • encode 0xFFFD in UTF-8 with 3 bytes, not 2. + +
      • modify _nc_utf8_outch() to avoid sign-extension when + checking for out-of-range value. +
      + +
    • other library fixes: +
        +
      • added checks for an empty $HOME environment + variable, to avoid retrieving terminfo descriptions from + ./.terminfo . + +
      • change functions _nc_parse_entry() and + postprocess_termcap() to avoid using + strtok(), because it is non-reentrant. + +
      • initialize fds[] array to 0's in + _nc_timed_wait(); apparently poll() only + sets the revents members of that array when there is + activity corresponding to the related file. + +
      • add a check for null pointer in Make_Enum_Type(). + +
      • fix a heap problem with the c++ binding. + +
      • correct missing includes for <string.h> in several places, + including the C++ binding. This is not noted by gcc unless we use + the -fno-builtin option. +
      + +
    • several fixes for tic: +
        +
      • add a check for empty buffers returned by fgets() in + comp_scan.c next_char() function, in case + tic is run on a non-text file (fixes a core dump). + +
      • modify tic to verify that its inputs are really files, + in case someone tries to read a directory (or + /dev/zero). + +
      • correct an uninitialized parameter to open_tempfile() + in tic.c which made "tic -I" give an ambiguous error message about + tmpnam. + +
      • correct logic in adjust_cancels(), which did not check + both alternatives when reclassifying an extended name between + boolean, number and string, causing an infinite loop in + tic. +
      + +
    • using new checks in tic for parameter counts in + capability strings, found/fixed several errors both in the + terminfo database and in the include/Caps file. +
        +
      • modified several terminfo capability strings, including the + definitions for setaf, setab, in include/Caps to indicate that the + entries are parameterized. This information is used to tell which + strings are translated when converting to termcap. This fixes a + problem where the generated termcap would contain a spurious "%p1" + for the terminfo "%p1%d". + +
      • correct parameter counts in include/Caps for dclk as well as some + printer-specific capabilities: csnm, defc, scs, scsd, smgtp, smglp. +
      + +
    • various fixes for install scripts used to support configure + --srcdir and --with-install-prefix. + +
    • correct several mismatches between manpage filename and ".TH" + directives, renaming dft_fgbg.3x to default_colors.3x and + menu_attribs.3x to menu_attributes.3x. +
    + +Portability: +
      +
    • configure script: +
        +
      • newer config.guess, config.sub, including changes to support OS/2 + EMX. The configure script for OS/2 EMX still relies on a patch + since there is no (working) support for that platform in the main + autoconf distribution. + +
      • make configure script checks on variables $GCC and + $GXX consistently compare against 'yes' rather than + test if they are nonnull, since either may be set to the + corresponding name of the C or C++ compiler. + +
      • change configure script to use AC_CANONICAL_SYSTEM rather than + AC_CANONICAL_HOST, which means that configure --target + will set a default program-prefix. + +
      • modify the check for big-core to force a couple of memory + accesses, which may work as needed for older/less-capable machines + (if not, there's still the explicit configure option). + +
      • modify configure test for tcgetattr() to allow for + old implementations, e.g., on BeOS, which only defined it as a + macro. + +
      • add configure check for filesystems (such as OS/2 EMX) which do + not distinguish between upper/lowercase filenames, use this to fix + tags rules in makefiles. + +
      • add MKncurses_def.sh to generate fallback definitions for + ncurses_cfg.h, to quiet gcc -Wundef warnings, modified ifdef's in + code to consistently use "#if" rather than "#ifdef". + +
      • change most remaining unquoted parameters of test in + configure script to use quotes, for instance fixing a problem in the + --disable-database option. + +
      • modify scripts so that "make install.data" works on OS/2 EMX. + +
      • modify scripts and makefiles so the Ada95 directory builds on + OS/2 EMX. +
      + +
    • library: +
        +
      • replaced case-statement in _nc_tracebits() for CSIZE + with a table to simplify working around implementations that define + random combinations of the related macros to zero. + +
      • improved OS/2 mouse support by retrying as a 2-button mouse if code + fails to set up a 3-button mouse. + +
      • added private entrypoint _nc_basename(), used to + consolidate related code in progs, as well as accommodating OS/2 EMX + pathnames. + +
      • alter definition of NCURSES_CONST to make it non-empty. + +
      • redefine 'TEXT' in menu.h for AMIGA, since it is reported to have + an (unspecified) symbol conflict. +
      + +
    • programs: +
        +
      • modified progs/tset.c and tack/sysdep.c to build with sgttyb + interface if neither termio or termios is available. Tested this + with FreeBSD 2.1.5 (which does have termios - but the sgttyb does + work). +
      + +
    + +

    Features of Ncurses

    + +The ncurses package is fully compatible with SVr4 (System V Release 4) curses: + +
      +
    • All 257 of the SVr4 calls have been implemented (and are documented). +
    • Full support for SVr4 curses features including keyboard mapping, color, +forms-drawing with ACS characters, and automatic recognition of keypad +and function keys. +
    • An emulation of the SVr4 panels library, supporting +a stack of windows with backing store, is included. +
    • An emulation of the SVr4 menus library, supporting +a uniform but flexible interface for menu programming, is included. +
    • An emulation of the SVr4 form library, supporting +data collection through on-screen forms, is included. +
    • Binary terminfo entries generated by the ncurses tic(1) implementation +are bit-for-bit-compatible with the entry format SVr4 curses uses. +
    • The utilities have options to allow you to filter terminfo +entries for use with less capable curses/terminfo +versions such as the HP/UX and AIX ports.
    + +The ncurses package also has many useful extensions over SVr4: + +
      +
    • The API is 8-bit clean and base-level conformant with the X/OPEN curses +specification, XSI curses (that is, it implements all BASE level features, +but not all EXTENDED features). Most EXTENDED-level features not directly +concerned with wide-character support are implemented, including many +function calls not supported under SVr4 curses (but portability of all +calls is documented so you can use the SVr4 subset only). +
    • Unlike SVr3 curses, ncurses can write to the rightmost-bottommost corner +of the screen if your terminal has an insert-character capability. +
    • Ada95 and C++ bindings. +
    • Support for mouse event reporting with X Window xterm and OS/2 console windows. +
    • Extended mouse support via Alessandro Rubini's gpm package. +
    • The function wresize() allows you to resize windows, preserving +their data. +
    • The function use_default_colors() allows you to +use the terminal's default colors for the default color pair, +achieving the effect of transparent colors. +
    • The functions keyok() +and define_key() allow +you to better control the use of function keys, +e.g., disabling the ncurses KEY_MOUSE, +or by defining more than one control sequence to map to a given key code. +
    • Support for 16-color terminals, such as aixterm and XFree86 xterm. +
    • Better cursor-movement optimization. The package now features a +cursor-local-movement computation more efficient than either BSD's +or System V's. +
    • Super hardware scrolling support. The screen-update code incorporates +a novel, simple, and cheap algorithm that enables it to make optimal +use of hardware scrolling, line-insertion, and line-deletion +for screen-line movements. This algorithm is more powerful than +the 4.4BSD curses quickch() routine. +
    • Real support for terminals with the magic-cookie glitch. The +screen-update code will refrain from drawing a highlight if the magic- +cookie unattributed spaces required just before the beginning and +after the end would step on a non-space character. It will +automatically shift highlight boundaries when doing so would make it +possible to draw the highlight without changing the visual appearance +of the screen. +
    • It is possible to generate the library with a list of pre-loaded +fallback entries linked to it so that it can serve those terminal types even +when no terminfo tree or termcap file is accessible (this may be useful +for support of screen-oriented programs that must run in single-user mode). +
    • The tic(1)/captoinfo utility provided with ncurses has the +ability to translate many termcaps from the XENIX, IBM and +AT&T extension sets. +
    • A BSD-like tset(1) utility is provided. +
    • The ncurses library and utilities will automatically read terminfo +entries from $HOME/.terminfo if it exists, and compile to that directory +if it exists and the user has no write access to the system directory. +This feature makes it easier for users to have personal terminfo entries +without giving up access to the system terminfo directory. +
    • You may specify a path of directories to search for compiled +descriptions with the environment variable TERMINFO_DIRS (this +generalizes the feature provided by TERMINFO under stock System V.) +
    • In terminfo source files, use capabilities may refer not just to +other entries in the same source file (as in System V) but also to +compiled entries in either the system terminfo directory or the user's +$HOME/.terminfo directory. +
    • A script (capconvert) is provided to help BSD users +transition from termcap to terminfo. It gathers the information in a +TERMCAP environment variable and/or a ~/.termcap local entries file +and converts it to an equivalent local terminfo tree under $HOME/.terminfo. +
    • Automatic fallback to the /etc/termcap file can be compiled in +when it is not possible to build a terminfo tree. This feature is neither +fast nor cheap, you don't want to use it unless you have to, +but it's there. +
    • The table-of-entries utility toe makes it easy for users to +see exactly what terminal types are available on the system. +
    • The library meets the XSI requirement that every macro entry +point have a corresponding function which may be linked (and will be +prototype-checked) if the macro definition is disabled with +#undef. +
    • An HTML "Introduction to Programming with NCURSES" document provides +a narrative introduction to the curses programming interface. +
    + +

    State of the Package

    + +Numerous bugs present in earlier versions have been fixed; the +library is far more reliable than it used to be. Bounds checking in many +`dangerous' entry points has been improved. The code is now type-safe +according to gcc -Wall. The library has been checked for malloc leaks and +arena corruption by the Purify memory-allocation tester.

    + +The ncurses code has been tested with a wide variety of applications +including (versions starting with those noted): +

    +
    cdk +
    Curses Development Kit +
    +http://www.vexus.ca/CDK.html +
    +http://dickey.his.com/cdk. +
    ded +
    directory-editor +
    +http://dickey.his.com/ded. +
    dialog +
    the underlying application used in Slackware's setup, and the basis +for similar applications on GNU/Linux. +
    +http://dickey.his.com/dialog. +
    lynx +
    the character-screen WWW browser +
    +http://lynx.isc.org/release. +
    Midnight Commander 4.1 +
    file manager +
    +www.gnome.org/mc/. +
    mutt +
    mail utility +
    +http://www.mutt.org. +
    ncftp +
    file-transfer utility +
    +http://www.ncftp.com. +
    nvi +
    New vi versions 1.50 are able to use ncurses versions 1.9.7 and later. +
    +http://www.bostic.com/vi/. +
    tin +
    newsreader, supporting color, MIME +
    +http://www.tin.org. +
    taper +
    tape archive utility +
    +http://members.iinet.net.au/~yusuf/taper/. +
    vh-1.6 +
    Volks-Hypertext browser for the Jargon File +
    +http://www.bg.debian.org/Packages/unstable/text/vh.html. +
    +as well as some that use ncurses for the terminfo support alone: +
    +
    minicom +
    terminal emulator +
    +http://www.pp.clinet.fi/~walker/minicom.html. +
    vile +
    vi-like-emacs +
    +http://dickey.his.com/vile. +
    +

    + +The ncurses distribution includes a selection of test programs (including +a few games). + +

    Who's Who and What's What

    + +The original developers of ncurses are Zeyd Ben-Halim and +Eric S. Raymond. +Ongoing work is being done by +Thomas Dickey +and +Jürgen Pfeifer. +Thomas Dickey +acts as the maintainer for the Free Software Foundation, which holds the +copyright on ncurses. +Contact the current maintainers at +bug-ncurses@gnu.org. +

    + +To join the ncurses mailing list, please write email to +bug-ncurses-request@gnu.org containing the line: +

    +             subscribe <name>@<host.domain>
    +
    + +This list is open to anyone interested in helping with the development and +testing of this package.

    + +Beta versions of ncurses and patches to the current release are made available at +ftp://dickey.his.com/ncurses. + +

    Future Plans

    +
      +
    • Extended-level XPG4 conformance, with internationalization support. +
    • Ports to more systems, including DOS and Windows. +
    +We need people to help with these projects. If you are interested in working +on them, please join the ncurses list. + +

    Other Related Resources

    + +The distribution includes and uses a version of the terminfo-format +terminal description file maintained by Eric Raymond. +http://earthspace.net/~esr/terminfo.

    + +You can find lots of information on terminal-related topics +not covered in the terminfo file at +Richard Shuford's +archive. + + + diff --git a/ncurses-5.2/c++/Makefile.in b/ncurses-5.2/c++/Makefile.in new file mode 100644 index 0000000..36ce484 --- /dev/null +++ b/ncurses-5.2/c++/Makefile.in @@ -0,0 +1,213 @@ +# $Id$ +############################################################################## +# Copyright (c) 1998,1999 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Thomas E. Dickey 1996,1997 +# +# Simple makefile for c++ window class demo + +# turn off _all_ suffix rules; we'll generate our own +.SUFFIXES: + +SHELL = /bin/sh + +CF_MFLAGS = @cf_cv_makeflags@ +@SET_MAKE@ +x = @PROG_EXT@ + +MODEL = ../@DFT_OBJ_SUBDIR@ +DESTDIR = @DESTDIR@ +srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +LIBTOOL = @LIBTOOL@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +AR = @AR@ +AR_OPTS = @AR_OPTS@ +RANLIB = @RANLIB@ + +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CXXLIBS = @CXXLIBS@ + +INCDIR = ../include +CPPFLAGS = -I../c++ -I$(INCDIR) -I$(srcdir) -DHAVE_CONFIG_H @CPPFLAGS@ + +CCFLAGS = $(CPPFLAGS) $(CXXFLAGS) + +CFLAGS_LIBTOOL = $(CCFLAGS) +CFLAGS_NORMAL = $(CCFLAGS) +CFLAGS_DEBUG = $(CCFLAGS) @CXX_G_OPT@ -DTRACE +CFLAGS_PROFILE = $(CCFLAGS) -pg +CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@ + +CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@) + +NCURSES_MAJOR = @NCURSES_MAJOR@ +NCURSES_MINOR = @NCURSES_MINOR@ +REL_VERSION = @cf_cv_rel_version@ +ABI_VERSION = @cf_cv_abi_version@ + +LINK = @LINK_PROGS@ $(LIBTOOL) $(CXX) @CXXLDFLAGS@ + +LIBROOT = ncurses++ + +LIBNAME_LIBTOOL = @LIB_PREFIX@$(LIBROOT)@LIB_SUFFIX@.la +LIBNAME_NORMAL = @LIB_PREFIX@$(LIBROOT)@LIB_SUFFIX@.a +LIBNAME = @LIB_PREFIX@$(LIBROOT)@CXX_LIB_SUFFIX@ + +LINK_FLAGS = @EXTRA_LDFLAGS@ -L../lib -L$(libdir) -l$(LIBROOT) + +LINK_LIBTOOL = @EXTRA_LDFLAGS@ -L../lib -L$(libdir) ../lib/$(LIBNAME) +LINK_NORMAL = $(LINK_FLAGS) +LINK_DEBUG = $(LINK_FLAGS) +LINK_PROFILE = $(LINK_FLAGS) +LINK_SHARED = $(LINK_FLAGS) + +LDFLAGS = @TEST_ARGS@ @LDFLAGS@ \ + @LD_MODEL@ @LIBS@ @EXTRA_LIBS@ @LOCAL_LDFLAGS@ $(CXXLIBS) + +LDFLAGS_LIBTOOL = $(LDFLAGS) +LDFLAGS_NORMAL = $(LDFLAGS) +LDFLAGS_DEBUG = $(LDFLAGS) @CC_G_OPT@ +LDFLAGS_PROFILE = $(LDFLAGS) -pg +LDFLAGS_SHARED = $(LDFLAGS) @LD_SHARED_OPTS@ + +LDFLAGS_DEFAULT = $(LINK_@DFT_UPR_MODEL@) $(LDFLAGS_@DFT_UPR_MODEL@) + +AUTO_SRC = \ + etip.h + +all \ +libs :: $(AUTO_SRC) ../lib/$(LIBNAME) + +all :: demo$x + +sources : $(AUTO_SRC) + +# Build a conventional library for installing, since a shared library would +# pull in all of the ncurses libraries (panel, menu, form, ncurses) as direct +# dependencies. +LIB_OBJS = \ + $(MODEL)/cursesf.o \ + $(MODEL)/cursesm.o \ + $(MODEL)/cursesw.o \ + $(MODEL)/cursespad.o \ + $(MODEL)/cursesp.o \ + $(MODEL)/cursslk.o \ + $(MODEL)/cursesapp.o \ + $(MODEL)/cursesmain.o + +../lib/$(LIBNAME_NORMAL) : $(LIB_OBJS) + $(AR) $(AR_OPTS) $@ $? + $(RANLIB) $@ + +../lib/$(LIBNAME_LIBTOOL) : $(LIB_OBJS) + cd ../lib && $(LIBTOOL) $(CXX) -o $(LIBNAME) $(LIB_OBJS:.o=.lo) \ + -rpath $(INSTALL_PREFIX)$(libdir) \ + -version-info $(NCURSES_MAJOR):$(NCURSES_MINOR) + +OBJS_DEMO = $(MODEL)/demo.o + +$(MODEL)/demo.o : $(srcdir)/demo.cc \ + $(cursesf_h) $(cursesm_h) $(cursesapp_h) + +demo$x: $(OBJS_DEMO) \ + ../lib/$(LIBNAME) \ + @TEST_DEPS@ + @ECHO_LINK@ $(LINK) -o $@ $(OBJS_DEMO) $(LDFLAGS_DEFAULT) + +etip.h: $(srcdir)/etip.h.in $(srcdir)/edit_cfg.sh + cp $(srcdir)/etip.h.in $@ + sh $(srcdir)/edit_cfg.sh ../include/ncurses_cfg.h $@ + +$(DESTDIR)$(libdir) : + $(srcdir)/../mkinstalldirs $@ + +install \ +install.libs:: ../lib/$(LIBNAME) $(DESTDIR)$(libdir) + $(LIBTOOL) $(INSTALL) ../lib/$(LIBNAME) $(DESTDIR)$(libdir)/$(LIBNAME) + +uninstall \ +uninstall.libs:: + -$(LIBTOOL) rm -f $(DESTDIR)$(libdir)/$(LIBNAME) + +mostlyclean :: + -rm -f core tags TAGS *~ *.ln *.atac trace + +clean :: mostlyclean + -$(LIBTOOL) rm -f demo$x $(AUTO_SRC) ../lib/$(LIBNAME) $(LIB_OBJS) $(LIB_OBJS:.o=.lo) $(OBJS_DEMO) + -rm -rf .libs + +distclean :: clean + -rm -f Makefile + +realclean :: distclean + +############################################################################### + +cursesw_h = $(srcdir)/cursesw.h \ + etip.h \ + $(INCDIR)/curses.h + +cursesp_h = $(srcdir)/cursesp.h \ + $(cursesw_h) \ + $(INCDIR)/panel.h + +cursesf_h = $(srcdir)/cursesf.h \ + $(cursesp_h) \ + $(INCDIR)/form.h + +cursesm_h = $(srcdir)/cursesm.h \ + $(cursesp_h) \ + $(INCDIR)/menu.h + +cursslk_h = $(srcdir)/cursslk.h \ + $(cursesw_h) + +cursesapp_h = $(srcdir)/cursesapp.h \ + $(cursslk_h) + +$(INCDIR)/form.h : + cd ../form && $(MAKE) $@ + +$(INCDIR)/menu.h : + cd ../menu && $(MAKE) $@ + +$(INCDIR)/panel.h : + cd ../panel && $(MAKE) $@ + +############################################################################### +# The remainder of this file is automatically generated during configuration +############################################################################### diff --git a/ncurses-5.2/c++/NEWS b/ncurses-5.2/c++/NEWS new file mode 100644 index 0000000..299292d --- /dev/null +++ b/ncurses-5.2/c++/NEWS @@ -0,0 +1,42 @@ +This is a log of changes that the ncurses C++ binding has gone +through starting with the integration of menu and forms integration +into the binding. + +990731 + Improve support for pads. A viewport window may now be added to + a pad. It will then be possible to use a builtin panning mechanism + to view the pad. + +970908 + Improve NCursesWindow class: added additional methods to + cover more ncurses functionality. Make refresh() and + noutrefresh() virtual members to allow different implementation + in the NCursesPanel class. + + CAUTION: changed order of parameters in vline() and hline() of + NCursesWindow class. + + Make refresh() in NCursesPanel non-static, it is now a + reimplementation of refresh() in the base class. Added + noutrefresh() to NCursesPanel. + + Added NCursesForm and related classes to support libform + functionality. + + Moved most of configuration related stuff from cursesw.h to + etip.h + + Added NCursesApplication class to support easy configuration + of menu and forms related attributes as well as ripped of + title lines and Soft-Label-Keys for an application. + + Support of Auto-Cleanup for a menus fieldlist. + + Change of return type for current_item() and operator[] for + menus. + + Enhanced demo. +970502 + + Introduced the THROW and THROWS functions/macros to prepare + a smoother transition to real exception handling. + + Exception classes provided in etip.h + + Added the NCursesMenu class to support libmenu functionality. + + The inheritace relation between NCursesWindow and NCursesColorWindow + was kind of brain damage. Monochrome is a special case of colored, so + the relation should be just the opposite. This would allow all + derived classes like NCursesPanel, NCursesMenu or NCursesForm to + have colors. + To resolve that design flaw I put the color functionality into the + NCursesWindow class and it can be switched on by the static member + useColors(). NCursesColorWindow is still there for compatibility + reasons. diff --git a/ncurses-5.2/c++/PROBLEMS b/ncurses-5.2/c++/PROBLEMS new file mode 100644 index 0000000..81c1eba --- /dev/null +++ b/ncurses-5.2/c++/PROBLEMS @@ -0,0 +1,5 @@ +This is a list of open problems. This mainly lists known missing pieces +and design flaws. + +1. Testing!!! +2. Better demo program diff --git a/ncurses-5.2/c++/README-first b/ncurses-5.2/c++/README-first new file mode 100644 index 0000000..eb37ac6 --- /dev/null +++ b/ncurses-5.2/c++/README-first @@ -0,0 +1,58 @@ + C++ interface to ncurses routines +----------------------------------------------------------------------- + +This directory contains the source code for several C++ classes which +ease the use of writing ncurses-based programs. The code is derived +from the libg++ CursesWindow class but enhanced for ncurses. + +The classes simplify the use of window specific functions by +encapsulating them in the window object. Function overloading is +used in order to narrow the interface. E.g. you don't have the +distinction between `printw' and `mvprintw' anymore. + +A second benefit is the removal of all #defines which are included in +the curses.h file. This is a steady cause of trouble because many +common identifiers are used. Instead now all #defines are inline +functions which also allows strict type checking of arguments. + +The next enhancement is color support. It was originally provided by a +derived class. This caused some trouble if you think about Panels or +Menus and Forms with colors. We decided to put color support into the +base class so that any derived class may use color support also. +The implementation chosen here is directed to unrestricted use +of mixes of color and monochrome windows. The original NCursesColorWindow +class is maintained for compatibility reasons. + +The last point to mention is the support of other packages that are +distributed with the ncurses package: the panels library, the menu library +and the form library. This support is provided by the NCursesPanel class, +which is also derived from the NCursesWindow class and the NCursesMenu +and NCursesForm classes which are derived from NCursesPanel. This allows +building interfaces with windows. + +Please see the example program for a quick introduction. + +Note that at this point, there is no documentation for these classes. +Hopefully some will be written in the not too distant future. For now, +to find out how to use the classes, read the code and the example program. + +Suggestions for enhancements and contributions of code (and docs) are +welcome. Please let us know which functionality you miss. + + ATTENTION LINUX USERS: There is currently some discussion of + replacing the BSD curses in the Linux libc with ncurses. If + this is done we could perhaps include these classes in the Linux + libg++ replacing the original CursesWindow class (and renaming it + to CursesWindow). This could be done because NCursesWindow can + be made easily to a superset of the CursesWindow class. + + +Original author: + Eric Newton for FSF's libg++ + +Authors of first ncurses based release (NCursesWindow, NCursesPanel): + Ulrich Drepper + and Anatoly Ivasyuk + +Author of this release: + Juergen Pfeifer diff --git a/ncurses-5.2/c++/cursesapp.cc b/ncurses-5.2/c++/cursesapp.cc new file mode 100644 index 0000000..6da9862 --- /dev/null +++ b/ncurses-5.2/c++/cursesapp.cc @@ -0,0 +1,146 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#include "cursesapp.h" +#include "internal.h" + +MODULE_ID("$Id$") + +void +NCursesApplication::init(bool bColors) { + if (bColors) + NCursesWindow::useColors(); + + if (Root_Window->colors() > 1) { + b_Colors = TRUE; + Root_Window->setcolor(1); + Root_Window->setpalette(COLOR_YELLOW,COLOR_BLUE); + Root_Window->setcolor(2); + Root_Window->setpalette(COLOR_CYAN,COLOR_BLUE); + Root_Window->setcolor(3); + Root_Window->setpalette(COLOR_BLACK,COLOR_BLUE); + Root_Window->setcolor(4); + Root_Window->setpalette(COLOR_BLACK,COLOR_CYAN); + Root_Window->setcolor(5); + Root_Window->setpalette(COLOR_BLUE,COLOR_YELLOW); + Root_Window->setcolor(6); + Root_Window->setpalette(COLOR_BLACK,COLOR_GREEN); + } + else + b_Colors = FALSE; + + Root_Window->bkgd(' '|window_backgrounds()); +} + +NCursesApplication* NCursesApplication::theApp = 0; +NCursesWindow* NCursesApplication::titleWindow = 0; +NCursesApplication::SLK_Link* NCursesApplication::slk_stack = 0; + +NCursesApplication::~NCursesApplication() { + Soft_Label_Key_Set* S; + + delete titleWindow; + while( (S=top()) ) { + pop(); + delete S; + } + delete Root_Window; + ::endwin(); +} + +int NCursesApplication::rinit(NCursesWindow& w) { + titleWindow = &w; + return OK; +} + +void NCursesApplication::push(Soft_Label_Key_Set& S) { + SLK_Link* L = new SLK_Link; + assert(L != 0); + L->prev = slk_stack; + L->SLKs = &S; + slk_stack = L; + if (Root_Window) + S.show(); +} + +bool NCursesApplication::pop() { + if (slk_stack) { + SLK_Link* L = slk_stack; + slk_stack = slk_stack->prev; + delete L; + if (Root_Window && top()) + top()->show(); + } + return (slk_stack ? FALSE : TRUE); +} + +Soft_Label_Key_Set* NCursesApplication::top() const { + if (slk_stack) + return slk_stack->SLKs; + else + return (Soft_Label_Key_Set*)0; +} + +int NCursesApplication::operator()(void) { + bool bColors = b_Colors; + Soft_Label_Key_Set* S; + + int ts = titlesize(); + if (ts>0) + NCursesWindow::ripoffline(ts,rinit); + Soft_Label_Key_Set::Label_Layout fmt = useSLKs(); + if (fmt!=Soft_Label_Key_Set::None) { + S = new Soft_Label_Key_Set(fmt); + assert(S != 0); + init_labels(*S); + } + + Root_Window = new NCursesWindow(::stdscr); + init(bColors); + + if (ts>0) + title(); + if (fmt!=Soft_Label_Key_Set::None) { + push(*S); + } + + return run(); +} + +NCursesApplication::NCursesApplication(bool bColors) { + b_Colors = bColors; + if (theApp) + THROW(new NCursesException("Application object already created.")); + else + theApp = this; +} diff --git a/ncurses-5.2/c++/cursesapp.h b/ncurses-5.2/c++/cursesapp.h new file mode 100644 index 0000000..0958bb7 --- /dev/null +++ b/ncurses-5.2/c++/cursesapp.h @@ -0,0 +1,163 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _CURSESAPP_H +#define _CURSESAPP_H + +#include + +class NCursesApplication { +public: + typedef struct _slk_link { // This structure is used to maintain + struct _slk_link* prev; // a stack of SLKs + Soft_Label_Key_Set* SLKs; + } SLK_Link; +private: + static int rinit(NCursesWindow& w); // Internal Init function for title + static NCursesApplication* theApp; // Global ref. to the application + + static SLK_Link* slk_stack; + +protected: + static NCursesWindow* titleWindow; // The Title Window (if any) + + bool b_Colors; // Is this a color application? + NCursesWindow* Root_Window; // This is the stdscr equiv. + + // Initialization of attributes; + // Rewrite this in your derived class if you prefer other settings + virtual void init(bool bColors); + + // The number of lines for the title window. Default is no title window + // You may rewrite this in your derived class + virtual int titlesize() const { + return 0; + } + + // This method is called to put something into the title window initially + // You may rewrite this in your derived class + virtual void title() { + } + + // The layout used for the Soft Label Keys. Default is to have no SLKs. + // You may rewrite this in your derived class + virtual Soft_Label_Key_Set::Label_Layout useSLKs() const { + return Soft_Label_Key_Set::None; + } + + // This method is called to initialize the SLKs. Default is nothing. + // You may rewrite this in your derived class + virtual void init_labels(Soft_Label_Key_Set& S) const { + } + + // Your derived class must implement this method. The return value must + // be the exit value of your application. + virtual int run() = 0; + + + // The constructor is protected, so you may use it in your derived + // class constructor. The argument tells whether or not you want colors. + NCursesApplication(bool wantColors = FALSE); + +public: + virtual ~NCursesApplication(); + + // Get a pointer to the current application object + static NCursesApplication* getApplication() { + return theApp; + } + + // This method runs the application and returns its exit value + int operator()(void); + + // Process the commandline arguments. The default implementation simply + // ignores them. Your derived class may rewrite this. + virtual void handleArgs(int argc, char* argv[]) { + } + + // Does this application use colors? + inline bool useColors() const { + return b_Colors; + } + + // Push the Key Set S onto the SLK Stack. S then becomes the current set + // of Soft Labelled Keys. + void push(Soft_Label_Key_Set& S); + + // Throw away the current set of SLKs and make the previous one the + // new current set. + bool pop(); + + // Retrieve the current set of Soft Labelled Keys. + Soft_Label_Key_Set* top() const; + + // Attributes to use for menu and forms foregrounds + virtual chtype foregrounds() const { + return b_Colors ? COLOR_PAIR(1) : A_BOLD; + } + + // Attributes to use for menu and forms backgrounds + virtual chtype backgrounds() const { + return b_Colors ? COLOR_PAIR(2) : A_NORMAL; + } + + // Attributes to use for inactive (menu) elements + virtual chtype inactives() const { + return b_Colors ? (COLOR_PAIR(3)|A_DIM) : A_DIM; + } + + // Attributes to use for (form) labels and SLKs + virtual chtype labels() const { + return b_Colors ? COLOR_PAIR(4) : A_NORMAL; + } + + // Attributes to use for form backgrounds + virtual chtype dialog_backgrounds() const { + return b_Colors ? COLOR_PAIR(4) : A_NORMAL; + } + + // Attributes to use as default for (form) window backgrounds + virtual chtype window_backgrounds() const { + return b_Colors ? COLOR_PAIR(5) : A_NORMAL; + } + + // Attributes to use for the title window + virtual chtype screen_titles() const { + return b_Colors ? COLOR_PAIR(6) : A_BOLD; + } + +}; + +#endif // _CURSESAPP_H diff --git a/ncurses-5.2/c++/cursesf.cc b/ncurses-5.2/c++/cursesf.cc new file mode 100644 index 0000000..c5885ca --- /dev/null +++ b/ncurses-5.2/c++/cursesf.cc @@ -0,0 +1,426 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#include "cursesf.h" +#include "cursesapp.h" +#include "internal.h" + +MODULE_ID("$Id$") + +NCursesFormField::~NCursesFormField () { + if (field) + OnError(::free_field (field)); +} + +/* Construct a FIELD* array from an array of NCursesFormField + * objects. + */ +FIELD** +NCursesForm::mapFields(NCursesFormField* nfields[]) { + int fieldCount = 0,lcv; + FIELD** old_fields; + + assert(nfields != 0); + + for (lcv=0; nfields[lcv]->field; ++lcv) + ++fieldCount; + + FIELD** fields = new FIELD*[fieldCount + 1]; + + for (lcv=0;nfields[lcv]->field;++lcv) { + fields[lcv] = nfields[lcv]->field; + } + fields[lcv] = NULL; + + my_fields = nfields; + + if (form && (old_fields = ::form_fields(form))) { + ::set_form_fields(form,(FIELD**)0); + delete[] old_fields; + } + return fields; +} + +void NCursesForm::setDefaultAttributes() { + NCursesApplication* S = NCursesApplication::getApplication(); + + int n = count(); + if (n > 0) { + for(int i=0; ioptions() & (O_EDIT|O_ACTIVE))==(O_EDIT|O_ACTIVE)) { + if (S) { + f->set_foreground(S->foregrounds()); + f->set_background(S->backgrounds()); + } + f->set_pad_character('_'); + } + else { + if (S) + f->set_background(S->labels()); + } + } + } + + if (S) { + bkgd(' '|S->dialog_backgrounds()); + if (sub) + sub->bkgd(' '|S->dialog_backgrounds()); + } +} + +void +NCursesForm::InitForm(NCursesFormField* nfields[], + bool with_frame, + bool autoDelete_Fields) { + int mrows, mcols; + + keypad(TRUE); + meta(TRUE); + + b_framed = with_frame; + b_autoDelete = autoDelete_Fields; + + form = (FORM*)0; + form = ::new_form(mapFields(nfields)); + if (!form) + OnError (E_SYSTEM_ERROR); + + UserHook* hook = new UserHook; + hook->m_user = NULL; + hook->m_back = this; + hook->m_owner = form; + ::set_form_userptr(form,(void*)hook); + + ::set_form_init (form, NCursesForm::frm_init); + ::set_form_term (form, NCursesForm::frm_term); + ::set_field_init (form, NCursesForm::fld_init); + ::set_field_term (form, NCursesForm::fld_term); + + scale(mrows, mcols); + ::set_form_win(form, w); + + if (with_frame) { + if ((mrows > height()-2) || (mcols > width()-2)) + OnError(E_NO_ROOM); + sub = new NCursesWindow(*this,mrows,mcols,1,1,'r'); + ::set_form_sub(form, sub->w); + b_sub_owner = TRUE; + } + else { + sub = (NCursesWindow*)0; + b_sub_owner = FALSE; + } + options_on(O_NL_OVERLOAD); + setDefaultAttributes(); +} + +NCursesForm::~NCursesForm() { + UserHook* hook = (UserHook*)::form_userptr(form); + delete hook; + if (b_sub_owner) { + delete sub; + ::set_form_sub(form,(WINDOW *)0); + } + if (form) { + FIELD** fields = ::form_fields(form); + int cnt = count(); + + OnError(::set_form_fields(form,(FIELD**)0)); + + if (b_autoDelete) { + if (cnt>0) { + for (int i=0; i <= cnt; i++) + delete my_fields[i]; + } + delete[] my_fields; + } + + ::free_form(form); + // It's essential to do this after free_form() + delete[] fields; + } +} + +void +NCursesForm::setSubWindow(NCursesWindow& nsub) { + if (!isDescendant(nsub)) + OnError(E_SYSTEM_ERROR); + else { + if (b_sub_owner) + delete sub; + sub = ⊄ + ::set_form_sub(form,sub->w); + } +} + +/* Internal hook functions. They will route the hook + * calls to virtual methods of the NCursesForm class, + * so in C++ providing a hook is done simply by + * implementing a virtual method in a derived class + */ +void +NCursesForm::frm_init(FORM *f) { + getHook(f)->On_Form_Init(); +} + +void +NCursesForm::frm_term(FORM *f) { + getHook(f)->On_Form_Termination(); +} + +void +NCursesForm::fld_init(FORM *f) { + NCursesForm* F = getHook(f); + F->On_Field_Init (*(F->current_field ())); +} + +void +NCursesForm::fld_term(FORM *f) { + NCursesForm* F = getHook(f); + F->On_Field_Termination (*(F->current_field ())); +} + +void +NCursesForm::On_Form_Init() { +} + +void +NCursesForm::On_Form_Termination() { +} + +void +NCursesForm::On_Field_Init(NCursesFormField& field) { +} + +void +NCursesForm::On_Field_Termination(NCursesFormField& field) { +} + +// call the form driver and do basic error checking. +int +NCursesForm::driver (int c) { + int res = ::form_driver (form, c); + switch (res) { + case E_OK: + case E_REQUEST_DENIED: + case E_INVALID_FIELD: + case E_UNKNOWN_COMMAND: + break; + default: + OnError (res); + } + return (res); +} + +void NCursesForm::On_Request_Denied(int c) const { + beep(); +} + +void NCursesForm::On_Invalid_Field(int c) const { + beep(); +} + +void NCursesForm::On_Unknown_Command(int c) const { + beep(); +} + +static const int CMD_QUIT = MAX_COMMAND + 1; + +NCursesFormField* +NCursesForm::operator()(void) { + int drvCmnd; + int err; + int c; + + post(); + show(); + refresh(); + + while (((drvCmnd = virtualize((c=getch()))) != CMD_QUIT)) { + switch((err=driver(drvCmnd))) { + case E_REQUEST_DENIED: + On_Request_Denied(c); + break; + case E_INVALID_FIELD: + On_Invalid_Field(c); + break; + case E_UNKNOWN_COMMAND: + On_Unknown_Command(c); + break; + case E_OK: + break; + default: + OnError(err); + } + } + + unpost(); + hide(); + refresh(); + return my_fields[::field_index (::current_field (form))]; +} + +// Provide a default key virtualization. Translate the keyboard +// code c into a form request code. +// The default implementation provides a hopefully straightforward +// mapping for the most common keystrokes and form requests. +int +NCursesForm::virtualize(int c) { + switch(c) { + + case KEY_HOME : return(REQ_FIRST_FIELD); + case KEY_END : return(REQ_LAST_FIELD); + + case KEY_DOWN : return(REQ_DOWN_CHAR); + case KEY_UP : return(REQ_UP_CHAR); + case KEY_LEFT : return(REQ_PREV_CHAR); + case KEY_RIGHT : return(REQ_NEXT_CHAR); + + case KEY_NPAGE : return(REQ_NEXT_PAGE); + case KEY_PPAGE : return(REQ_PREV_PAGE); + + case KEY_BACKSPACE : return(REQ_DEL_PREV); + case KEY_ENTER : return(REQ_NEW_LINE); + case KEY_CLEAR : return(REQ_CLR_FIELD); + + case CTRL('X') : return(CMD_QUIT); // eXit + + case CTRL('F') : return(REQ_NEXT_FIELD); // Forward + case CTRL('B') : return(REQ_PREV_FIELD); // Backward + case CTRL('L') : return(REQ_LEFT_FIELD); // Left + case CTRL('R') : return(REQ_RIGHT_FIELD); // Right + case CTRL('U') : return(REQ_UP_FIELD); // Up + case CTRL('D') : return(REQ_DOWN_FIELD); // Down + + case CTRL('W') : return(REQ_NEXT_WORD); + case CTRL('T') : return(REQ_PREV_WORD); + + case CTRL('A') : return(REQ_BEG_FIELD); + case CTRL('E') : return(REQ_END_FIELD); + + case CTRL('I') : return(REQ_INS_CHAR); + case CTRL('M') : + case CTRL('J') : return(REQ_NEW_LINE); + case CTRL('O') : return(REQ_INS_LINE); + case CTRL('V') : return(REQ_DEL_CHAR); + case CTRL('H') : return(REQ_DEL_PREV); + case CTRL('Y') : return(REQ_DEL_LINE); + case CTRL('G') : return(REQ_DEL_WORD); + case CTRL('K') : return(REQ_CLR_EOF); + + case CTRL('N') : return(REQ_NEXT_CHOICE); + case CTRL('P') : return(REQ_PREV_CHOICE); + + default: + return(c); + } +} +// +// ------------------------------------------------------------------------- +// User Defined Fieldtypes +// ------------------------------------------------------------------------- +// +bool UserDefinedFieldType::fcheck(FIELD *f, const void *u) { + NCursesFormField* F = (NCursesFormField*)u; + assert(F != 0); + UserDefinedFieldType* udf = (UserDefinedFieldType*)(F->fieldtype()); + assert(udf != 0); + return udf->field_check(*F); +} + +bool UserDefinedFieldType::ccheck(int c, const void *u) { + NCursesFormField* F = (NCursesFormField*)u; + assert(F != 0); + UserDefinedFieldType* udf = + (UserDefinedFieldType*)(F->fieldtype()); + assert(udf != 0); + return udf->char_check(c); +} + +void* UserDefinedFieldType::makearg(va_list* va) { + return va_arg(*va,NCursesFormField*); +} + +FIELDTYPE* UserDefinedFieldType::generic_fieldtype = + ::new_fieldtype(UserDefinedFieldType::fcheck, + UserDefinedFieldType::ccheck); + +FIELDTYPE* UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice = + ::new_fieldtype(UserDefinedFieldType::fcheck, + UserDefinedFieldType::ccheck); + +bool UserDefinedFieldType_With_Choice::next_choice(FIELD *f, const void *u) { + NCursesFormField* F = (NCursesFormField*)u; + assert(F != 0); + UserDefinedFieldType_With_Choice* udf = + (UserDefinedFieldType_With_Choice*)(F->fieldtype()); + assert(udf != 0); + return udf->next(*F); +} + +bool UserDefinedFieldType_With_Choice::prev_choice(FIELD *f, const void *u) { + NCursesFormField* F = (NCursesFormField*)u; + assert(F != 0); + UserDefinedFieldType_With_Choice* udf = + (UserDefinedFieldType_With_Choice*)(F->fieldtype()); + assert(udf != 0); + return udf->previous(*F); +} + +class UDF_Init { +private: + int code; + static UDF_Init* I; +public: + UDF_Init() { + code = ::set_fieldtype_arg(UserDefinedFieldType::generic_fieldtype, + UserDefinedFieldType::makearg, + NULL, + NULL); + if (code==E_OK) + code = ::set_fieldtype_arg + (UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice, + UserDefinedFieldType::makearg, + NULL, + NULL); + if (code==E_OK) + code = ::set_fieldtype_choice + (UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice, + UserDefinedFieldType_With_Choice::next_choice, + UserDefinedFieldType_With_Choice::prev_choice); + } +}; + +UDF_Init* UDF_Init::I = new UDF_Init(); + diff --git a/ncurses-5.2/c++/cursesf.h b/ncurses-5.2/c++/cursesf.h new file mode 100644 index 0000000..a5a4a9e --- /dev/null +++ b/ncurses-5.2/c++/cursesf.h @@ -0,0 +1,824 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _CURSESF_H +#define _CURSESF_H + +#include +#include + +extern "C" { +# include +} +// +// ------------------------------------------------------------------------- +// The abstract base class for buitin and user defined Fieldtypes. +// ------------------------------------------------------------------------- +// +class NCursesFormField; // forward declaration + +// Class to represent builtin field types as well as C++ written new +// fieldtypes (see classes UserDefineFieldType... +class NCursesFieldType { + friend class NCursesFormField; + +protected: + FIELDTYPE* fieldtype; + + inline void OnError(int err) const THROWS(NCursesFormException) { + if (err!=E_OK) + THROW(new NCursesFormException (err)); + } + + NCursesFieldType(FIELDTYPE *f) : fieldtype(f) { + } + + virtual ~NCursesFieldType() {} + + // Set the fields f fieldtype to this one. + virtual void set(NCursesFormField& f) = 0; + +public: + NCursesFieldType() : fieldtype((FIELDTYPE*)0) { + } +}; + +// +// ------------------------------------------------------------------------- +// The class representing a forms field, wrapping the lowlevel FIELD struct +// ------------------------------------------------------------------------- +// +class NCursesFormField { + friend class NCursesForm; + +protected: + FIELD *field; // lowlevel structure + NCursesFieldType* ftype; // Associated field type + + // Error handler + inline void OnError (int err) const THROWS(NCursesFormException) { + if (err != E_OK) + THROW(new NCursesFormException (err)); + } + +public: + // Create a 'Null' field. Can be used to delimit a field list + NCursesFormField() + : field((FIELD*)0), ftype((NCursesFieldType*)0) { + } + + // Create a new field + NCursesFormField (int rows, + int cols, + int first_row = 0, + int first_col = 0, + int offscreen_rows = 0, + int additional_buffers = 0) + : ftype((NCursesFieldType*)0) { + field = ::new_field(rows,cols,first_row,first_col, + offscreen_rows, additional_buffers); + if (!field) + OnError(errno); + } + + virtual ~NCursesFormField (); + + // Duplicate the field at a new position + inline NCursesFormField* dup(int first_row, int first_col) { + NCursesFormField* f = new NCursesFormField(); + if (!f) + OnError(E_SYSTEM_ERROR); + else { + f->ftype = ftype; + f->field = ::dup_field(field,first_row,first_col); + if (!f->field) + OnError(errno); + } + return f; + } + + // Link the field to a new location + inline NCursesFormField* link(int first_row, int first_col) { + NCursesFormField* f = new NCursesFormField(); + if (!f) + OnError(E_SYSTEM_ERROR); + else { + f->ftype = ftype; + f->field = ::link_field(field,first_row,first_col); + if (!f->field) + OnError(errno); + } + return f; + } + + // Get the lowlevel field representation + inline FIELD* get_field() const { + return field; + } + + // Retrieve info about the field + inline void info(int& rows, int& cols, + int& first_row, int& first_col, + int& offscreen_rows, int& additional_buffers) const { + OnError(::field_info(field, &rows, &cols, + &first_row, &first_col, + &offscreen_rows, &additional_buffers)); + } + + // Retrieve info about the fields dynamic properties. + inline void dynamic_info(int& dynamic_rows, int& dynamic_cols, + int& max_growth) const { + OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols, + &max_growth)); + } + + // For a dynamic field you may set the maximum growth limit. + // A zero means unlimited growth. + inline void set_maximum_growth(int growth = 0) { + OnError(::set_max_field(field,growth)); + } + + // Move the field to a new position + inline void move(int row, int col) { + OnError(::move_field(field,row,col)); + } + + // Mark the field to start a new page + inline void new_page(bool pageFlag = FALSE) { + OnError(::set_new_page(field,pageFlag)); + } + + // Retrieve whether or not the field starts a new page. + inline bool is_new_page() const { + return ::new_page(field); + } + + // Set the justification for the field + inline void set_justification(int just) { + OnError(::set_field_just(field,just)); + } + + // Retrieve the fields justification + inline int justification() const { + return ::field_just(field); + } + // Set the foreground attribute for the field + inline void set_foreground(chtype fore) { + OnError(::set_field_fore(field,fore)); + } + + // Retrieve the fields foreground attribute + inline chtype fore() const { + return ::field_fore(field); + } + + // Set the background attribute for the field + inline void set_background(chtype back) { + OnError(::set_field_back(field,back)); + } + + // Retrieve the fields background attribute + inline chtype back() const { + return ::field_back(field); + } + + // Set the padding character for the field + inline void set_pad_character(int pad) { + OnError(::set_field_pad(field,pad)); + } + + // Retrieve the fields padding character + inline int pad() const { + return ::field_pad(field); + } + + // Switch on the fields options + inline void options_on (Field_Options options) { + OnError (::field_opts_on (field, options)); + } + + // Switch off the fields options + inline void options_off (Field_Options options) { + OnError (::field_opts_off (field, options)); + } + + // Retrieve the fields options + inline Field_Options options () const { + return ::field_opts (field); + } + + // Set the fields options + inline void set_options (Field_Options options) { + OnError (::set_field_opts (field, options)); + } + + // Mark the field as changed + inline void set_changed(bool changeFlag = TRUE) { + OnError(::set_field_status(field,changeFlag)); + } + + // Test whether or not the field is marked as changed + inline bool changed() const { + return ::field_status(field); + } + + // Return the index of the field in the field array of a form + // or -1 if the field is not associated to a form + inline int (index)() const { + return ::field_index(field); + } + + // Store a value in a fields buffer. The default buffer is nr. 0 + inline void set_value(const char *val, int buffer = 0) { + OnError(::set_field_buffer(field,buffer,val)); + } + + // Retrieve the value of a fields buffer. The defaukt buffer is nr. 0 + inline char* value(int buffer = 0) const { + return ::field_buffer(field,buffer); + } + + // Set the validation type of the field. + inline void set_fieldtype(NCursesFieldType& f) { + ftype = &f; + f.set(*this); // A good friend may do that... + } + + // Retrieve the validation type of the field. + inline NCursesFieldType* fieldtype() const { + return ftype; + } + +}; + +// +// ------------------------------------------------------------------------- +// The class representing a form, wrapping the lowlevel FORM struct +// ------------------------------------------------------------------------- +// +class NCursesForm : public NCursesPanel { +protected: + FORM* form; // the lowlevel structure + +private: + NCursesWindow* sub; // the subwindow object + bool b_sub_owner; // is this our own subwindow? + bool b_framed; // has the form a border? + bool b_autoDelete; // Delete fields when deleting form? + + NCursesFormField** my_fields; // The array of fields for this form + + // This structure is used for the form's user data field to link the + // FORM* to the C++ object and to provide extra space for a user pointer. + typedef struct { + void* m_user; // the pointer for the user's data + const NCursesForm* m_back; // backward pointer to C++ object + const FORM* m_owner; + } UserHook; + + // Get the backward pointer to the C++ object from a FORM + static inline NCursesForm* getHook(const FORM *f) { + UserHook* hook = (UserHook*)::form_userptr(f); + assert(hook != 0 && hook->m_owner==f); + return (NCursesForm*)(hook->m_back); + } + + // This are the built-in hook functions in this C++ binding. In C++ we use + // virtual member functions (see below On_..._Init and On_..._Termination) + // to provide this functionality in an object oriented manner. + static void frm_init(FORM *); + static void frm_term(FORM *); + static void fld_init(FORM *); + static void fld_term(FORM *); + + // Calculate FIELD* array for the menu + FIELD** mapFields(NCursesFormField* nfields[]); + +protected: + // internal routines + inline void set_user(void *user) { + UserHook* uptr = (UserHook*)::form_userptr (form); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); + uptr->m_user = user; + } + + inline void *get_user() { + UserHook* uptr = (UserHook*)::form_userptr (form); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); + return uptr->m_user; + } + + void InitForm (NCursesFormField* Fields[], + bool with_frame, + bool autoDeleteFields); + + inline void OnError (int err) const THROWS(NCursesFormException) { + if (err != E_OK) + THROW(new NCursesFormException (err)); + } + + // this wraps the form_driver call. + virtual int driver (int c) ; + + // 'Internal' constructor, builds an object without association to a + // field array. + NCursesForm( int lines, + int cols, + int begin_y = 0, + int begin_x = 0) + : NCursesPanel(lines,cols,begin_y,begin_x), + form ((FORM*)0) { + } + +public: + // Create form for the default panel. + NCursesForm (NCursesFormField* Fields[], + bool with_frame=FALSE, // reserve space for a frame? + bool autoDelete_Fields=FALSE) // do automatic cleanup? + : NCursesPanel() { + InitForm(Fields, with_frame, autoDelete_Fields); + } + + // Create a form in a panel with the given position and size. + NCursesForm (NCursesFormField* Fields[], + int lines, + int cols, + int begin_y, + int begin_x, + bool with_frame=FALSE, // reserve space for a frame? + bool autoDelete_Fields=FALSE) // do automatic cleanup? + : NCursesPanel(lines, cols, begin_y, begin_x) { + InitForm(Fields, with_frame, autoDelete_Fields); + } + + virtual ~NCursesForm(); + + // Set the default attributes for the form + virtual void setDefaultAttributes(); + + // Retrieve current field of the form. + inline NCursesFormField* current_field() const { + return my_fields[::field_index(::current_field(form))]; + } + + // Set the forms subwindow + void setSubWindow(NCursesWindow& sub); + + // Set these fields for the form + inline void setFields(NCursesFormField* Fields[]) { + OnError(::set_form_fields(form,mapFields(Fields))); + } + + // Remove the form from the screen + inline void unpost (void) { + OnError (::unpost_form (form)); + } + + // Post the form to the screen if flag is true, unpost it otherwise + inline void post(bool flag = TRUE) { + OnError (flag ? ::post_form(form) : ::unpost_form (form)); + } + + // Decorations + inline void frame(const char *title=NULL, const char* btitle=NULL) { + if (b_framed) + NCursesPanel::frame(title,btitle); + else + OnError(E_SYSTEM_ERROR); + } + + inline void boldframe(const char *title=NULL, const char* btitle=NULL) { + if (b_framed) + NCursesPanel::boldframe(title,btitle); + else + OnError(E_SYSTEM_ERROR); + } + + inline void label(const char *topLabel, const char *bottomLabel) { + if (b_framed) + NCursesPanel::label(topLabel,bottomLabel); + else + OnError(E_SYSTEM_ERROR); + } + + // ----- + // Hooks + // ----- + + // Called after the form gets repositioned in its window. + // This is especially true if the form is posted. + virtual void On_Form_Init(); + + // Called before the form gets repositioned in its window. + // This is especially true if the form is unposted. + virtual void On_Form_Termination(); + + // Called after the field became the current field + virtual void On_Field_Init(NCursesFormField& field); + + // Called before this field is left as current field. + virtual void On_Field_Termination(NCursesFormField& field); + + // Calculate required window size for the form. + void scale(int& rows, int& cols) const { + OnError(::scale_form(form,&rows,&cols)); + } + + // Retrieve number of fields in the form. + int count() const { + return ::field_count(form); + } + + // Make the page the current page of the form. + void set_page(int page) { + OnError(::set_form_page(form,page)); + } + + // Retrieve current page number + int page() const { + return ::form_page(form); + } + + // Switch on the forms options + inline void options_on (Form_Options options) { + OnError (::form_opts_on (form, options)); + } + + // Switch off the forms options + inline void options_off (Form_Options options) { + OnError (::form_opts_off (form, options)); + } + + // Retrieve the forms options + inline Form_Options options () const { + return ::form_opts (form); + } + + // Set the forms options + inline void set_options (Form_Options options) { + OnError (::set_form_opts (form, options)); + } + + // Are there more data in the current field after the data shown + inline bool data_ahead() const { + return ::data_ahead(form); + } + + // Are there more data in the current field before the data shown + inline bool data_behind() const { + return ::data_behind(form); + } + + // Position the cursor to the current field + inline void position_cursor () { + OnError (::pos_form_cursor (form)); + } + // Set the current field + inline void set_current(NCursesFormField& F) { + OnError (::set_current_field(form, F.field)); + } + + // Provide a default key virtualization. Translate the keyboard + // code c into a form request code. + // The default implementation provides a hopefully straightforward + // mapping for the most common keystrokes and form requests. + virtual int virtualize(int c); + + // Operators + inline NCursesFormField* operator[](int i) const { + if ( (i < 0) || (i >= ::field_count (form)) ) + OnError (E_BAD_ARGUMENT); + return my_fields[i]; + } + + // Perform the menu's operation + // Return the field where you left the form. + virtual NCursesFormField* operator()(void); + + // Exception handlers. The default is a Beep. + virtual void On_Request_Denied(int c) const; + virtual void On_Invalid_Field(int c) const; + virtual void On_Unknown_Command(int c) const; + +}; + +// +// ------------------------------------------------------------------------- +// This is the typical C++ typesafe way to allow to attach +// user data to a field of a form. Its assumed that the user +// data belongs to some class T. Use T as template argument +// to create a UserField. +// ------------------------------------------------------------------------- +template class NCursesUserField : public NCursesFormField +{ +public: + NCursesUserField (int rows, + int cols, + int first_row = 0, + int first_col = 0, + const T* p_UserData = (T*)0, + int offscreen_rows = 0, + int additional_buffers = 0) + : NCursesFormField (rows, cols, + first_row, first_col, + offscreen_rows, additional_buffers) { + if (field) + OnError(::set_field_userptr(field,(void *)p_UserData)); + } + + virtual ~NCursesUserField() {}; + + inline const T* UserData (void) const { + return (const T*)::field_userptr (field); + } + + inline virtual void setUserData(const T* p_UserData) { + if (field) + OnError (::set_field_userptr (field, (void *)p_UserData)); + } +}; +// +// ------------------------------------------------------------------------- +// The same mechanism is used to attach user data to a form +// ------------------------------------------------------------------------- +// +template class NCursesUserForm : public NCursesForm +{ +protected: + // 'Internal' constructor, builds an object without association to a + // field array. + NCursesUserForm( int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + const T* p_UserData = (T*)0) + : NCursesForm(lines,cols,begin_y,begin_x) { + if (form) + set_user ((void *)p_UserData); + } + +public: + NCursesUserForm (NCursesFormField Fields[], + bool with_frame=FALSE, + bool autoDelete_Fields=FALSE) + : NCursesForm (Fields, with_frame, autoDelete_Fields) { + }; + + NCursesUserForm (NCursesFormField Fields[], + const T* p_UserData = (T*)0, + bool with_frame=FALSE, + bool autoDelete_Fields=FALSE) + : NCursesForm (Fields, with_frame, autoDelete_Fields) { + if (form) + set_user ((void *)p_UserData); + }; + + NCursesUserForm (NCursesFormField Fields[], + int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + const T* p_UserData = (T*)0, + bool with_frame=FALSE, + bool autoDelete_Fields=FALSE) + : NCursesForm (Fields, lines, cols, begin_y, begin_x, + with_frame, autoDelete_Fields) { + if (form) + set_user ((void *)p_UserData); + }; + + virtual ~NCursesUserForm() { + }; + + inline T* UserData (void) const { + return (T*)get_user (); + }; + + inline virtual void setUserData (const T* p_UserData) { + if (form) + set_user ((void *)p_UserData); + } + +}; +// +// ------------------------------------------------------------------------- +// Builtin Fieldtypes +// ------------------------------------------------------------------------- +// +class Alpha_Field : public NCursesFieldType { +private: + int min_field_width; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); + } + +public: + Alpha_Field(int width) + : NCursesFieldType(TYPE_ALPHA), + min_field_width(width) { + } +}; + +class Alphanumeric_Field : public NCursesFieldType { +private: + int min_field_width; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); + } + +public: + Alphanumeric_Field(int width) + : NCursesFieldType(TYPE_ALNUM), + min_field_width(width) { + } +}; + +class Integer_Field : public NCursesFieldType { +private: + int precision; + long lower_limit, upper_limit; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype, + precision,lower_limit,upper_limit)); + } + +public: + Integer_Field(int prec, long low=0L, long high=0L) + : NCursesFieldType(TYPE_INTEGER), + precision(prec), lower_limit(low), upper_limit(high) { + } +}; + +class Numeric_Field : public NCursesFieldType { +private: + int precision; + double lower_limit, upper_limit; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype, + precision,lower_limit,upper_limit)); + } + +public: + Numeric_Field(int prec, double low=0.0, double high=0.0) + : NCursesFieldType(TYPE_NUMERIC), + precision(prec), lower_limit(low), upper_limit(high) { + } +}; + +class Regular_Expression_Field : public NCursesFieldType { +private: + char* regex; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype,regex)); + } + +public: + Regular_Expression_Field(const char *expr) + : NCursesFieldType(TYPE_REGEXP) { + regex = new char[1+::strlen(expr)]; + (strcpy)(regex,expr); + } + + ~Regular_Expression_Field() { + delete[] regex; + } +}; + +class Enumeration_Field : public NCursesFieldType { +private: + char** list; + int case_sensitive; + int non_unique_matches; + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype, + list,case_sensitive,non_unique_matches)); + } +public: + Enumeration_Field(char* enums[], + bool case_sens=FALSE, + bool non_unique=FALSE) + : NCursesFieldType(TYPE_ENUM), + list(enums), + case_sensitive(case_sens?-1:0), + non_unique_matches(non_unique?-1:0) { + } +}; + +class IPV4_Address_Field : public NCursesFieldType { +private: + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype)); + } + +public: + IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) { + } +}; +// +// ------------------------------------------------------------------------- +// Abstract base class for User-Defined Fieldtypes +// ------------------------------------------------------------------------- +// +class UserDefinedFieldType : public NCursesFieldType { + friend class UDF_Init; // Internal helper to set up statics +private: + // For all C++ defined fieldtypes we need only one generic lowlevel + // FIELDTYPE* element. + static FIELDTYPE* generic_fieldtype; + +protected: + // This are the functions required by the low level libforms functions + // to construct a fieldtype. + static bool fcheck(FIELD *, const void*); + static bool ccheck(int c, const void *); + static void* makearg(va_list*); + + void set(NCursesFormField& f) { + OnError(::set_field_type(f.get_field(),fieldtype,&f)); + } + +protected: + // Redefine this function to do a field validation. The argument + // is a reference to the field you should validate. + virtual bool field_check(NCursesFormField& f) = 0; + + // Redefine this function to do a character validation. The argument + // is the character to be validated. + virtual bool char_check (int c) = 0; + +public: + UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) { + } +}; +// +// ------------------------------------------------------------------------- +// Abstract base class for User-Defined Fieldtypes with Choice functions +// ------------------------------------------------------------------------- +// +class UserDefinedFieldType_With_Choice : public UserDefinedFieldType { + friend class UDF_Init; // Internal helper to set up statics +private: + // For all C++ defined fieldtypes with choice functions we need only one + // generic lowlevel FIELDTYPE* element. + static FIELDTYPE* generic_fieldtype_with_choice; + + // This are the functions required by the low level libforms functions + // to construct a fieldtype with choice functions. + static bool next_choice(FIELD*, const void *); + static bool prev_choice(FIELD*, const void *); + +protected: + // Redefine this function to do the retrieval of the next choice value. + // The argument is a reference to the field tobe examined. + virtual bool next (NCursesFormField& f) = 0; + + // Redefine this function to do the retrieval of the previous choice value. + // The argument is a reference to the field tobe examined. + virtual bool previous(NCursesFormField& f) = 0; + +public: + UserDefinedFieldType_With_Choice() { + fieldtype = generic_fieldtype_with_choice; + } +}; + +#endif // _CURSESF_H + diff --git a/ncurses-5.2/c++/cursesm.cc b/ncurses-5.2/c++/cursesm.cc new file mode 100644 index 0000000..b2f20b3 --- /dev/null +++ b/ncurses-5.2/c++/cursesm.cc @@ -0,0 +1,383 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#include "cursesm.h" +#include "cursesapp.h" +#include "internal.h" + +MODULE_ID("$Id$") + +NCursesMenuItem::~NCursesMenuItem() { + if (item) + OnError(::free_item(item)); +} + +bool +NCursesMenuItem::action() { + return FALSE; +}; + +NCursesMenuCallbackItem::~NCursesMenuCallbackItem() { +} + +bool +NCursesMenuCallbackItem::action() { + if (p_fct) + return p_fct (*this); + else + return FALSE; +} + +/* Internal hook functions. They will route the hook + * calls to virtual methods of the NCursesMenu class, + * so in C++ providing a hook is done simply by + * implementing a virtual method in a derived class + */ +void +NCursesMenu::mnu_init(MENU *m) { + getHook(m)->On_Menu_Init(); +} + +void +NCursesMenu::mnu_term(MENU *m) { + getHook(m)->On_Menu_Termination(); +} + +void +NCursesMenu::itm_init(MENU *m) { + NCursesMenu* M = getHook(m); + M->On_Item_Init (*(M->current_item ())); +} + +void +NCursesMenu::itm_term(MENU *m) { + NCursesMenu* M = getHook(m); + M->On_Item_Termination (*(M->current_item ())); +} + +/* Construct an ITEM* array from an array of NCursesMenuItem + * objects. + */ +ITEM** +NCursesMenu::mapItems(NCursesMenuItem* nitems[]) { + int itemCount = 0,lcv; + + for (lcv=0; nitems[lcv]->item; ++lcv) + ++itemCount; + + ITEM** items = new ITEM*[itemCount + 1]; + + for (lcv=0;nitems[lcv]->item;++lcv) { + items[lcv] = nitems[lcv]->item; + } + items[lcv] = NULL; + + my_items = nitems; + + if (menu) + delete[] ::menu_items(menu); + return items; +} + +void +NCursesMenu::InitMenu(NCursesMenuItem* nitems[], + bool with_frame, + bool autoDelete_Items) { + int mrows, mcols; + + keypad(TRUE); + meta(TRUE); + + b_framed = with_frame; + b_autoDelete = autoDelete_Items; + + menu = (MENU*)0; + menu = ::new_menu(mapItems(nitems)); + if (!menu) + OnError (E_SYSTEM_ERROR); + + UserHook* hook = new UserHook; + hook->m_user = NULL; + hook->m_back = this; + hook->m_owner = menu; + ::set_menu_userptr(menu,(void*)hook); + + ::set_menu_init (menu, NCursesMenu::mnu_init); + ::set_menu_term (menu, NCursesMenu::mnu_term); + ::set_item_init (menu, NCursesMenu::itm_init); + ::set_item_term (menu, NCursesMenu::itm_term); + + scale(mrows, mcols); + ::set_menu_win(menu, w); + + if (with_frame) { + if ((mrows > height()-2) || (mcols > width()-2)) + OnError(E_NO_ROOM); + sub = new NCursesWindow(*this,mrows,mcols,1,1,'r'); + ::set_menu_sub(menu, sub->w); + b_sub_owner = TRUE; + } + else { + sub = (NCursesWindow*)0; + b_sub_owner = FALSE; + } + setDefaultAttributes(); +} + +void +NCursesMenu::setDefaultAttributes() { + NCursesApplication* S = NCursesApplication::getApplication(); + if (S) { + ::set_menu_fore(menu, S->foregrounds()); + ::set_menu_back(menu, S->backgrounds()); + ::set_menu_grey(menu, S->inactives()); + } +} + +NCursesMenu::~NCursesMenu() { + UserHook* hook = (UserHook*)::menu_userptr(menu); + delete hook; + if (b_sub_owner) { + delete sub; + ::set_menu_sub(menu,(WINDOW *)0); + } + if (menu) { + ITEM** itms = ::menu_items(menu); + int cnt = count(); + + OnError(::set_menu_items(menu,(ITEM**)0)); + + if (b_autoDelete) { + if (cnt>0) { + for (int i=0; i <= cnt; i++) + delete my_items[i]; + } + delete[] my_items; + } + + ::free_menu(menu); + // It's essential to do this after free_menu() + delete[] itms; + } +} + +void +NCursesMenu::setSubWindow(NCursesWindow& nsub) { + if (!isDescendant(nsub)) + OnError(E_SYSTEM_ERROR); + else { + if (b_sub_owner) + delete sub; + sub = ⊄ + ::set_menu_sub(menu,sub->w); + } +} + +bool +NCursesMenu::set_pattern (const char *pat) { + int res = ::set_menu_pattern (menu, pat); + switch(res) { + case E_OK: + break; + case E_NO_MATCH: + return FALSE; + default: + OnError (res); + } + return TRUE; +} + +// call the menu driver and do basic error checking. +int +NCursesMenu::driver (int c) { + int res = ::menu_driver (menu, c); + switch (res) { + case E_OK: + case E_REQUEST_DENIED: + case E_NOT_SELECTABLE: + case E_UNKNOWN_COMMAND: + case E_NO_MATCH: + break; + default: + OnError (res); + } + return (res); +} + +static const int CMD_QUIT = MAX_COMMAND + 1; +static const int CMD_ACTION = MAX_COMMAND + 2; +// +// ------------------------------------------------------------------------- +// Provide a default key virtualization. Translate the keyboard +// code c into a menu request code. +// The default implementation provides a hopefully straightforward +// mapping for the most common keystrokes and menu requests. +// ------------------------------------------------------------------------- +int +NCursesMenu::virtualize(int c) { + switch(c) { + case CTRL('X') : return(CMD_QUIT); // eXit + + case KEY_DOWN : return(REQ_DOWN_ITEM); + case CTRL('N') : return(REQ_NEXT_ITEM); // Next + case KEY_UP : return(REQ_UP_ITEM); + case CTRL('P') : return(REQ_PREV_ITEM); // Previous + + case CTRL('U') : return(REQ_SCR_ULINE); // Up + case CTRL('D') : return(REQ_SCR_DLINE); // Down + case CTRL('F') : return(REQ_SCR_DPAGE); // Forward + case CTRL('B') : return(REQ_SCR_UPAGE); // Backward + + case CTRL('Y') : return(REQ_CLEAR_PATTERN); + case CTRL('H') : return(REQ_BACK_PATTERN); + case CTRL('A') : return(REQ_NEXT_MATCH); + case CTRL('E') : return(REQ_PREV_MATCH); + case CTRL('T') : return(REQ_TOGGLE_ITEM); + + case CTRL('J') : + case CTRL('M') : return(CMD_ACTION); + + case KEY_HOME : return(REQ_FIRST_ITEM); + case KEY_LEFT : return(REQ_LEFT_ITEM); + case KEY_RIGHT : return(REQ_RIGHT_ITEM); + case KEY_END : return(REQ_LAST_ITEM); + case KEY_BACKSPACE : return(REQ_BACK_PATTERN); + case KEY_NPAGE : return(REQ_SCR_DPAGE); + case KEY_PPAGE : return(REQ_SCR_UPAGE); + + default: + return(c); + } +} + +NCursesMenuItem* +NCursesMenu::operator()(void) { + int drvCmnd; + int err; + int c; + bool b_action = FALSE; + + post(); + show(); + refresh(); + + while (!b_action && ((drvCmnd = virtualize((c=getch()))) != CMD_QUIT)) { + + switch((err=driver(drvCmnd))) { + case E_REQUEST_DENIED: + On_Request_Denied(c); + break; + case E_NOT_SELECTABLE: + On_Not_Selectable(c); + break; + case E_UNKNOWN_COMMAND: + if (drvCmnd == CMD_ACTION) { + if (options() & O_ONEVALUE) { + NCursesMenuItem* itm = current_item(); + assert(itm != 0); + if (itm->options() & O_SELECTABLE) + { + b_action = itm->action(); + refresh(); + } + else + On_Not_Selectable(c); + } + else { + int n = count(); + for(int i=0; ivalue()) { + b_action |= itm->action(); + refresh(); + } + } + } + } else + On_Unknown_Command(c); + break; + case E_NO_MATCH: + On_No_Match(c); + break; + case E_OK: + break; + default: + OnError(err); + } + } + + unpost(); + hide(); + refresh(); + if (options() & O_ONEVALUE) + return my_items[::item_index (::current_item (menu))]; + else + return NULL; +} + +void +NCursesMenu::On_Menu_Init() { +} + +void +NCursesMenu::On_Menu_Termination() { +} + +void +NCursesMenu::On_Item_Init(NCursesMenuItem& item) { +} + +void +NCursesMenu::On_Item_Termination(NCursesMenuItem& item) { +} + +void +NCursesMenu::On_Request_Denied(int c) const { + beep(); +} + +void +NCursesMenu::On_Not_Selectable(int c) const { + beep(); +} + +void +NCursesMenu::On_No_Match(int c) const { + beep(); +} + +void +NCursesMenu::On_Unknown_Command(int c) const { + beep(); +} + diff --git a/ncurses-5.2/c++/cursesm.h b/ncurses-5.2/c++/cursesm.h new file mode 100644 index 0000000..8c14c56 --- /dev/null +++ b/ncurses-5.2/c++/cursesm.h @@ -0,0 +1,592 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _CURSESM_H +#define _CURSESM_H + +#include + +extern "C" { +# include +} +// +// ------------------------------------------------------------------------- +// This wraps the ITEM type of +// ------------------------------------------------------------------------- +// +class NCursesMenuItem { + friend class NCursesMenu; + +protected: + ITEM *item; + + inline void OnError (int err) const THROWS(NCursesMenuException) { + if (err != E_OK) + THROW(new NCursesMenuException (err)); + } + +public: + NCursesMenuItem (const char* p_name = NULL, + const char* p_descript = NULL ) { + item = p_name ? ::new_item (p_name, p_descript) : (ITEM*)0; + if (p_name && !item) + OnError (E_SYSTEM_ERROR); + } + // Create an item. If you pass both parameters as NULL, a delimiting + // item is constructed which can be used to terminate a list of + // NCursesMenu objects. + + virtual ~NCursesMenuItem (); + // Release the items memory + + inline const char* name () const { + return ::item_name (item); + } + // Name of the item + + inline const char* description () const { + return ::item_description (item); + } + // Description of the item + + inline int (index) (void) const { + return ::item_index (item); + } + // Index of the item in an item array (or -1) + + inline void options_on (Item_Options options) { + OnError (::item_opts_on (item, options)); + } + // Switch on the items options + + inline void options_off (Item_Options options) { + OnError (::item_opts_off (item, options)); + } + // Switch off the item's option + + inline Item_Options options () const { + return ::item_opts (item); + } + // Retrieve the items options + + inline void set_options (Item_Options options) { + OnError (::set_item_opts (item, options)); + } + // Set the items options + + inline void set_value (bool f) { + OnError (::set_item_value (item,f)); + } + // Set/Reset the items selection state + + inline bool value () const { + return ::item_value (item); + } + // Retrieve the items selection state + + inline bool visible () const { + return ::item_visible (item); + } + // Retrieve visibility of the item + + virtual bool action(); + // Perform an action associated with this item; you may use this in an + // user supplied driver for a menu; you may derive from this class and + // overload action() to supply items with different actions. + // If an action returns true, the menu will be exited. The default action + // is to do nothing. +}; + +// Prototype for an items callback function. +typedef bool ITEMCALLBACK(NCursesMenuItem&); + +// If you don't like to create a child class for individual items to +// overload action(), you may use this class and provide a callback +// function pointer for items. +class NCursesMenuCallbackItem : public NCursesMenuItem { +private: + ITEMCALLBACK* p_fct; + +public: + NCursesMenuCallbackItem(ITEMCALLBACK* fct = NULL, + const char* p_name = NULL, + const char* p_descript = NULL ) + : NCursesMenuItem (p_name, p_descript), + p_fct (fct) { + } + + virtual ~NCursesMenuCallbackItem(); + + bool action(); +}; +// +// ------------------------------------------------------------------------- +// This wraps the MENU type of +// ------------------------------------------------------------------------- +// +class NCursesMenu : public NCursesPanel { +protected: + MENU *menu; + +private: + NCursesWindow* sub; // the subwindow object + bool b_sub_owner; // is this our own subwindow? + bool b_framed; // has the menu a border? + bool b_autoDelete; // Delete items when deleting menu? + + NCursesMenuItem** my_items; // The array of items for this menu + + // This structure is used for the menu's user data field to link the + // MENU* to the C++ object and to provide extra space for a user pointer. + typedef struct { + void* m_user; // the pointer for the user's data + const NCursesMenu* m_back; // backward pointer to C++ object + const MENU* m_owner; + } UserHook; + + // Get the backward pointer to the C++ object from a MENU + static inline NCursesMenu* getHook(const MENU *m) { + UserHook* hook = (UserHook*)::menu_userptr(m); + assert(hook != 0 && hook->m_owner==m); + return (NCursesMenu*)(hook->m_back); + } + + // This are the built-in hook functions in this C++ binding. In C++ we use + // virtual member functions (see below On_..._Init and On_..._Termination) + // to provide this functionality in an object oriented manner. + static void mnu_init(MENU *); + static void mnu_term(MENU *); + static void itm_init(MENU *); + static void itm_term(MENU *); + + // Calculate ITEM* array for the menu + ITEM** mapItems(NCursesMenuItem* nitems[]); + +protected: + // internal routines + inline void set_user(void *user) { + UserHook* uptr = (UserHook*)::menu_userptr (menu); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu); + uptr->m_user = user; + } + + inline void *get_user() { + UserHook* uptr = (UserHook*)::menu_userptr (menu); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu); + return uptr->m_user; + } + + void InitMenu (NCursesMenuItem* menu[], + bool with_frame, + bool autoDeleteItems); + + inline void OnError (int err) const THROWS(NCursesMenuException) { + if (err != E_OK) + THROW(new NCursesMenuException (this, err)); + } + + // this wraps the menu_driver call. + virtual int driver (int c) ; + + // 'Internal' constructor to create a menu without association to + // an array of items. + NCursesMenu( int lines, + int cols, + int begin_y = 0, + int begin_x = 0) + : NCursesPanel(lines,cols,begin_y,begin_x), + menu ((MENU*)0) { + } + +public: + // Make a full window size menu + NCursesMenu (NCursesMenuItem* Items[], + bool with_frame=FALSE, // Reserve space for a frame? + bool autoDelete_Items=FALSE) // Autocleanup of Items? + : NCursesPanel() { + InitMenu(Items, with_frame, autoDelete_Items); + } + + // Make a menu with a window of this size. + NCursesMenu (NCursesMenuItem* Items[], + int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + bool with_frame=FALSE, // Reserve space for a frame? + bool autoDelete_Items=FALSE) // Autocleanup of Items? + : NCursesPanel(lines, cols, begin_y, begin_x) { + InitMenu(Items, with_frame, autoDelete_Items); + } + + virtual ~NCursesMenu (); + + // Retrieve the menus subwindow + inline NCursesWindow& subWindow() const { + assert(sub!=NULL); + return *sub; + } + + // Set the menus subwindow + void setSubWindow(NCursesWindow& sub); + + // Set these items for the menu + inline void setItems(NCursesMenuItem* Items[]) { + OnError(::set_menu_items(menu,mapItems(Items))); + } + + // Remove the menu from the screen + inline void unpost (void) { + OnError (::unpost_menu (menu)); + } + + // Post the menu to the screen if flag is true, unpost it otherwise + inline void post(bool flag = TRUE) { + flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu)); + } + + // Get the numer of rows and columns for this menu + inline void scale (int& mrows, int& mcols) const { + OnError (::scale_menu (menu, &mrows, &mcols)); + } + + // Set the format of this menu + inline void set_format(int mrows, int mcols) { + OnError (::set_menu_format(menu, mrows, mcols)); + } + + // Get the format of this menu + inline void menu_format(int& rows,int& cols) { + ::menu_format(menu,&rows,&cols); + } + + // Items of the menu + inline NCursesMenuItem* items() const { + return *my_items; + } + + // Get the number of items in this menu + inline int count() const { + return ::item_count(menu); + } + + // Get the current item (i.e. the one the cursor is located) + inline NCursesMenuItem* current_item() const { + return my_items[::item_index(::current_item(menu))]; + } + + // Get the marker string + inline const char* mark() const { + return ::menu_mark(menu); + } + + // Set the marker string + inline void set_mark(const char *mark) { + OnError (::set_menu_mark (menu, mark)); + } + + // Get the name of the request code c + inline static const char* request_name(int c) { + return ::menu_request_name(c); + } + + // Get the current pattern + inline char* pattern() const { + return ::menu_pattern(menu); + } + + // true if there is a pattern match, false otherwise. + bool set_pattern (const char *pat); + + // set the default attributes for the menu + // i.e. set fore, back and grey attribute + virtual void setDefaultAttributes(); + + // Get the menus background attributes + inline chtype back() const { + return ::menu_back(menu); + } + + // Get the menus foreground attributes + inline chtype fore() const { + return ::menu_fore(menu); + } + + // Get the menus grey attributes (used for unselectable items) + inline chtype grey() const { + return ::menu_grey(menu); + } + + // Set the menus background attributes + inline chtype set_background(chtype a) { + return ::set_menu_back(menu,a); + } + + // Set the menus foreground attributes + inline chtype set_foreground(chtype a) { + return ::set_menu_fore(menu,a); + } + + // Set the menus grey attributes (used for unselectable items) + inline chtype set_grey(chtype a) { + return ::set_menu_grey(menu,a); + } + + inline void options_on (Menu_Options opts) { + OnError (::menu_opts_on (menu,opts)); + } + + inline void options_off(Menu_Options opts) { + OnError (::menu_opts_off(menu,opts)); + } + + inline Menu_Options options() const { + return ::menu_opts(menu); + } + + inline void set_options (Menu_Options opts) { + OnError (::set_menu_opts (menu,opts)); + } + + inline int pad() const { + return ::menu_pad(menu); + } + + inline void set_pad (int padch) { + OnError (::set_menu_pad (menu, padch)); + } + + // Position the cursor to the current item + inline void position_cursor () const { + OnError (::pos_menu_cursor (menu)); + } + + // Set the current item + inline void set_current(NCursesMenuItem& I) { + OnError (::set_current_item(menu, I.item)); + } + + // Get the current top row of the menu + inline int top_row (void) const { + return ::top_row (menu); + } + + // Set the current top row of the menu + inline void set_top_row (int row) { + OnError (::set_top_row (menu, row)); + } + + // spacing control + // Set the spacing for the menu + inline void setSpacing(int spc_description, + int spc_rows, + int spc_columns) { + OnError(::set_menu_spacing(menu, + spc_description, + spc_rows, + spc_columns)); + } + + // Get the spacing info for the menu + inline void Spacing(int& spc_description, + int& spc_rows, + int& spc_columns) const { + OnError(::menu_spacing(menu, + &spc_description, + &spc_rows, + &spc_columns)); + } + + // Decorations + inline void frame(const char *title=NULL, const char* btitle=NULL) { + if (b_framed) + NCursesPanel::frame(title,btitle); + else + OnError(E_SYSTEM_ERROR); + } + + inline void boldframe(const char *title=NULL, const char* btitle=NULL) { + if (b_framed) + NCursesPanel::boldframe(title,btitle); + else + OnError(E_SYSTEM_ERROR); + } + + inline void label(const char *topLabel, const char *bottomLabel) { + if (b_framed) + NCursesPanel::label(topLabel,bottomLabel); + else + OnError(E_SYSTEM_ERROR); + } + + // ----- + // Hooks + // ----- + + // Called after the menu gets repositioned in its window. + // This is especially true if the menu is posted. + virtual void On_Menu_Init(); + + // Called before the menu gets repositioned in its window. + // This is especially true if the menu is unposted. + virtual void On_Menu_Termination(); + + // Called after the item became the current item + virtual void On_Item_Init(NCursesMenuItem& item); + + // Called before this item is left as current item. + virtual void On_Item_Termination(NCursesMenuItem& item); + + // Provide a default key virtualization. Translate the keyboard + // code c into a menu request code. + // The default implementation provides a hopefully straightforward + // mapping for the most common keystrokes and menu requests. + virtual int virtualize(int c); + + + // Operators + inline NCursesMenuItem* operator[](int i) const { + if ( (i < 0) || (i >= ::item_count (menu)) ) + OnError (E_BAD_ARGUMENT); + return (my_items[i]); + } + + // Perform the menu's operation + // Return the item where you left the selection mark for a single + // selection menu, or NULL for a multivalued menu. + virtual NCursesMenuItem* operator()(void); + + // -------------------- + // Exception handlers + // Called by operator() + // -------------------- + + // Called if the request is denied + virtual void On_Request_Denied(int c) const; + + // Called if the item is not selectable + virtual void On_Not_Selectable(int c) const; + + // Called if pattern doesn't match + virtual void On_No_Match(int c) const; + + // Called if the command is unknown + virtual void On_Unknown_Command(int c) const; + +}; +// +// ------------------------------------------------------------------------- +// This is the typical C++ typesafe way to allow to attach +// user data to an item of a menu. Its assumed that the user +// data belongs to some class T. Use T as template argument +// to create a UserItem. +// ------------------------------------------------------------------------- +// +template class NCursesUserItem : public NCursesMenuItem +{ +public: + NCursesUserItem (const char* p_name, + const char* p_descript = NULL, + const T* p_UserData = (T*)0) + : NCursesMenuItem (p_name, p_descript) { + if (item) + OnError (::set_item_userptr (item, (void *)p_UserData)); + }; + + virtual ~NCursesUserItem() {}; + + inline const T* UserData (void) const { + return (const T*)::item_userptr (item); + }; + + inline virtual void setUserData(const T* p_UserData) { + if (item) + OnError (::set_item_userptr (item, (void *)p_UserData)); + } +}; +// +// ------------------------------------------------------------------------- +// The same mechanism is used to attach user data to a menu +// ------------------------------------------------------------------------- +// +template class NCursesUserMenu : public NCursesMenu +{ +protected: + NCursesUserMenu( int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + const T* p_UserData = (T*)0) + : NCursesMenu(lines,cols,begin_y,begin_x) { + if (menu) + set_user ((void *)p_UserData); + } + +public: + NCursesUserMenu (NCursesMenuItem Items[], + const T* p_UserData = (T*)0, + bool with_frame=FALSE, + bool autoDelete_Items=FALSE) + : NCursesMenu (Items, with_frame, autoDelete_Items) { + if (menu) + set_user ((void *)p_UserData); + }; + + NCursesUserMenu (NCursesMenuItem Items[], + int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + const T* p_UserData = (T*)0, + bool with_frame=FALSE) + : NCursesMenu (Items, lines, cols, begin_y, begin_x, with_frame) { + if (menu) + set_user ((void *)p_UserData); + }; + + virtual ~NCursesUserMenu() { + }; + + inline T* UserData (void) const { + return (T*)get_user (); + }; + + inline virtual void setUserData (const T* p_UserData) { + if (menu) + set_user ((void *)p_UserData); + } +}; + +#endif // _CURSESM_H diff --git a/ncurses-5.2/c++/cursesmain.cc b/ncurses-5.2/c++/cursesmain.cc new file mode 100644 index 0000000..33f36d5 --- /dev/null +++ b/ncurses-5.2/c++/cursesmain.cc @@ -0,0 +1,51 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#include "cursesapp.h" +#include "internal.h" + +MODULE_ID("$Id$") + +/* This is the default implementation of main() for a NCursesApplication. + * You only have to instantiate a static NCursesApplication object in your + * main application source file and link this module with your application. + */ +int main(int argc, char* argv[]) +{ + NCursesApplication* A = NCursesApplication::getApplication(); + if (!A) + return(1); + A->handleArgs(argc,argv); + ::endwin(); + return((*A)()); +} diff --git a/ncurses-5.2/c++/cursesp.cc b/ncurses-5.2/c++/cursesp.cc new file mode 100644 index 0000000..36278fe --- /dev/null +++ b/ncurses-5.2/c++/cursesp.cc @@ -0,0 +1,124 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1993,1997 * + ****************************************************************************/ + +#include "cursesp.h" +#include "internal.h" +#include + +MODULE_ID("$Id$") + +NCursesPanel* NCursesPanel::dummy = (NCursesPanel*)0; + +void NCursesPanel::init() { + p = ::new_panel(w); + if (!p) + OnError(ERR); + + UserHook* hook = new UserHook; + hook->m_user = NULL; + hook->m_back = this; + hook->m_owner = p; + ::set_panel_userptr(p, (void *)hook); +} + +NCursesPanel::~NCursesPanel() { + UserHook* hook = (UserHook*)::panel_userptr(p); + assert(hook != 0 && hook->m_back==this && hook->m_owner==p); + delete hook; + ::del_panel(p); + ::update_panels(); +} + +void +NCursesPanel::redraw() { + PANEL *pan; + + pan = ::panel_above(NULL); + while (pan) { + ::touchwin(panel_window(pan)); + pan = ::panel_above(pan); + } + ::update_panels(); + ::doupdate(); +} + +int +NCursesPanel::refresh() { + ::update_panels(); + return doupdate(); +} + +int +NCursesPanel::noutrefresh() { + ::update_panels(); + return OK; +} + +void +NCursesPanel::boldframe(const char *title, const char* btitle) { + standout(); + frame(title, btitle); + standend(); +} + +void +NCursesPanel::frame(const char *title,const char *btitle) { + int err = OK; + if (!title && !btitle) { + err = box(); + } + else { + err = box(); + if (err==OK) + label(title,btitle); + } + OnError(err); +} + +void +NCursesPanel::label(const char *tLabel, const char *bLabel) { + if (tLabel) + centertext(0,tLabel); + if (bLabel) + centertext(maxy(),bLabel); +} + +void +NCursesPanel::centertext(int row,const char *label) { + if (label) { + int x = (maxx() - strlen(label)) / 2; + if (x<0) + x=0; + OnError(addstr(row, x, label, width())); + } +} diff --git a/ncurses-5.2/c++/cursesp.h b/ncurses-5.2/c++/cursesp.h new file mode 100644 index 0000000..7b37645 --- /dev/null +++ b/ncurses-5.2/c++/cursesp.h @@ -0,0 +1,218 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#ifndef _CURSESP_H +#define _CURSESP_H + +// $Id$ + +#include + +extern "C" { +# include +} + +class NCursesPanel : public NCursesWindow { +protected: + PANEL *p; + static NCursesPanel *dummy; + +private: + // This structure is used for the panel's user data field to link the + // PANEL* to the C++ object and to provide extra space for a user pointer. + typedef struct { + void* m_user; // the pointer for the user's data + const NCursesPanel* m_back; // backward pointer to C++ object + const PANEL* m_owner; // the panel itself + } UserHook; + + void init(); // Initialize the panel object + +protected: + void set_user(void *user) { + UserHook* uptr = (UserHook*)::panel_userptr (p); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==p); + uptr->m_user = user; + } + // Set the user pointer of the panel. + + void *get_user() { + UserHook* uptr = (UserHook*)::panel_userptr (p); + assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==p); + return uptr->m_user; + } + + void OnError (int err) const THROWS((NCursesPanelException)) { + if (err==ERR) + THROW(new NCursesPanelException (this, err)); + } + // If err is equal to the curses error indicator ERR, an error handler + // is called. + +public: + NCursesPanel(int lines, + int cols, + int begin_y = 0, + int begin_x = 0) + : NCursesWindow(lines,cols,begin_y,begin_x) { + init(); + } + // Create a panel with this size starting at the requested position. + + NCursesPanel() : NCursesWindow(::stdscr) { init(); } + // This constructor creates the default Panel associated with the + // ::stdscr window + + virtual ~NCursesPanel(); + + // basic manipulation + inline void hide() { + OnError (::hide_panel(p)); + } + // Hide the panel. It stays in the stack but becomes invisible. + + inline void show() { + OnError (::show_panel(p)); + } + // Show the panel, i.e. make it visible. + + inline void top() { + OnError (::top_panel(p)); + } + // Make this panel the top panel in the stack. + + inline void bottom() { + OnError (::bottom_panel(p)); + } + // Make this panel the bottom panel in the stack. + // N.B.: The panel associated with ::stdscr is always on the bottom. So + // actually bottom() makes the panel the first above ::stdscr. + + virtual int mvwin(int y, int x) { + OnError(::move_panel(p, y, x)); + return OK; + } + + inline bool hidden() const { + return (::panel_hidden (p) ? TRUE : FALSE); + } + // Return TRUE if the panel is hidden, FALSE otherwise. + +/* The functions panel_above() and panel_below() are not reflected in + the NCursesPanel class. The reason for this is, that we cannot + assume that a panel retrieved by those operations is one wrapped + by a C++ class. Although this situation might be handled, we also + need a reverse mapping from PANEL to NCursesPanel which needs some + redesign of the low level stuff. At the moment, we define them in the + interface but they will always produce an error. */ + inline NCursesPanel& above() const { + OnError(ERR); + return *dummy; + } + + inline NCursesPanel& below() const { + OnError(ERR); + return *dummy; + } + + // Those two are rewrites of the corresponding virtual members of + // NCursesWindow + virtual int refresh(); + // Propagate all panel changes to the virtual screen and update the + // physical screen. + + virtual int noutrefresh(); + // Propagate all panel changes to the virtual screen. + + static void redraw(); + // Redraw all panels. + + // decorations + virtual void frame(const char* title=NULL, + const char* btitle=NULL); + // Put a frame around the panel and put the title centered in the top line + // and btitle in the bottom line. + + virtual void boldframe(const char* title=NULL, + const char* btitle=NULL); + // Same as frame(), but use highlighted attributes. + + virtual void label(const char* topLabel, + const char* bottomLabel); + // Put the title centered in the top line and btitle in the bottom line. + + virtual void centertext(int row,const char* label); + // Put the label text centered in the specified row. +}; + +/* We use templates to provide a typesafe mechanism to associate + * user data with a panel. A NCursesUserPanel is a panel + * associated with some user data of type T. + */ +template class NCursesUserPanel : public NCursesPanel +{ +public: + NCursesUserPanel (int lines, + int cols, + int begin_y = 0, + int begin_x = 0, + const T* p_UserData = (T*)0) + : NCursesPanel (lines, cols, begin_y, begin_x) { + if (p) + set_user ((void *)p_UserData); + }; + // This creates an user panel of the requested size with associated + // user data pointed to by p_UserData. + + NCursesUserPanel(const T* p_UserData = (T*)0) : NCursesPanel() { + if (p) + set_user((void *)p_UserData); + }; + // This creates an user panel associated with the ::stdscr and user data + // pointed to by p_UserData. + + virtual ~NCursesUserPanel() {}; + + T* UserData (void) const { + return (T*)get_user (); + }; + // Retrieve the user data associated with the panel. + + virtual void setUserData (const T* p_UserData) { + if (p) + set_user ((void *)p_UserData); + } + // Associate the user panel with the user data pointed to by p_UserData. +}; + +#endif // _CURSESP_H diff --git a/ncurses-5.2/c++/cursespad.cc b/ncurses-5.2/c++/cursespad.cc new file mode 100644 index 0000000..e1ae334 --- /dev/null +++ b/ncurses-5.2/c++/cursespad.cc @@ -0,0 +1,270 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1999 * + ****************************************************************************/ + +#include "etip.h" +#include "cursesw.h" +#include "internal.h" + +MODULE_ID("$Id$") + +NCursesPad::NCursesPad(int lines, int cols) + : NCursesWindow(), + viewWin((NCursesWindow*)0), + viewSub((NCursesWindow*)0), + h_gridsize(0), v_gridsize(0), + min_row(0), min_col(0) +{ + w = ::newpad(lines,cols); + if ((WINDOW*)0==w) { + count--; + err_handler("Cannot construct window"); + } + alloced = TRUE; +} + + +int NCursesPad::driver (int key) { + // Default implementation + switch(key) { + case KEY_UP: + // ======= + return REQ_PAD_UP; + case KEY_DOWN: + // ========= + return REQ_PAD_DOWN; + case KEY_LEFT: + // ========= + return REQ_PAD_LEFT; + case KEY_RIGHT: + // ========== + return REQ_PAD_RIGHT; + case KEY_EXIT: + // ========= + case CTRL('X'): + // ========== + return REQ_PAD_EXIT; + + default: return(key); + } +} + + +void NCursesPad::operator()(void) { + NCursesWindow* W = Win(); + + if ((NCursesWindow*)0 != W) { + int Width = W->width(); + int Height = W->height(); + + int req = REQ_PAD_REFRESH; + + W->keypad(TRUE); + W->meta(TRUE); + refresh(); + + do { + bool changed = FALSE; + + switch (req) { + case REQ_PAD_REFRESH: + // ================ + changed = TRUE; + break; + case REQ_PAD_LEFT: + // ============= + if (min_col > 0) { + changed = TRUE; + if (min_col < h_gridsize) + min_col = 0; + else + min_col -= h_gridsize; + } + else + OnNavigationError(req); + break; + case REQ_PAD_RIGHT: + // ============== + if (min_col < (width() - Width - 1)) { + changed = TRUE; + if (min_col > (width() - Width - h_gridsize - 1)) + min_col = width() - Width - 1; + else + min_col += h_gridsize; + } + else + OnNavigationError(req); + break; + case REQ_PAD_UP: + // =========== + if (min_row > 0) { + changed = TRUE; + if (min_row < v_gridsize) + min_row = 0; + else + min_row -= v_gridsize; + } + else + OnNavigationError(req); + break; + case REQ_PAD_DOWN: + // ============= + if (min_row < (height() - Height - 1)) { + changed = TRUE; + if (min_row > (height() - Height - v_gridsize - 1)) + min_row = height() - Height - 1; + else + min_row += v_gridsize; + } + else + OnNavigationError(req); + break; + + default: + OnUnknownOperation(req); + } + + if (changed) { + noutrefresh(); + W->syncup(); + OnOperation(req); + viewWin->refresh(); + } + } while( (req=driver(W->getch())) != REQ_PAD_EXIT ); + } +} + + +int NCursesPad::refresh() { + int res = noutrefresh(); + if (res==OK && ((NCursesWindow*)0 != viewWin)) { + res = (viewWin->refresh()); + } + return(res); +} + +int NCursesPad::noutrefresh() { + int res = OK; + NCursesWindow* W = Win(); + if ((NCursesWindow*)0 != W) { + res = copywin(*W,min_row,min_col, + 0,0,W->maxy(),W->maxx(), + FALSE); + if (res==OK) { + W->syncup(); + res = viewWin->noutrefresh(); + } + } + return (res); +} + +void NCursesPad::setWindow(NCursesWindow& view, + int v_grid NCURSES_PARAM_INIT(1), + int h_grid NCURSES_PARAM_INIT(1)) +{ + viewWin = &view; + min_row = min_col = 0; + if (h_grid <=0 || v_grid <= 0) + err_handler("Illegal Gridsize"); + else { + h_gridsize = h_grid; + v_gridsize = v_grid; + } +} + +void NCursesPad::setSubWindow(NCursesWindow& sub) +{ + if ((NCursesWindow*)0 == viewWin) + err_handler("Pad has no viewport"); + if (!viewWin->isDescendant(sub)) + THROW(new NCursesException("NCursesFramePad", E_SYSTEM_ERROR)); + viewSub = ⊂ +} + +void NCursesFramedPad::OnOperation(int pad_req) { + NCursesWindow* W = Win(); + NCursesWindow* Win = getWindow(); + + if (((NCursesWindow*)0 != W) && ((NCursesWindow*)0 != Win)) { + int Width = W->width(); + int Height = W->height(); + int i, row, col, h_len, v_len; + + h_len = (Width*Width + width() - 1)/width(); + if (h_len==0) + h_len = 1; + if (h_len > Width) + h_len = Width; + + v_len = (Height*Height + height() - 1)/height(); + if (v_len==0) + v_len = 1; + if (v_len > Height) + v_len = Height; + + col = (min_col * Width + width() - 1) / width(); + if (col + h_len > Width) + col = Width - h_len; + + row = (min_row * Height + height() - 1) / height(); + if (row + v_len > Height) + row = Height - v_len; + + Win->vline(1,Width+1,Height); + Win->attron(A_REVERSE); + if (v_len>=2) { + Win->addch(row+1,Width+1,ACS_UARROW); + for(i=2;iaddch(row+i,Width+1,' '); + Win->addch(row+v_len,Width+1,ACS_DARROW); + } + else { + for(i=1;i<=v_len;i++) + Win->addch(row+i,Width+1,' '); + } + Win->attroff(A_REVERSE); + + Win->hline(Height+1,1,Width); + Win->attron(A_REVERSE); + if (h_len >= 2) { + Win->addch(Height+1,col+1,ACS_LARROW); + for(i=2;iaddch(Height+1,col+i,' '); + Win->addch(Height+1,col+h_len,ACS_RARROW); + } + else { + for(i=1;i<=h_len;i++) + Win->addch(Height+1,col+i,' '); + } + Win->attroff(A_REVERSE); + } +} diff --git a/ncurses-5.2/c++/cursesw.cc b/ncurses-5.2/c++/cursesw.cc new file mode 100644 index 0000000..514347d --- /dev/null +++ b/ncurses-5.2/c++/cursesw.cc @@ -0,0 +1,434 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- + +/* + Copyright (C) 1989 Free Software Foundation + written by Eric Newton (newton@rocky.oswego.edu) + + This file is part of the GNU C++ Library. This library is free + software; you can redistribute it and/or modify it under the terms of + the GNU Library General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. This library 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 Library General Public License for more details. + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + modified by Ulrich Drepper (drepper@karlsruhe.gmd.de) + and Anatoly Ivasyuk (anatoly@nick.csh.rit.edu) + + modified by Juergen Pfeifer (juergen.pfeifer@gmx.net) +*/ + +#include "cursesw.h" +#include "internal.h" + +MODULE_ID("$Id$") + +#define COLORS_NEED_INITIALIZATION -1 +#define COLORS_NOT_INITIALIZED 0 +#define COLORS_MONOCHROME 1 +#define COLORS_ARE_REALLY_THERE 2 + +// declare static variables for the class +long NCursesWindow::count = 0L; +bool NCursesWindow::b_initialized = FALSE; + +#if defined(__GNUG__) +# ifndef _IO_va_list +# define _IO_va_list char * +# endif +#endif + +int +NCursesWindow::scanw(const char* fmt, ...) +{ +#if defined(__GNUG__) + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + int result = wgetstr(w, buf); + if (result == OK) { + strstreambuf ss(buf, sizeof(buf)); + result = ss.vscan(fmt, (_IO_va_list)args); + } + va_end(args); + return result; +#else + return ERR; +#endif +} + + +int +NCursesWindow::scanw(int y, int x, const char* fmt, ...) +{ +#if defined(__GNUG__) + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + int result = wmove(w, y, x); + if (result == OK) { + result = wgetstr(w, buf); + if (result == OK) { + strstreambuf ss(buf, sizeof(buf)); + result = ss.vscan(fmt, (_IO_va_list)args); + } + } + va_end(args); + return result; +#else + return ERR; +#endif +} + + +int +NCursesWindow::printw(const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + char buf[BUFSIZ]; + vsprintf(buf, fmt, args); + va_end(args); + return waddstr(w, buf); +} + + +int +NCursesWindow::printw(int y, int x, const char * fmt, ...) +{ + va_list args; + va_start(args, fmt); + int result = wmove(w, y, x); + if (result == OK) { + char buf[BUFSIZ]; + vsprintf(buf, fmt, args); + result = waddstr(w, buf); + } + va_end(args); + return result; +} + + +void +NCursesWindow::init(void) +{ + leaveok(0); + keypad(1); + meta(1); +} + +void +NCursesWindow::err_handler(const char *msg) const THROWS(NCursesException) +{ + THROW(new NCursesException(msg)); +} + +void +NCursesWindow::initialize() { + if (!b_initialized) { + ::initscr(); + b_initialized = TRUE; + if (colorInitialized==COLORS_NEED_INITIALIZATION) { + colorInitialized=COLORS_NOT_INITIALIZED; + useColors(); + } + ::noecho(); + ::cbreak(); + } +} + +NCursesWindow::NCursesWindow() { + if (!b_initialized) + initialize(); + + w = (WINDOW *)0; + init(); + alloced = FALSE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(int lines, int cols, int begin_y, int begin_x) +{ + if (!b_initialized) + initialize(); + + w = ::newwin(lines, cols, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct window"); + } + init(); + + alloced = TRUE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(WINDOW* &window) +{ + if (!b_initialized) + initialize(); + + w = window; + init(); + alloced = FALSE; + subwins = par = sib = 0; + count++; +} + +NCursesWindow::NCursesWindow(NCursesWindow& win, int l, int c, + int begin_y, int begin_x, char absrel) +{ + if (absrel == 'a') { // absolute origin + begin_y -= win.begy(); + begin_x -= win.begx(); + } + + // Even though we treat subwindows as a tree, the standard curses + // library needs the `subwin' call to link to the parent in + // order to correctly perform refreshes, etc. + // Friendly enough, this also works for pads. + w = ::derwin(win.w, l, c, begin_y, begin_x); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + alloced = TRUE; + count++; +} + +NCursesWindow::NCursesWindow(NCursesWindow& win, + bool do_box NCURSES_PARAM_INIT(TRUE)) +{ + w = :: derwin(win.w,win.height()-2,win.width()-2,1,1); + if (w == 0) { + err_handler("Cannot construct subwindow"); + } + + par = &win; + sib = win.subwins; + win.subwins = this; + subwins = 0; + alloced = TRUE; + count++; + + if (do_box) { + win.box(); + win.touchwin(); + } +} + +NCursesWindow NCursesWindow::Clone() { + WINDOW *d = ::dupwin(w); + NCursesWindow W(d); + W.subwins = subwins; + W.sib = sib; + W.par = par; + W.alloced = alloced; + return W; +} + +typedef int (*RIPOFFINIT)(NCursesWindow&); +static RIPOFFINIT R_INIT[5]; // There can't be more +static int r_init_idx = 0; +static RIPOFFINIT* prip = R_INIT; + +extern "C" int _nc_ripoffline(int,int (*init)(WINDOW*,int)); + +NCursesWindow::NCursesWindow(WINDOW *win, int cols) { + w = win; + assert((w->_maxx+1)==cols); + alloced = FALSE; + subwins = par = sib = 0; +} + +int NCursesWindow::ripoff_init(WINDOW *w, int cols) +{ + int res = ERR; + + RIPOFFINIT init = *prip++; + if (init) { + NCursesWindow* W = new NCursesWindow(w,cols); + res = init(*W); + } + return res; +} + +int NCursesWindow::ripoffline(int ripoff_lines, + int (*init)(NCursesWindow& win)) { + int code = ::_nc_ripoffline(ripoff_lines,ripoff_init); + if (code==OK && init && ripoff_lines) { + R_INIT[r_init_idx++] = init; + } + return code; +} + +bool +NCursesWindow::isDescendant(NCursesWindow& win) { + for (NCursesWindow* p = subwins; p != NULL; p = p->sib) { + if (p==&win) + return TRUE; + else { + if (p->isDescendant(win)) + return TRUE; + } + } + return FALSE; +} + +void +NCursesWindow::kill_subwindows() +{ + for (NCursesWindow* p = subwins; p != 0; p = p->sib) { + p->kill_subwindows(); + if (p->alloced) { + if (p->w != 0) + ::delwin(p->w); + p->alloced = FALSE; + } + p->w = 0; // cause a run-time error if anyone attempts to use... + } +} + + +NCursesWindow::~NCursesWindow() +{ + kill_subwindows(); + + if (par != 0) { // Snip us from the parent's list of subwindows. + NCursesWindow * win = par->subwins; + NCursesWindow * trail = 0; + for (;;) { + if (win == 0) + break; + else if (win == this) { + if (trail != 0) + trail->sib = win->sib; + else + par->subwins = win->sib; + break; + } else { + trail = win; + win = win->sib; + } + } + } + + if (alloced && w != 0) + delwin(w); + + if (alloced) { + --count; + if (count == 0) { + ::endwin(); + } + else if (count < 0) { // cannot happen! + err_handler("Too many windows destroyed"); + } + } +} + +// --------------------------------------------------------------------- +// Color stuff +// +int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED; + +void +NCursesWindow::useColors(void) +{ + if (colorInitialized == COLORS_NOT_INITIALIZED) { + if (b_initialized) { + if (::has_colors()) { + ::start_color(); + colorInitialized = COLORS_ARE_REALLY_THERE; + } + else + colorInitialized = COLORS_MONOCHROME; + } + else + colorInitialized = COLORS_NEED_INITIALIZATION; + } +} + +short +NCursesWindow::getcolor(int getback) const +{ + short fore, back; + + if (colorInitialized==COLORS_ARE_REALLY_THERE) { + if (pair_content((short)PAIR_NUMBER(w->_attrs), &fore, &back)) + err_handler("Can't get color pair"); + } + else { + // Monochrome means white on black + back = COLOR_BLACK; + fore = COLOR_WHITE; + } + return getback ? back : fore; +} + +int NCursesWindow::NumberOfColors() +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return COLORS; + else + return 1; // monochrome (actually there are two ;-) +} + +short +NCursesWindow::getcolor() const +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return PAIR_NUMBER(w->_attrs); + else + return 0; // we only have pair zero +} + +int +NCursesWindow::setpalette(short fore, short back, short pair) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return init_pair(pair, fore, back); + else + return OK; +} + +int +NCursesWindow::setpalette(short fore, short back) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) + return setpalette(fore, back, (short)PAIR_NUMBER(w->_attrs)); + else + return OK; +} + + +int +NCursesWindow::setcolor(short pair) +{ + if (colorInitialized==COLORS_ARE_REALLY_THERE) { + if ((pair < 1) || (pair > COLOR_PAIRS)) + err_handler("Can't set color pair"); + + attroff(A_COLOR); + attrset(COLOR_PAIR(pair)); + } + return OK; +} + +#if HAVE_HAS_KEY +extern "C" int _nc_has_mouse(void); + +bool NCursesWindow::has_mouse() const { + return ((::has_key(KEY_MOUSE) || ::_nc_has_mouse()) + ? TRUE : FALSE); +} +#endif diff --git a/ncurses-5.2/c++/cursesw.h b/ncurses-5.2/c++/cursesw.h new file mode 100644 index 0000000..2a68d5a --- /dev/null +++ b/ncurses-5.2/c++/cursesw.h @@ -0,0 +1,1375 @@ +// * This makes emacs happy -*-Mode: C++;-*- +#ifndef _CURSESW_H +#define _CURSESW_H + +// $Id$ + +#include +#include +#include +#ifdef __MWERKS__ +/* This is a bogus check, stringstream is actually ANSI C++ standard, + * but old compilers like GCC don't have it, and new compilers like Metrowerks + * don't have strstream + */ +#include +#else +#include +#endif + +extern "C" { +# include +} + +/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro. + Undefine it here, because NCursesWindow uses lines as a method. */ +#undef lines + +/* "Convert" macros to inlines. We'll define it as another symbol to avoid + * conflict with library symbols. + */ +#undef UNDEF +#define UNDEF(name) CUR_ ##name + +#ifdef addch +inline int UNDEF(addch)(chtype ch) { return addch(ch); } +#undef addch +#define addch UNDEF(addch) +#endif + +#ifdef echochar +inline int UNDEF(echochar)(chtype ch) { return echochar(ch); } +#undef echochar +#define echochar UNDEF(echochar) +#endif + +#ifdef insdelln +inline int UNDEF(insdelln)(int n) { return insdelln(n); } +#undef insdelln +#define insdelln UNDEF(insdelln) +#endif + +#ifdef addstr +/* The (char*) cast is to hack around missing const's */ +inline int UNDEF(addstr)(const char * str) { return addstr((char*)str); } +#undef addstr +#define addstr UNDEF(addstr) +#endif + +#ifdef attron +inline int UNDEF(attron)(chtype at) { return attron(at); } +#undef attron +#define attron UNDEF(attron) +#endif + +#ifdef attroff +inline int UNDEF(attroff)(chtype at) { return attroff(at); } +#undef attroff +#define attroff UNDEF(attroff) +#endif + +#ifdef attrset +inline chtype UNDEF(attrset)(chtype at) { return attrset(at); } +#undef attrset +#define attrset UNDEF(attrset) +#endif + +#ifdef color_set +inline chtype UNDEF(color_set)(short p,void* opts) { return color_set(p,opts); } +#undef color_set +#define color_set UNDEF(color_set) +#endif + +#ifdef border +inline int UNDEF(border)(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br) +{ return border(ls,rs,ts,bs,tl,tr,bl,br); } +#undef border +#define border UNDEF(border) +#endif + +#ifdef box +inline int UNDEF(box)(WINDOW *win, int v, int h) { return box(win, v, h); } +#undef box +#define box UNDEF(box) +#endif + +#ifdef mvwhline +inline int UNDEF(mvwhline)(WINDOW *win,int y,int x,chtype c,int n) { + return mvwhline(win,y,x,c,n); } +#undef mvwhline +#define mvwhline UNDEF(mvwhline) +#endif + +#ifdef mvwvline +inline int UNDEF(mvwvline)(WINDOW *win,int y,int x,chtype c,int n) { + return mvwvline(win,y,x,c,n); } +#undef mvwvline +#define mvwvline UNDEF(mvwvline) +#endif + +#ifdef clear +inline int UNDEF(clear)() { return clear(); } +#undef clear +#define clear UNDEF(clear) +#endif + +#ifdef clearok +inline int UNDEF(clearok)(WINDOW* win, bool bf) { return clearok(win, bf); } +#undef clearok +#define clearok UNDEF(clearok) +#else +extern "C" int clearok(WINDOW*, bool); +#endif + +#ifdef clrtobot +inline int UNDEF(clrtobot)() { return clrtobot(); } +#undef clrtobot +#define clrtobot UNDEF(clrtobot) +#endif + +#ifdef clrtoeol +inline int UNDEF(clrtoeol)() { return clrtoeol(); } +#undef clrtoeol +#define clrtoeol UNDEF(clrtoeol) +#endif + +#ifdef delch +inline int UNDEF(delch)() { return delch(); } +#undef delch +#define delch UNDEF(delch) +#endif + +#ifdef deleteln +inline int UNDEF(deleteln)() { return deleteln(); } +#undef deleteln +#define deleteln UNDEF(deleteln) +#endif + +#ifdef erase +inline int UNDEF(erase)() { return erase(); } +#undef erase +#define erase UNDEF(erase) +#endif + +#ifdef flushok +inline int UNDEF(flushok)(WINDOW* _win, bool _bf) { + return flushok(_win, _bf); } +#undef flushok +#define flushok UNDEF(flushok) +#else +#define _no_flushok +#endif + +#ifdef getch +inline int UNDEF(getch)() { return getch(); } +#undef getch +#define getch UNDEF(getch) +#endif + +#ifdef getstr +inline int UNDEF(getstr)(char *_str) { return getstr(_str); } +#undef getstr +#define getstr UNDEF(getstr) +#endif + +#ifdef instr +inline int UNDEF(instr)(char *_str) { return instr(_str); } +#undef instr +#define instr UNDEF(instr) +#endif + +#ifdef innstr +inline int UNDEF(innstr)(char *_str, int n) { return innstr(_str,n); } +#undef innstr +#define innstr UNDEF(innstr) +#endif + +#ifdef mvwinnstr +inline int UNDEF(mvwinnstr)(WINDOW *win, int y, int x, char *_str, int n) { + return mvwinnstr(win,y,x,_str,n); } +#undef mvwinnstr +#define mvwinnstr UNDEF(mvwinnstr) +#endif + +#ifdef mvinnstr +inline int UNDEF(mvinnstr)(int y, int x, char *_str, int n) { + return mvinnstr(y,x,_str,n); } +#undef mvinnstr +#define mvinnstr UNDEF(mvinnstr) +#endif + +#ifdef winsstr +inline int UNDEF(winsstr)(WINDOW *w, const char *_str) { + return winsstr(w,_str); } +#undef winsstr +#define winsstr UNDEF(winsstr) +#endif + +#ifdef mvwinsstr +inline int UNDEF(mvwinsstr)(WINDOW *w, int y, int x, const char *_str) { + return mvwinsstr(w,y,x,_str); } +#undef mvwinsstr +#define mvwinsstr UNDEF(mvwinsstr) +#endif + +#ifdef insstr +inline int UNDEF(insstr)(const char *_str) { + return insstr(_str); } +#undef insstr +#define insstr UNDEF(insstr) +#endif + +#ifdef mvinsstr +inline int UNDEF(mvinsstr)(int y, int x,const char *_str) { + return mvinsstr(y,x,_str); } +#undef mvinsstr +#define mvinsstr UNDEF(mvinsstr) +#endif + +#ifdef insnstr +inline int UNDEF(insnstr)(const char *_str, int n) { + return insnstr(_str,n); } +#undef insnstr +#define insnstr UNDEF(insnstr) +#endif + +#ifdef mvwinsnstr +inline int UNDEF(mvwinsnstr)(WINDOW *w, int y, int x,const char *_str, int n) { + return mvwinsnstr(w,y,x,_str,n); } +#undef mvwinsnstr +#define mvwinsnstr UNDEF(mvwinsnstr) +#endif + +#ifdef mvinsnstr +inline int UNDEF(mvinsnstr)(int y, int x,const char *_str, int n) { + return mvinsnstr(y,x,_str,n); } +#undef mvinsnstr +#define mvinsnstr UNDEF(mvinsnstr) +#endif + +#ifdef getnstr +inline int UNDEF(getnstr)(char *_str, int n) { return getnstr(_str,n); } +#undef getnstr +#define getnstr UNDEF(getnstr) +#endif + +#ifdef getyx +inline void UNDEF(getyx)(const WINDOW* win, int& y, int& x) { + getyx(win, y, x); } +#undef getyx +#define getyx UNDEF(getyx) +#endif + +#ifdef getbegyx +inline void UNDEF(getbegyx)(WINDOW* win, int& y, int& x) { getbegyx(win, y, x); } +#undef getbegyx +#define getbegyx UNDEF(getbegyx) +#endif + +#ifdef getmaxyx +inline void UNDEF(getmaxyx)(WINDOW* win, int& y, int& x) { getmaxyx(win, y, x); } +#undef getmaxyx +#define getmaxyx UNDEF(getmaxyx) +#endif + +#ifdef hline +inline int UNDEF(hline)(chtype ch, int n) { return hline(ch, n); } +#undef hline +#define hline UNDEF(hline) +#endif + +#ifdef inch +inline chtype UNDEF(inch)() { return inch(); } +#undef inch +#define inch UNDEF(inch) +#endif + +#ifdef insch +inline int UNDEF(insch)(char c) { return insch(c); } +#undef insch +#define insch UNDEF(insch) +#endif + +#ifdef insertln +inline int UNDEF(insertln)() { return insertln(); } +#undef insertln +#define insertln UNDEF(insertln) +#endif + +#ifdef leaveok +inline int UNDEF(leaveok)(WINDOW* win, bool bf) { return leaveok(win, bf); } +#undef leaveok +#define leaveok UNDEF(leaveok) +#else +extern "C" int leaveok(WINDOW* win, bool bf); +#endif + +#ifdef move +inline int UNDEF(move)(int x, int y) { return move(x, y); } +#undef move +#define move UNDEF(move) +#endif + +#ifdef refresh +inline int UNDEF(refresh)() { return refresh(); } +#undef refresh +#define refresh UNDEF(refresh) +#endif + +#ifdef redrawwin +inline int UNDEF(redrawwin)(WINDOW *win) { return redrawwin(win); } +#undef redrawwin +#define redrawwin UNDEF(redrawwin) +#endif + +#ifdef scrl +inline int UNDEF(scrl)(int l) { return scrl(l); } +#undef scrl +#define scrl UNDEF(scrl) +#endif + +#ifdef scroll +inline int UNDEF(scroll)(WINDOW *win) { return scroll(win); } +#undef scroll +#define scroll UNDEF(scroll) +#endif + +#ifdef scrollok +inline int UNDEF(scrollok)(WINDOW* win, bool bf) { return scrollok(win, bf); } +#undef scrollok +#define scrollok UNDEF(scrollok) +#else +#if defined(__NCURSES_H) +extern "C" int scrollok(WINDOW*, bool); +#else +extern "C" int scrollok(WINDOW*, char); +#endif +#endif + +#ifdef setscrreg +inline int UNDEF(setscrreg)(int t, int b) { return setscrreg(t, b); } +#undef setscrreg +#define setscrreg UNDEF(setscrreg) +#endif + +#ifdef standend +inline int UNDEF(standend)() { return standend(); } +#undef standend +#define standend UNDEF(standend) +#endif + +#ifdef standout +inline int UNDEF(standout)() { return standout(); } +#undef standout +#define standout UNDEF(standout) +#endif + +#ifdef subpad +inline WINDOW *UNDEF(subpad)(WINDOW *p, int l, int c, int y, int x) +{ return derwin(p,l,c,y,x); } +#undef subpad +#define subpad UNDEF(subpad) +#endif + +#ifdef timeout +inline void UNDEF(timeout)(int delay) { timeout(delay); } +#undef timeout +#define timeout UNDEF(timeout) +#endif + +#ifdef touchline +inline int UNDEF(touchline)(WINDOW *win, int s, int c) +{ return touchline(win,s,c); } +#undef touchline +#define touchline UNDEF(touchline) +#endif + +#ifdef touchwin +inline int UNDEF(touchwin)(WINDOW *win) { return touchwin(win); } +#undef touchwin +#define touchwin UNDEF(touchwin) +#endif + +#ifdef untouchwin +inline int UNDEF(untouchwin)(WINDOW *win) { return untouchwin(win); } +#undef untouchwin +#define untouchwin UNDEF(untouchwin) +#endif + +#ifdef vline +inline int UNDEF(vline)(chtype ch, int n) { return vline(ch, n); } +#undef vline +#define vline UNDEF(vline) +#endif + +#ifdef waddstr +inline int UNDEF(waddstr)(WINDOW *win, char *str) { return waddstr(win, str); } +#undef waddstr +#define waddstr UNDEF(waddstr) +#endif + +#ifdef waddchstr +inline int UNDEF(waddchstr)(WINDOW *win, chtype *at) { return waddchstr(win, at); } +#undef waddchstr +#define waddchstr UNDEF(waddchstr) +#endif + +#ifdef wstandend +inline int UNDEF(wstandend)(WINDOW *win) { return wstandend(win); } +#undef wstandend +#define wstandend UNDEF(wstandend) +#endif + +#ifdef wstandout +inline int UNDEF(wstandout)(WINDOW *win) { return wstandout(win); } +#undef wstandout +#define wstandout UNDEF(wstandout) +#endif + + +#ifdef wattroff +inline int UNDEF(wattroff)(WINDOW *win, int att) { return wattroff(win, att); } +#undef wattroff +#define wattroff UNDEF(wattroff) +#endif + +#ifdef chgat +inline int UNDEF(chgat)(int n,attr_t attr, short color, const void *opts) { + return chgat(n,attr,color,opts); } +#undef chgat +#define chgat UNDEF(chgat) +#endif + +#ifdef mvchgat +inline int UNDEF(mvchgat)(int y, int x, int n, + attr_t attr, short color, const void *opts) { + return mvchgat(y,x,n,attr,color,opts); } +#undef mvchgat +#define mvchgat UNDEF(mvchgat) +#endif + +#ifdef mvwchgat +inline int UNDEF(mvwchgat)(WINDOW *win, int y, int x, int n, + attr_t attr, short color, const void *opts) { + return mvwchgat(win,y,x,n,attr,color,opts); } +#undef mvwchgat +#define mvwchgat UNDEF(mvwchgat) +#endif + +#ifdef wattrset +inline int UNDEF(wattrset)(WINDOW *win, int att) { return wattrset(win, att); } +#undef wattrset +#define wattrset UNDEF(wattrset) +#endif + +#ifdef winch +inline chtype UNDEF(winch)(const WINDOW* win) { return winch(win); } +#undef winch +#define winch UNDEF(winch) +#endif + +#ifdef mvwaddch +inline int UNDEF(mvwaddch)(WINDOW *win, int y, int x, const chtype ch) +{ return mvwaddch(win, y, x, ch); } +#undef mvwaddch +#define mvwaddch UNDEF(mvwaddch) +#endif + +#ifdef mvwaddchnstr +inline int UNDEF(mvwaddchnstr)(WINDOW *win, int y, int x, chtype *str, int n) +{ return mvwaddchnstr(win, y, x, str, n); } +#undef mvwaddchnstr +#define mvwaddchnstr UNDEF(mvwaddchnstr) +#endif + +#ifdef mvwaddchstr +inline int UNDEF(mvwaddchstr)(WINDOW *win, int y, int x, chtype *str) +{ return mvwaddchstr(win, y, x, str); } +#undef mvwaddchstr +#define mvwaddchstr UNDEF(mvwaddchstr) +#endif + +#ifdef addnstr +inline int UNDEF(addnstr)(const char *str, int n) +{ return addnstr((char*)str, n); } +#undef addnstr +#define addnstr UNDEF(addnstr) +#endif + +#ifdef mvwaddnstr +inline int UNDEF(mvwaddnstr)(WINDOW *win, int y, int x, const char *str, int n) +{ return mvwaddnstr(win, y, x, (char*)str, n); } +#undef mvwaddnstr +#define mvwaddnstr UNDEF(mvwaddnstr) +#endif + +#ifdef mvwaddstr +inline int UNDEF(mvwaddstr)(WINDOW *win, int y, int x, const char * str) +{ return mvwaddstr(win, y, x, (char*)str); } +#undef mvwaddstr +#define mvwaddstr UNDEF(mvwaddstr) +#endif + +#ifdef mvwdelch +inline int UNDEF(mvwdelch)(WINDOW *win, int y, int x) +{ return mvwdelch(win, y, x); } +#undef mvwdelch +#define mvwdelch UNDEF(mvwdelch) +#endif + +#ifdef mvwgetch +inline int UNDEF(mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);} +#undef mvwgetch +#define mvwgetch UNDEF(mvwgetch) +#endif + +#ifdef mvwgetstr +inline int UNDEF(mvwgetstr)(WINDOW *win, int y, int x, char *str) +{return mvwgetstr(win,y,x, str);} +#undef mvwgetstr +#define mvwgetstr UNDEF(mvwgetstr) +#endif + +#ifdef mvwgetnstr +inline int UNDEF(mvwgetnstr)(WINDOW *win, int y, int x, char *str, int n) +{return mvwgetnstr(win,y,x, str,n);} +#undef mvwgetnstr +#define mvwgetnstr UNDEF(mvwgetnstr) +#endif + +#ifdef mvwinch +inline chtype UNDEF(mvwinch)(WINDOW *win, int y, int x) { + return mvwinch(win, y, x);} +#undef mvwinch +#define mvwinch UNDEF(mvwinch) +#endif + +#ifdef mvwinsch +inline int UNDEF(mvwinsch)(WINDOW *win, int y, int x, char c) +{ return mvwinsch(win, y, x, c); } +#undef mvwinsch +#define mvwinsch UNDEF(mvwinsch) +#endif + +#ifdef mvaddch +inline int UNDEF(mvaddch)(int y, int x, chtype ch) +{ return mvaddch(y, x, ch); } +#undef mvaddch +#define mvaddch UNDEF(mvaddch) +#endif + +#ifdef mvaddnstr +inline int UNDEF(mvaddnstr)(int y, int x, const char *str, int n) +{ return mvaddnstr(y, x, (char*)str, n); } +#undef mvaddnstr +#define mvaddnstr UNDEF(mvaddnstr) +#endif + +#ifdef mvaddstr +inline int UNDEF(mvaddstr)(int y, int x, const char * str) +{ return mvaddstr(y, x, (char*)str); } +#undef mvaddstr +#define mvaddstr UNDEF(mvaddstr) +#endif + +#ifdef mvdelch +inline int UNDEF(mvdelch)(int y, int x) { return mvdelch(y, x);} +#undef mvdelch +#define mvdelch UNDEF(mvdelch) +#endif + +#ifdef mvgetch +inline int UNDEF(mvgetch)(int y, int x) { return mvgetch(y, x);} +#undef mvgetch +#define mvgetch UNDEF(mvgetch) +#endif + +#ifdef mvgetstr +inline int UNDEF(mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);} +#undef mvgetstr +#define mvgetstr UNDEF(mvgetstr) +#endif + +#ifdef mvgetnstr +inline int UNDEF(mvgetnstr)(int y, int x, char *str, int n) { + return mvgetnstr(y, x, str,n);} +#undef mvgetnstr +#define mvgetnstr UNDEF(mvgetnstr) +#endif + +#ifdef mvinch +inline chtype UNDEF(mvinch)(int y, int x) { return mvinch(y, x);} +#undef mvinch +#define mvinch UNDEF(mvinch) +#endif + +#ifdef mvinsch +inline int UNDEF(mvinsch)(int y, int x, char c) +{ return mvinsch(y, x, c); } +#undef mvinsch +#define mvinsch UNDEF(mvinsch) +#endif + +#ifdef napms +inline void UNDEF(napms)(unsigned long x) { napms(x); } +#undef napms +#define napms UNDEF(napms) +#endif + +#ifdef fixterm +inline int UNDEF(fixterm)(void) { return fixterm(); } +#undef fixterm +#define fixterm UNDEF(fixterm) +#endif + +#ifdef resetterm +inline int UNDEF(resetterm)(void) { return resetterm(); } +#undef resetterm +#define resetterm UNDEF(resetterm) +#endif + +#ifdef saveterm +inline int UNDEF(saveterm)(void) { return saveterm(); } +#undef saveterm +#define saveterm UNDEF(saveterm) +#endif + +#ifdef crmode +inline int UNDEF(crmode)(void) { return crmode(); } +#undef crmode +#define crmode UNDEF(crmode) +#endif + +#ifdef nocrmode +inline int UNDEF(nocrmode)(void) { return nocrmode(); } +#undef nocrmode +#define nocrmode UNDEF(nocrmode) +#endif + +#ifdef getbkgd +inline chtype UNDEF(getbkgd)(const WINDOW *win) { return getbkgd(win); } +#undef getbkgd +#define getbkgd UNDEF(getbkgd) +#endif + +#ifdef bkgd +inline int UNDEF(bkgd)(chtype ch) { return bkgd(ch); } +#undef bkgd +#define bkgd UNDEF(bkgd) +#endif + +#ifdef bkgdset +inline void UNDEF(bkgdset)(chtype ch) { bkgdset(ch); } +#undef bkgdset +#define bkgdset UNDEF(bkgdset) +#endif + +/* + * + * C++ class for windows. + * + * + */ + +class NCursesWindow +{ + friend class NCursesMenu; + friend class NCursesForm; + +private: + static bool b_initialized; + static void initialize(); + static int ripoff_init(WINDOW *,int); + + void init(); + + short getcolor(int getback) const; + + static int setpalette(short fore, short back, short pair); + static int colorInitialized; + + // This private constructor is only used during the initialization + // of windows generated by ripoffline() calls. + NCursesWindow(WINDOW* win, int cols); + +protected: + void err_handler(const char *) const THROWS(NCursesException); + // Signal an error with the given message text. + + static long count; // count of all active windows: + // We rely on the c++ promise that + // all otherwise uninitialized + // static class vars are set to 0 + + WINDOW* w; // the curses WINDOW + + bool alloced; // TRUE if we own the WINDOW + + NCursesWindow* par; // parent, if subwindow + NCursesWindow* subwins; // head of subwindows list + NCursesWindow* sib; // next subwindow of parent + + void kill_subwindows(); // disable all subwindows + // Destroy all subwindows. + + /* Only for use by derived classes. They are then in charge to + fill the member variables correctly. */ + NCursesWindow(); + +public: + NCursesWindow(WINDOW* &window); // useful only for stdscr + + NCursesWindow(int lines, // number of lines + int cols, // number of columns + int begin_y, // line origin + int begin_x); // col origin + + NCursesWindow(NCursesWindow& par,// parent window + int lines, // number of lines + int cols, // number of columns + int begin_y, // absolute or relative + int begin_x, // origins: + char absrel = 'a');// if `a', by & bx are + // absolute screen pos, else if `r', they are relative to par origin + + NCursesWindow(NCursesWindow& par,// parent window + bool do_box = TRUE); + // this is the very common case that we want to create the subwindow that + // is two lines and two columns smaller and begins at (1,1). + // We may automatically request the box around it. + + virtual ~NCursesWindow(); + + NCursesWindow Clone(); + // Make an exact copy of the window. + + // Initialization. + static void useColors(void); + // Call this routine very early if you want to have colors. + + static int ripoffline(int ripoff_lines, + int (*init)(NCursesWindow& win)); + // This function is used to generate a window of ripped-of lines. + // If the argument is positive, lines are removed from the top, if it + // is negative lines are removed from the bottom. This enhances the + // lowlevel ripoffline() function because it uses the internal + // implementation that allows to remove more than just a single line. + // This function must be called before any other ncurses function. The + // creation of the window is defered until ncurses gets initialized. + // The initialization function is then called. + + // ------------------------------------------------------------------------- + // terminal status + // ------------------------------------------------------------------------- + int lines() const { return LINES; } + // Number of lines on terminal, *not* window + + int cols() const { return COLS; } + // Number of cols on terminal, *not* window + + int tabsize() const { return TABSIZE; } + // Size of a tab on terminal, *not* window + + static int NumberOfColors(); + // Number of available colors + + int colors() const { return NumberOfColors(); } + // Number of available colors + + // ------------------------------------------------------------------------- + // window status + // ------------------------------------------------------------------------- + int height() const { return maxy() + 1; } + // Number of lines in this window + + int width() const { return maxx() + 1; } + // Number of columns in this window + + int begx() const { return w->_begx; } + // Column of top left corner relative to stdscr + + int begy() const { return w->_begy; } + // Line of top left corner relative to stdscr + + int maxx() const { return w->_maxx; } + // Largest x coord in window + + int maxy() const { return w->_maxy; } + // Largest y coord in window + + short getcolor() const; + // Actual color pair + + short foreground() const { return getcolor(0); } + // Actual foreground color + + short background() const { return getcolor(1); } + // Actual background color + + int setpalette(short fore, short back); + // Set color palette entry + + int setcolor(short pair); + // Set actually used palette entry + + // ------------------------------------------------------------------------- + // window positioning + // ------------------------------------------------------------------------- + virtual int mvwin(int begin_y, int begin_x) { + return ::mvwin(w,begin_y,begin_x); } + // Move window to new position with the new position as top left corner. + // This is virtual because it is redefined in NCursesPanel. + + // ------------------------------------------------------------------------- + // coordinate positioning + // ------------------------------------------------------------------------- + int move(int y, int x) { return ::wmove(w, y, x); } + // Move cursor the this position + + void getyx(int& y, int& x) const { ::getyx(w, y, x); } + // Get current position of the cursor + + int mvcur(int oldrow, int oldcol, int newrow, int newcol) const { + return ::mvcur(oldrow, oldcol, newrow, newcol); } + // Perform lowlevel cursor motion that takes effect immediately. + + // ------------------------------------------------------------------------- + // input + // ------------------------------------------------------------------------- + int getch() { return ::wgetch(w); } + // Get a keystroke from the window. + + int getch(int y, int x) { return ::mvwgetch(w,y,x); } + // Move cursor to position and get a keystroke from the window + + int getstr(char* str, int n=-1) { + return ::wgetnstr(w, str,n); } + // Read a series of characters into str until a newline or carriage return + // is received. Read at most n characters. If n is negative, the limit is + // ignored. + + int getstr(int y, int x, char* str, int n=-1) { + return ::mvwgetnstr(w,y,x,str,n); } + // Move the cursor to the requested position and then perform the getstr() + // as described above. + + int instr(char *s, int n=-1) { return ::winnstr(w,s,n); } + // Get a string of characters from the window into the buffer s. Retrieve + // at most n characters, if n is negative retrieve all characters up to the + // end of the current line. Attributes are stripped from the characters. + + int instr(int y, int x, char *s, int n=-1) { + return ::mvwinnstr(w,y,x,s,n); } + // Move the cursor to the requested position and then perform the instr() + // as described above. + + int scanw(const char* fmt, ...) + // Perform a scanw function from the window. This only works if you're + // using the GNU C++ compiler. +#if __GNUG__ >= 2 + __attribute__ ((format (scanf, 2, 3))); +#else + ; +#endif + + int scanw(int y, int x, const char* fmt, ...) + // Move the cursor to the requested position and then perform a scanw + // from the window. This nly works if you're using the GNU C++ compiler. +#if __GNUG__ >= 2 + __attribute__ ((format (scanf, 4, 5))); +#else + ; +#endif + + // ------------------------------------------------------------------------- + // output + // ------------------------------------------------------------------------- + int addch(const chtype ch) { return ::waddch(w, ch); } + // Put attributed character to the window. + + int addch(int y, int x, const chtype ch) { + return ::mvwaddch(w,y,x,ch); } + // Move cursor to the requested position and then put attributed character + // to the window. + + int echochar(const chtype ch) { return ::wechochar(w,ch); } + // Put attributed character to the window and refresh it immediately. + + int addstr(const char* str, int n=-1) { + return ::waddnstr(w, (char*)str,n); } + // Write the string str to the window, stop writing if the terminating + // NUL or the limit n is reached. If n is negative, it is ignored. + + int addstr(int y, int x, const char * str, int n=-1) { + return ::mvwaddnstr(w,y,x,(char*)str,n); } + // Move the cursor to the requested position and then perform the addstr + // as described above. + + int printw(const char* fmt, ...) + // Do a formatted print to the window. +#if __GNUG__ >= 2 + __attribute__ ((format (printf, 2, 3))); +#else + ; +#endif + + int printw(int y, int x, const char * fmt, ...) + // Move the cursor and then do a formatted print to the window. +#if __GNUG__ >= 2 + __attribute__ ((format (printf, 4, 5))); +#else + ; +#endif + + chtype inch() const { return ::winch(w); } + // Retrieve attributed character under the current cursor position. + + chtype inch(int y, int x) { return ::mvwinch(w,y,x); } + // Move cursor to requested position and then retrieve attributed character + // at this position. + + int insch(chtype ch) { return ::winsch(w, ch); } + // Insert attributed character into the window before current cursor + // position. + + int insch(int y, int x, chtype ch) { + return ::mvwinsch(w,y,x,(char)ch); } + // Move cursor to requested position and then insert the attributed + // character before that position. + + int insertln() { return ::winsdelln(w,1); } + // Insert an empty line above the current line. + + int insdelln(int n=1) { return ::winsdelln(w,n); } + // If n>0 insert that many lines above the current line. If n<0 delete + // that many lines beginning with the current line. + + int insstr(const char *s, int n=-1) { + return ::winsnstr(w,s,n); } + // Insert the string into the window before the current cursor position. + // Insert stops at end of string or when the limit n is reached. If n is + // negative, it is ignored. + + int insstr(int y, int x, const char *s, int n=-1) { + return ::mvwinsnstr(w,y,x,s,n); } + // Move the cursor to the requested position and then perform the insstr() + // as described above. + + int attron (chtype at) { return ::wattron (w, at); } + // Switch on the window attributes; + + int attroff(chtype at) { return ::wattroff(w, (int) at); } + // Switch off the window attributes; + + int attrset(chtype at) { return ::wattrset(w, (int) at); } + // Set the window attributes; + + int color_set(short color_pair_number, void* opts=NULL) { + return ::wcolor_set(w, color_pair_number, opts); } + // Set the window color attribute; + + int chgat(int n,attr_t attr, short color, const void *opts=NULL) { + return ::wchgat(w,n,attr,color,opts); } + // Change the attributes of the next n characters in the current line. If + // n is negative or greater than the number of remaining characters in the + // line, the attributes will be changed up to the end of the line. + + int chgat(int y, int x, + int n,attr_t attr, short color, const void *opts=NULL) { + return ::mvwchgat(w,y,x,n,attr,color,opts); } + // Move the cursor to the requested position and then perform chgat() as + // described above. + + // ------------------------------------------------------------------------- + // background + // ------------------------------------------------------------------------- + chtype getbkgd() const { return ::getbkgd(w); } + // Get current background setting. + + int bkgd(const chtype ch) { return ::wbkgd(w,ch); } + // Set the background property and apply it to the window. + + void bkgdset(chtype ch) { ::wbkgdset(w,ch); } + // Set the background property. + + // ------------------------------------------------------------------------- + // borders + // ------------------------------------------------------------------------- + int box(chtype vert=0, chtype hor=0) { + return ::wborder(w, vert, vert, hor, hor, 0, 0 ,0, 0); } + // Draw a box around the window with the given vertical and horizontal + // drawing characters. If you specifiy a zero as character, curses will try + // to find a "nice" character. + + int border(chtype left=0, chtype right=0, + chtype top =0, chtype bottom=0, + chtype top_left =0, chtype top_right=0, + chtype bottom_left =0, chtype bottom_right=0) { + return ::wborder(w,left,right,top,bottom,top_left,top_right, + bottom_left,bottom_right); } + // Draw a border around the window with the given characters for the + // various parts of the border. If you pass zero for a character, curses + // will try to find "nice" characters. + + // ------------------------------------------------------------------------- + // lines and boxes + // ------------------------------------------------------------------------- + int hline(int len, chtype ch=0) { return ::whline(w, ch, len); } + // Draw a horizontal line of len characters with the given character. If + // you pass zero for the character, curses will try to find a "nice" one. + + int hline(int y, int x, int len, chtype ch=0) { + return ::mvwhline(w,y,x,ch,len); } + // Move the cursor to the requested position and then draw a horizontal line. + + int vline(int len, chtype ch=0) { return ::wvline(w, ch, len); } + // Draw a vertical line of len characters with the given character. If + // you pass zero for the character, curses will try to find a "nice" one. + + int vline(int y, int x, int len, chtype ch=0) { + return ::mvwvline(w,y,x,ch,len); } + // Move the cursor to the requested position and then draw a vertical line. + + // ------------------------------------------------------------------------- + // erasure + // ------------------------------------------------------------------------- + int erase() { return ::werase(w); } + // Erase the window. + + int clear() { return ::wclear(w); } + // Clear the window. + + int clearok(bool bf) { return ::clearok(w, bf); } + // Set/Reset the clear flag. If set, the next refresh() will clear the + // screen. + + int clrtobot() { return ::wclrtobot(w); } + // Clear to the end of the window. + + int clrtoeol() { return ::wclrtoeol(w); } + // Clear to the end of the line. + + int delch() { return ::wdelch(w); } + // Delete character under the cursor. + + int delch(int y, int x) { return ::mvwdelch(w,y,x); } + // Move cursor to requested position and delete the character under the + // cursor. + + int deleteln() { return ::winsdelln(w,-1); } + // Delete the current line. + + // ------------------------------------------------------------------------- + // screen control + // ------------------------------------------------------------------------- + int scroll(int amount=1) { return ::wscrl(w,amount); } + // Scroll amount lines. If amount is positive, scroll up, otherwise + // scroll down. + + int scrollok(bool bf) { return ::scrollok(w, bf); } + // If bf is TRUE, window scrolls if cursor is moved off the bottom + // edge of the window or a scrolling region, otherwise the cursor is left + // at the bottom line. + + int setscrreg(int from, int to) { + return ::wsetscrreg(w,from,to); } + // Define a soft scrolling region. + + int idlok(bool bf) { return ::idlok(w, bf); } + // If bf is TRUE, use insert/delete line hardware support if possible. + // Otherwise do it in software. + + + void idcok(bool bf) { ::idcok(w, bf); } + // If bf is TRUE, use insert/delete character hardware support if possible. + // Otherwise do it in software. + + int touchwin() { return ::wtouchln(w,0,height(),1); } + // Mark the whole window as modified. + + int untouchwin() { return ::wtouchln(w,0,height(),0); } + // Mark the whole window as unmodified. + + int touchln(int s, int cnt, bool changed=TRUE) { + return ::wtouchln(w,s,cnt,(int)(changed?1:0)); } + // Mark cnt lines beginning from line s as changed or unchanged, depending + // on the value of the changed flag. + + bool is_linetouched(int line) const { + return (::is_linetouched(w,line) ? TRUE:FALSE); } + // Return TRUE if line is marked as changed, FALSE otherwise + + bool is_wintouched() const { + return (::is_wintouched(w) ? TRUE:FALSE); } + // Return TRUE if window is marked as changed, FALSE otherwise + + int leaveok(bool bf) { return ::leaveok(w, bf); } + // If bf is TRUE, curses will leave the cursor after an update whereever + // it is after the update. + + int redrawln(int from, int n) { return ::wredrawln(w,from,n); } + // Redraw n lines starting from the requested line + + int redrawwin() { return ::wredrawln(w,0,height()); } + // Redraw the whole window + + int doupdate() { return ::doupdate(); } + // Do all outputs to make the physical screen looking like the virtual one + + void syncdown() { ::wsyncdown(w); } + // Propagate the changes down to all descendant windows + + void syncup() { ::wsyncup(w); } + // Propagate the changes up in the hierarchy + + void cursyncup() { ::wcursyncup(w); } + // Position the cursor in all ancestor windows corresponding to our setting + + int syncok(bool bf) { return ::syncok(w,bf); } + // If called with bf=TRUE, syncup() is called whenever the window is changed + +#ifndef _no_flushok + int flushok(bool bf) { return ::flushok(w, bf); } +#endif + + void immedok(bool bf) { ::immedok(w,bf); } + // If called with bf=TRUE, any change in the window will cause an + // automatic immediate refresh() + + int keypad(bool bf) { return ::keypad(w, bf); } + // If called with bf=TRUE, the application will interpret function keys. + + int meta(bool bf) { return ::meta(w,bf); } + // If called with bf=TRUE, keys may generate 8-Bit characters. Otherwise + // 7-Bit characters are generated. + + int standout() { return ::wstandout(w); } + // Enable "standout" attributes + + int standend() { return ::wstandend(w); } + // Disable "standout" attributes + + // ------------------------------------------------------------------------- + // The next two are virtual, because we redefine them in the + // NCursesPanel class. + // ------------------------------------------------------------------------- + virtual int refresh() { return ::wrefresh(w); } + // Propagate the changes in this window to the virtual screen and call + // doupdate(). This is redefined in NCursesPanel. + + virtual int noutrefresh() { return ::wnoutrefresh(w); } + // Propagate the changes in this window to the virtual screen. This is + // redefined in NCursesPanel. + + // ------------------------------------------------------------------------- + // multiple window control + // ------------------------------------------------------------------------- + int overlay(NCursesWindow& win) { + return ::overlay(w, win.w); } + // Overlay this window over win. + + int overwrite(NCursesWindow& win) { + return ::overwrite(w, win.w); } + // Overwrite win with this window. + + int copywin(NCursesWindow& win, + int sminrow, int smincol, + int dminrow, int dmincol, + int dmaxrow, int dmaxcol, bool overlay=TRUE) { + return ::copywin(w,win.w,sminrow,smincol,dminrow,dmincol, + dmaxrow,dmaxcol,(int)(overlay?1:0)); } + // Overlay or overwrite the rectangle in win given by dminrow,dmincol, + // dmaxrow,dmaxcol with the rectangle in this window beginning at + // sminrow,smincol. + + // ------------------------------------------------------------------------- + // Mouse related + // ------------------------------------------------------------------------- + bool has_mouse() const; + // Return TRUE if terminal supports a mouse, FALSE otherwise + + // ------------------------------------------------------------------------- + // traversal support + // ------------------------------------------------------------------------- + NCursesWindow* child() { return subwins; } + // Get the first child window. + + NCursesWindow* sibling() { return sib; } + // Get the next child of my parent. + + NCursesWindow* parent() { return par; } + // Get my parent. + + bool isDescendant(NCursesWindow& win); + // Return TRUE if win is a descendant of this. +}; + +// ------------------------------------------------------------------------- +// We leave this here for compatibility reasons. +// ------------------------------------------------------------------------- +class NCursesColorWindow : public NCursesWindow { +public: + NCursesColorWindow(WINDOW* &window) // useful only for stdscr + : NCursesWindow(window) { + useColors(); } + + NCursesColorWindow(int lines, // number of lines + int cols, // number of columns + int begin_y, // line origin + int begin_x) // col origin + : NCursesWindow(lines,cols,begin_y,begin_x) { + useColors(); } + + NCursesColorWindow(NCursesWindow& par,// parent window + int lines, // number of lines + int cols, // number of columns + int begin_y, // absolute or relative + int begin_x, // origins: + char absrel = 'a') // if `a', by & bx are + : NCursesWindow(par,lines,cols, // absolute screen pos, + begin_y,begin_x, // else if `r', they are + absrel ) { // relative to par origin + useColors(); } +}; + +// These enum definitions really belong inside the NCursesPad class, but only +// recent compilers support that feature. + + typedef enum { + REQ_PAD_REFRESH = KEY_MAX + 1, + REQ_PAD_UP, + REQ_PAD_DOWN, + REQ_PAD_LEFT, + REQ_PAD_RIGHT, + REQ_PAD_EXIT + } Pad_Request; + + const Pad_Request PAD_LOW = REQ_PAD_REFRESH; // lowest op-code + const Pad_Request PAD_HIGH = REQ_PAD_EXIT; // highest op-code + +// ------------------------------------------------------------------------- +// Pad Support. We allow an association of a pad with a "real" window +// through which the pad may be viewed. +// ------------------------------------------------------------------------- +class NCursesPad : public NCursesWindow { +private: + NCursesWindow* viewWin; // the "viewport" window + NCursesWindow* viewSub; // the "viewport" subwindow + + int h_gridsize, v_gridsize; + +protected: + int min_row, min_col; // top left row/col of the pads display area + + NCursesWindow* Win(void) const { + // Get the window into which the pad should be copied (if any) + return (viewSub?viewSub:(viewWin?viewWin:0)); + } + + NCursesWindow* getWindow(void) const { + return viewWin; + } + + NCursesWindow* getSubWindow(void) const { + return viewSub; + } + + virtual int driver (int key); // Virtualize keystroke key + // The driver translates the keystroke c into an Pad_Request + + virtual void OnUnknownOperation(int pad_req) { + ::beep(); + } + // This is called if the driver returns an unknown op-code + + virtual void OnNavigationError(int pad_req) { + ::beep(); + } + // This is called if a navigation request couldn't be satisfied + + virtual void OnOperation(int pad_req) { + }; + // OnOperation is called if a Pad_Operation was executed and just before + // the refresh() operation is done. + +public: + NCursesPad(int lines, int cols); + // create a pad with the given size + + virtual ~NCursesPad() {} + + int echochar(const chtype ch) { return ::pechochar(w,ch); } + // Put the attributed character onto the pad and immediately do a + // prefresh(). + + int refresh(); + // If a viewport is defined the pad is displayed in this window, otherwise + // this is a noop. + + int refresh(int pminrow, int pmincol, + int sminrow, int smincol, + int smaxrow, int smaxcol) { + return ::prefresh(w,pminrow,pmincol, + sminrow,smincol,smaxrow,smaxcol); + } + // The coordinates sminrow,smincol,smaxrow,smaxcol describe a rectangle + // on the screen. refresh copies a rectangle of this size beginning + // with top left corner pminrow,pmincol onto the screen and calls doupdate(). + + int noutrefresh(); + // If a viewport is defined the pad is displayed in this window, otherwise + // this is a noop. + + int noutrefresh(int pminrow, int pmincol, + int sminrow, int smincol, + int smaxrow, int smaxcol) { + return ::pnoutrefresh(w,pminrow,pmincol, + sminrow,smincol,smaxrow,smaxcol); + } + // Does the same like refresh() but without calling doupdate(). + + virtual void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1); + // Add the window "view" as viewing window to the pad. + + virtual void setSubWindow(NCursesWindow& sub); + // Use the subwindow "sub" of the viewport window for the actual viewing. + // The full viewport window is usually used to provide some decorations + // like frames, titles etc. + + virtual void operator() (void); + // Perform Pad's operation +}; + +// A FramedPad is constructed always with a viewport window. This viewport +// will be framed (by a box() command) and the interior of the box is the +// viewport subwindow. On the frame we display scrollbar sliders. +class NCursesFramedPad : public NCursesPad { +protected: + virtual void OnOperation(int pad_req); + +public: + NCursesFramedPad(NCursesWindow& win, int lines, int cols, + int v_grid = 1, int h_grid = 1) + : NCursesPad(lines,cols) { + NCursesPad::setWindow(win,v_grid,h_grid); + NCursesPad::setSubWindow(*(new NCursesWindow(win))); + } + // Construct the FramedPad with the given Window win as viewport. + + virtual ~NCursesFramedPad() { + delete getSubWindow(); + } + + void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1) { + err_handler("Operation not allowed"); + } + // Disable this call; the viewport is already defined + + void setSubWindow(NCursesWindow& sub) { + err_handler("Operation not allowed"); + } + // Disable this call; the viewport subwindow is already defined + +}; + +#endif // _CURSESW_H diff --git a/ncurses-5.2/c++/cursslk.cc b/ncurses-5.2/c++/cursslk.cc new file mode 100644 index 0000000..fc493e6 --- /dev/null +++ b/ncurses-5.2/c++/cursslk.cc @@ -0,0 +1,122 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +#include "cursslk.h" +#include "cursesapp.h" +#include "internal.h" +#include + +MODULE_ID("$Id$") + +void Soft_Label_Key_Set::Soft_Label_Key::operator=(char *text) { + delete[] label; + label = new char[1 + ::strlen(text)]; + (strcpy)(label,text); +} + +long Soft_Label_Key_Set::count = 0L; +int Soft_Label_Key_Set::num_labels = 0; + +Soft_Label_Key_Set::Label_Layout + Soft_Label_Key_Set::format = None; + +void Soft_Label_Key_Set::init() { + slk_array = new Soft_Label_Key[num_labels]; + for(int i=0; i < num_labels; i++) { + slk_array[i].num = i+1; + } + b_attrInit = FALSE; +} + +Soft_Label_Key_Set::Soft_Label_Key_Set() { + if (format==None) + Error("No default SLK layout"); + init(); +} + +Soft_Label_Key_Set::Soft_Label_Key_Set(Soft_Label_Key_Set::Label_Layout fmt) { + if (fmt==None) + Error("Invalid SLK Layout"); + if (count++==0) { + format = fmt; + if (ERR == ::slk_init((int)fmt)) + Error("slk_init"); + num_labels = (fmt>=PC_Style?12:8); + } + else if (fmt!=format) + Error("All SLKs must have same layout"); + init(); +} + +Soft_Label_Key_Set::~Soft_Label_Key_Set() { + if (!::isendwin()) + clear(); + delete[] slk_array; + count--; +} + +Soft_Label_Key_Set::Soft_Label_Key& Soft_Label_Key_Set::operator[](int i) { + if (i<1 || i>num_labels) + Error("Invalid Label index"); + return slk_array[i-1]; +} + +void Soft_Label_Key_Set::activate_label(int i, bool bf) { + if (!b_attrInit) { + NCursesApplication* A = NCursesApplication::getApplication(); + if (A) attrset(A->labels()); + b_attrInit = TRUE; + } + Soft_Label_Key& K = (*this)[i]; + if (ERR==::slk_set(K.num,bf?K.label:"",K.format)) + Error("slk_set"); + noutrefresh(); +} + +void Soft_Label_Key_Set::activate_labels(bool bf) { + if (!b_attrInit) { + NCursesApplication* A = NCursesApplication::getApplication(); + if (A) attrset(A->labels()); + b_attrInit = TRUE; + } + for(int i=1; i <= num_labels; i++) { + Soft_Label_Key& K = (*this)[i]; + if (ERR==::slk_set(K.num,bf?K.label:"",K.format)) + Error("slk_set"); + } + if (bf) + restore(); + else + clear(); + noutrefresh(); +} diff --git a/ncurses-5.2/c++/cursslk.h b/ncurses-5.2/c++/cursslk.h new file mode 100644 index 0000000..71750e0 --- /dev/null +++ b/ncurses-5.2/c++/cursslk.h @@ -0,0 +1,205 @@ +// * this is for making emacs happy: -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _CURSSLK_H +#define _CURSSLK_H + +#include + +class Soft_Label_Key_Set { +public: + // This inner class represents the attributes of a Soft Label Key (SLK) + class Soft_Label_Key { + friend class Soft_Label_Key_Set; + public: + typedef enum { Left=0, Center=1, Right=2 } Justification; + + private: + char *label; // The Text of the Label + Justification format; // The Justification + int num; // The number of the Label + + Soft_Label_Key() : label((char*)0),format(Left),num(-1) { + } + + virtual ~Soft_Label_Key() { + delete[] label; + }; + + public: + // Set the text of the Label + void operator=(char *text); + + // Set the Justification of the Label + inline void operator=(Justification just) { + format = just; + } + + // Retrieve the text of the label + inline char* operator()(void) const { + return label; + } + }; + +public: + typedef enum { + None = -1, + Three_Two_Three = 0, + Four_Four = 1, + PC_Style = 2, + PC_Style_With_Index = 3 + } Label_Layout; + +private: + static long count; // Number of Key Sets + static Label_Layout format; // Layout of the Key Sets + static int num_labels; // Number Of Labels in Key Sets + bool b_attrInit; // Are attributes initialized + + Soft_Label_Key *slk_array; // The array of SLK's + + // Init the Key Set + void init(); + + // Activate or Deactivate Label# i, Label counting starts with 1! + void activate_label(int i, bool bf=TRUE); + + // Activate of Deactivate all Labels + void activate_labels(bool bf); + +protected: + inline void Error (const char* msg) const THROWS(NCursesException) { + THROW(new NCursesException (msg)); + } + + // Remove SLK's from screen + void clear() { + if (ERR==::slk_clear()) + Error("slk_clear"); + } + + // Restore them + void restore() { + if (ERR==::slk_restore()) + Error("slk_restore"); + } + +public: + + // Construct a Key Set, use the most comfortable layout as default. + // You must create a Soft_Label_Key_Set before you create any object of + // the NCursesWindow, NCursesPanel or derived classes. (Actually before + // ::initscr() is called). + Soft_Label_Key_Set(Label_Layout fmt); + + // This constructor assumes, that you already constructed a Key Set + // with a layout by the constructor above. This layout will be reused. + Soft_Label_Key_Set(); + + virtual ~Soft_Label_Key_Set(); + + // Get Label# i. Label counting starts with 1! + Soft_Label_Key& operator[](int i); + + // Retrieve number of Labels + inline int labels() const { return num_labels; } + + // Refresh the SLK portion of the screen + inline void refresh() { + if (ERR==::slk_refresh()) + Error("slk_refresh"); + } + + // Mark the SLK portion of the screen for refresh, defer actual refresh + // until next update call. + inline void noutrefresh() { + if (ERR==::slk_noutrefresh()) + Error("slk_noutrefresh"); + } + + // Mark the whole SLK portion of the screen as modified + inline void touch() { + if (ERR==::slk_touch()) + Error("slk_touch"); + } + + // Activate Label# i + inline void show(int i) { + activate_label(i,FALSE); + activate_label(i,TRUE); + } + + // Hide Label# i + inline void hide(int i) { + activate_label(i,FALSE); + } + + // Show all Labels + inline void show() { + activate_labels(FALSE); + activate_labels(TRUE); + } + + // Hide all Labels + inline void hide() { + activate_labels(FALSE); + } + + inline void attron(attr_t attrs) { + if (ERR==::slk_attron(attrs)) + Error("slk_attron"); + } + + inline void attroff(attr_t attrs) { + if (ERR==::slk_attroff(attrs)) + Error("slk_attroff"); + } + + inline void attrset(attr_t attrs) { + if (ERR==::slk_attrset(attrs)) + Error("slk_attrset"); + } + + inline void color(short color_pair_number) { + if (ERR==::slk_color(color_pair_number)) + Error("slk_color"); + } + + inline attr_t attr() const { + return ::slk_attr(); + } +}; + +#endif // _CURSSLK_H diff --git a/ncurses-5.2/c++/demo.cc b/ncurses-5.2/c++/demo.cc new file mode 100644 index 0000000..614dc4f --- /dev/null +++ b/ncurses-5.2/c++/demo.cc @@ -0,0 +1,449 @@ +/* + * Silly demo program for the NCursesPanel class. + * + * written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu) + * + * Demo code for NCursesMenu and NCursesForm written by + * Juergen Pfeifer + * + * $Id$ + */ + +#include "cursesapp.h" +#include "cursesm.h" +#include "cursesf.h" + +#if HAVE_LIBC_H +# include +#endif + +extern "C" unsigned int sleep(unsigned int); + +#undef index // needed for NeXT + +// +// ------------------------------------------------------------------------- +// +class SillyDemo +{ + public: + void run(int sleeptime) { + + NCursesPanel *std = new NCursesPanel(); + + // Make a few small demo panels + + NCursesPanel *u = new NCursesPanel(8,20,12,4); + NCursesPanel *v = new NCursesPanel(8,20,10,6); + NCursesPanel *w = new NCursesPanel(8,20,8,8); + NCursesPanel *x = new NCursesPanel(8,20,6,10); + NCursesPanel *y = new NCursesPanel(8,20,4,12); + NCursesPanel *z = new NCursesPanel(8,30,2,14); + + // Draw something on the main screen, so we can see what happens + // when panels get moved or deleted. + + std->box(); + std->move(std->height()/2,1); + std->hline(std->width()-2); + std->move(1,std->width()/2); + std->vline(std->height()-2); + std->addch(0,std->width()/2,ACS_TTEE); + std->addch(std->height()-1,std->width()/2,ACS_BTEE); + std->addch(std->height()/2,0,ACS_LTEE); + std->addch(std->height()/2,std->width()-1,ACS_RTEE); + std->addch(std->height()/2,std->width()/2,ACS_PLUS); + + // Draw frames with titles around panels so that we can see where + // the panels are located. + u->boldframe("Win U"); + v->frame("Win V"); + w->boldframe("Win W"); + x->frame("Win X"); + y->boldframe("Win Y"); + z->frame("Win Z"); + if (NCursesApplication::getApplication()->useColors()) { + u->bkgd(' '|COLOR_PAIR(1)); + w->bkgd(' '|COLOR_PAIR(1)); + y->bkgd(' '|COLOR_PAIR(1)); + v->bkgd(' '|COLOR_PAIR(2)); + x->bkgd(' '|COLOR_PAIR(2)); + z->bkgd(' '|COLOR_PAIR(2)); + } + + // A refresh to any valid panel updates all panels and refreshes + // the screen. Using std is just convenient - We know it's always + // valid until the end of the program. + + std->refresh(); + sleep(sleeptime); + + // Show what happens when panels are deleted and moved. + + sleep(sleeptime); + delete u; + std->refresh(); + + sleep(sleeptime); + delete z; + std->refresh(); + + sleep(sleeptime); + delete v; + std->refresh(); + + // show how it looks when a panel moves + sleep(sleeptime); + y->mvwin(5,30); + std->refresh(); + + sleep(sleeptime); + delete y; + std->refresh(); + + // show how it looks when you raise a panel + sleep(sleeptime); + w->top(); + std->refresh(); + + sleep(sleeptime); + delete w; + std->refresh(); + + sleep(sleeptime); + delete x; + + std->clear(); + std->refresh(); + + // Don't forget to clean up the main screen. Since this is the + // last thing using NCursesWindow, this has the effect of + // shutting down ncurses and restoring the terminal state. + + sleep(sleeptime); + delete std; + } +}; + +class UserData +{ +private: + int u; +public: + UserData(int x) : u(x) {} + int sleeptime() const { return u; } +}; +// +// ------------------------------------------------------------------------- +// +template class MyAction : public NCursesUserItem +{ +public: + MyAction (const char* p_name, + const T* p_UserData) + : NCursesUserItem(p_name, (const char*)0, p_UserData) + {}; + + ~MyAction() {} + + bool action() { + SillyDemo a; + a.run(NCursesUserItem::UserData()->sleeptime()); + return FALSE; + } +}; + +class QuitItem : public NCursesMenuItem +{ +public: + QuitItem() : NCursesMenuItem("Quit") { + } + + bool action() { + return TRUE; + } +}; +// +// ------------------------------------------------------------------------- +// +class Label : public NCursesFormField +{ +public: + Label(const char* title, + int row, int col) + : NCursesFormField(1,(int)::strlen(title),row,col) { + set_value(title); + options_off(O_EDIT|O_ACTIVE); + } +}; +// +// ------------------------------------------------------------------------- +// +class MyFieldType : public UserDefinedFieldType { +private: + int chk; +protected: + bool field_check(NCursesFormField& f) { + return TRUE; + } + bool char_check(int c) { + return (c==chk?TRUE:FALSE); + } +public: + MyFieldType(int x) : chk(x) { + } +}; +// +// ------------------------------------------------------------------------- +// +class TestForm : public NCursesForm +{ +private: + NCursesFormField** F; + MyFieldType* mft; + Integer_Field *ift; + Enumeration_Field *eft; + + static char *weekdays[]; + +public: + TestForm() : NCursesForm(13,51,(lines()-15)/2,(cols()-53)/2) { + + F = new NCursesFormField*[10]; + mft = new MyFieldType('X'); + ift = new Integer_Field(0,1,10); + eft = new Enumeration_Field(weekdays); + + F[0] = new Label("Demo Entry Form",0,16); + F[1] = new Label("Weekday Enum",2,1); + F[2] = new Label("Number(1-10)",2,21); + F[3] = new Label("Only 'X'",2,35); + F[4] = new Label("Multiline Field (Dynamic and Scrollable)",5,1); + F[5] = new NCursesFormField(1,18,3,1); + F[6] = new NCursesFormField(1,12,3,21); + F[7] = new NCursesFormField(1,12,3,35); + F[8] = new NCursesFormField(4,46,6,1,2); + F[9] = new NCursesFormField(); + + InitForm(F,TRUE,TRUE); + boldframe(); + + F[5]->set_fieldtype(*eft); + F[6]->set_fieldtype(*ift); + + F[7]->set_fieldtype(*mft); + F[7]->set_maximum_growth(20); // max. 20 characters + F[7]->options_off(O_STATIC); // make field dynamic + + F[8]->set_maximum_growth(10); // max. 10 lines + F[8]->options_off(O_STATIC); // make field dynamic + } + + ~TestForm() { + delete mft; + delete ift; + delete eft; + } +}; + +char* TestForm::weekdays[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday", (char *)0 }; +// +// ------------------------------------------------------------------------- +// +class FormAction : public NCursesMenuItem +{ +public: + FormAction(const char *s) : NCursesMenuItem(s) { + } + + bool action() { + TestForm F; + Soft_Label_Key_Set* S = new Soft_Label_Key_Set; + for(int i=1; i <= S->labels(); i++) { + char buf[5]; + ::sprintf(buf,"Frm%02d",i); + (*S)[i] = buf; // Text + (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification + } + NCursesApplication::getApplication()->push(*S); + F(); + NCursesApplication::getApplication()->pop(); + return FALSE; + } +}; +// +// ------------------------------------------------------------------------- +// +class PadAction : public NCursesMenuItem +{ +public: + PadAction(const char* s) : NCursesMenuItem(s) { + } + + bool action() { + const int GRIDSIZE = 3; + const int PADSIZE = 200; + unsigned gridcount = 0; + + NCursesPanel std; + NCursesPanel P(std.lines()-2,std.cols()-2,1,1); + NCursesFramedPad FP(P,PADSIZE,PADSIZE); + + for (int i=0; i < PADSIZE; i++) { + for (int j=0; j < PADSIZE; j++) { + if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) { + if (i==0 || j==0) + FP.addch('+'); + else + FP.addch((chtype)('A' + (gridcount++ % 26))); + } + else if (i % GRIDSIZE == 0) + FP.addch('-'); + else if (j % GRIDSIZE == 0) + FP.addch('|'); + else + FP.addch(' '); + } + } + + P.label("Pad Demo",NULL); + FP(); + P.clear(); + return FALSE; + } +}; + +// +// ------------------------------------------------------------------------- +// +class PassiveItem : public NCursesMenuItem { +public: + PassiveItem(const char* text) : NCursesMenuItem(text) { + options_off(O_SELECTABLE); + } +}; +// +// ------------------------------------------------------------------------- +// +class MyMenu : public NCursesMenu +{ +private: + NCursesPanel* P; + NCursesMenuItem** I; + UserData *u; + #define n_items 7 + +public: + MyMenu () + : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2) + { + u = new UserData(1); + I = new NCursesMenuItem*[1+n_items]; + I[0] = new PassiveItem("One"); + I[1] = new PassiveItem("Two"); + I[2] = new MyAction ("Silly", u); + I[3] = new FormAction("Form"); + I[4] = new PadAction("Pad"); + I[5] = new PassiveItem("Six"); + I[6] = new QuitItem(); + I[7] = new NCursesMenuItem(); // Terminating empty item + + InitMenu(I,TRUE,TRUE); + + P = new NCursesPanel(1,n_items,LINES-1,1); + boldframe("Demo","Silly"); + P->show(); + } + + ~MyMenu() + { + P->hide(); + delete P; + delete u; + } + + virtual void On_Menu_Init() + { + NCursesWindow W(::stdscr); + P->move(0,0); + P->clrtoeol(); + for(int i=1; i<=count(); i++) + P->addch('0' + i); + P->bkgd(W.getbkgd()); + refresh(); + } + + virtual void On_Menu_Termination() + { + P->move(0,0); + P->clrtoeol(); + refresh(); + } + + virtual void On_Item_Init(NCursesMenuItem& item) + { + P->move(0,item.index()); + P->attron(A_REVERSE); + P->printw("%1d",1+item.index()); + P->attroff(A_REVERSE); + refresh(); + } + + virtual void On_Item_Termination(NCursesMenuItem& item) + { + P->move(0,item.index()); + P->attroff(A_REVERSE); + P->printw("%1d",1+item.index()); + refresh(); + } +}; +// +// ------------------------------------------------------------------------- +// +class TestApplication : public NCursesApplication { +protected: + int titlesize() const { return 1; } + void title(); + Soft_Label_Key_Set::Label_Layout useSLKs() const { + return Soft_Label_Key_Set::PC_Style_With_Index; + } + void init_labels(Soft_Label_Key_Set& S) const; + +public: + TestApplication() : NCursesApplication(TRUE) { + } + + int run(); +}; + +void TestApplication::init_labels(Soft_Label_Key_Set& S) const { + for(int i=1; i <= S.labels(); i++) { + char buf[5]; + ::sprintf(buf,"Key%02d",i); + S[i] = buf; // Text + S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification + } +} + +void TestApplication::title() { + const char * const title = "Simple C++ Binding Demo"; + const int len = ::strlen(title); + + titleWindow->bkgd(screen_titles()); + titleWindow->addstr(0,(titleWindow->cols()-len)/2,title); + titleWindow->noutrefresh(); +} + + +int TestApplication::run() { + MyMenu M; + M(); + return 0; +} + +// +// ------------------------------------------------------------------------- +// +static TestApplication Demo; diff --git a/ncurses-5.2/c++/edit_cfg.sh b/ncurses-5.2/c++/edit_cfg.sh new file mode 100755 index 0000000..d3abb9f --- /dev/null +++ b/ncurses-5.2/c++/edit_cfg.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# $Id$ +############################################################################## +# Copyright (c) 1998,2000 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Thomas E. Dickey 1997 +# +# Edit the default value of the etip.h file based on the autoconf-generated +# values: +# +# $1 = ncurses_cfg.h +# $2 = etip.h +# +echo "substituting autoconf'd values from $1 into $2" +for name in \ + CPP_HAS_PARAM_INIT \ + ETIP_NEEDS_MATH_EXCEPTION \ + ETIP_NEEDS_MATH_H \ + HAVE_BUILTIN_H \ + HAVE_GXX_BUILTIN_H \ + HAVE_GPP_BUILTIN_H \ + HAVE_TYPEINFO \ + HAVE_VALUES_H +do + mv $2 $2.bak + if ( grep "[ ]$name[ ]1" $1 2>&1 >/dev/null) + then + value=1 + sed -e 's/define '$name'.*$/define '$name' 1/' $2.bak >$2 + else + value=0 + sed -e 's/define '$name'.*$/define '$name' 0/' $2.bak >$2 + fi + if (cmp -s $2 $2.bak) + then + echo '... '$name $value + mv $2.bak $2 + else + echo '... '$name $value + rm -f $2.bak + fi +done diff --git a/ncurses-5.2/c++/etip.h.in b/ncurses-5.2/c++/etip.h.in new file mode 100644 index 0000000..5b5ca37 --- /dev/null +++ b/ncurses-5.2/c++/etip.h.in @@ -0,0 +1,273 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,1999 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _ETIP_H +#define _ETIP_H + +// These are substituted at configure/build time +#ifndef HAVE_BUILTIN_H +#define HAVE_BUILTIN_H 0 +#endif + +#ifndef HAVE_GXX_BUILTIN_H +#define HAVE_GXX_BUILTIN_H 0 +#endif + +#ifndef HAVE_GPP_BUILTIN_H +#define HAVE_GPP_BUILTIN_H 0 +#endif + +#ifndef HAVE_TYPEINFO +#define HAVE_TYPEINFO 0 +#endif + +#ifndef HAVE_VALUES_H +#define HAVE_VALUES_H 0 +#endif + +#ifndef ETIP_NEEDS_MATH_H +#define ETIP_NEEDS_MATH_H 0 +#endif + +#ifndef ETIP_NEEDS_MATH_EXCEPTION +#define ETIP_NEEDS_MATH_EXCEPTION 0 +#endif + +#ifndef CPP_HAS_PARAM_INIT +#define CPP_HAS_PARAM_INIT 0 +#endif + +#ifdef __GNUG__ +# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8)) +# if HAVE_TYPEINFO +# include +# endif +# endif +#endif + +#if defined(__GNUG__) +# if HAVE_BUILTIN_H || HAVE_GXX_BUILTIN_H || HAVE_GPP_BUILTIN_H +# if ETIP_NEEDS_MATH_H +# if ETIP_NEEDS_MATH_EXCEPTION +# undef exception +# define exception math_exception +# endif +# include +# endif +# undef exception +# define exception builtin_exception +# if HAVE_GPP_BUILTIN_H +# include +# elif HAVE_GXX_BUILTIN_H +# include +# else +# include +# endif +# undef exception +# endif +#elif defined (__SUNPRO_CC) +# include +# include +#else +# include +#endif + +extern "C" { +#if HAVE_VALUES_H +# include +#endif + +#include +#include +#include +} + +// Language features +#if CPP_HAS_PARAM_INIT +#define NCURSES_PARAM_INIT(value) = value +#else +#define NCURSES_PARAM_INIT(value) /*nothing*/ +#endif + +// Forward Declarations +class NCursesPanel; +class NCursesMenu; +class NCursesForm; + +class NCursesException +{ +public: + const char *message; + int errorno; + + NCursesException (const char* msg, int err) + : message(msg), errorno (err) + {}; + + NCursesException (const char* msg) + : message(msg), errorno (E_SYSTEM_ERROR) + {}; + + virtual const char *classname() const { + return "NCursesWindow"; + } +}; + +class NCursesPanelException : public NCursesException +{ +public: + const NCursesPanel* p; + + NCursesPanelException (const char *msg, int err) : + NCursesException (msg, err), + p ((NCursesPanel*)0) + {}; + + NCursesPanelException (const NCursesPanel* panel, + const char *msg, + int err) : + NCursesException (msg, err), + p (panel) + {}; + + NCursesPanelException (int err) : + NCursesException ("panel library error", err), + p ((NCursesPanel*)0) + {}; + + NCursesPanelException (const NCursesPanel* panel, + int err) : + NCursesException ("panel library error", err), + p (panel) + {}; + + virtual const char *classname() const { + return "NCursesPanel"; + } + +}; + +class NCursesMenuException : public NCursesException +{ +public: + const NCursesMenu* m; + + NCursesMenuException (const char *msg, int err) : + NCursesException (msg, err), + m ((NCursesMenu *)0) + {}; + + NCursesMenuException (const NCursesMenu* menu, + const char *msg, + int err) : + NCursesException (msg, err), + m (menu) + {}; + + NCursesMenuException (int err) : + NCursesException ("menu library error", err), + m ((NCursesMenu *)0) + {}; + + NCursesMenuException (const NCursesMenu* menu, + int err) : + NCursesException ("menu library error", err), + m (menu) + {}; + + virtual const char *classname() const { + return "NCursesMenu"; + } + +}; + +class NCursesFormException : public NCursesException +{ +public: + const NCursesForm* f; + + NCursesFormException (const char *msg, int err) : + NCursesException (msg, err), + f ((NCursesForm*)0) + {}; + + NCursesFormException (const NCursesForm* form, + const char *msg, + int err) : + NCursesException (msg, err), + f (form) + {}; + + NCursesFormException (int err) : + NCursesException ("form library error", err), + f ((NCursesForm*)0) + {}; + + NCursesFormException (const NCursesForm* form, + int err) : + NCursesException ("form library error", err), + f (form) + {}; + + virtual const char *classname() const { + return "NCursesForm"; + } + +}; + +#if !(defined(__GNUG__)||defined(__SUNPRO_CC)) +# include + extern "C" void exit(int); +#endif + +inline void THROW(const NCursesException *e) { +#if defined(__GNUG__) +# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8)) + (*lib_error_handler)(e?e->classname():"",e?e->message:""); +#else + throw *e; +#endif +#elif defined(__SUNPRO_CC) + genericerror(1, ((e != 0) ? (char *)(e->message) : "")); +#else + if (e) + cerr << e->message << endl; + exit(0); +#endif +} + +#define THROWS(s) + +#endif // _ETIP_H diff --git a/ncurses-5.2/c++/headers b/ncurses-5.2/c++/headers new file mode 100644 index 0000000..89f8ec5 --- /dev/null +++ b/ncurses-5.2/c++/headers @@ -0,0 +1,39 @@ +# C++ headers +# $Id$ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Thomas E. Dickey 1997 +# +$(srcdir)/cursesapp.h +$(srcdir)/cursesf.h +$(srcdir)/cursesm.h +$(srcdir)/cursesp.h +$(srcdir)/cursesw.h +$(srcdir)/cursslk.h +etip.h diff --git a/ncurses-5.2/c++/internal.h b/ncurses-5.2/c++/internal.h new file mode 100644 index 0000000..7df6c4d --- /dev/null +++ b/ncurses-5.2/c++/internal.h @@ -0,0 +1,47 @@ +// * This makes emacs happy -*-Mode: C++;-*- +/**************************************************************************** + * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer 1997 * + ****************************************************************************/ + +// $Id$ + +#ifndef _CPLUS_INTERNAL_H +#define _CPLUS_INTERNAL_H 1 + +#if USE_RCS_IDS +#define MODULE_ID(id) static const char Ident[] = id; +#else +#define MODULE_ID(id) /*nothing*/ +#endif + +#define CTRL(x) ((x) & 0x1f) + +#endif diff --git a/ncurses-5.2/c++/modules b/ncurses-5.2/c++/modules new file mode 100644 index 0000000..a2e2e60 --- /dev/null +++ b/ncurses-5.2/c++/modules @@ -0,0 +1,43 @@ +# Program modules +# $Id$ +############################################################################## +# Copyright (c) 1998 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# +# Author: Thomas E. Dickey 1995,1997 +# + +@ base +cursesf c++ $(srcdir) $(cursesf_h) $(cursesapp_h) +cursesm c++ $(srcdir) $(cursesm_h) $(cursesapp_h) +cursesp c++ $(srcdir) $(cursesp_h) +cursesw c++ $(srcdir) $(cursesw_h) +cursespad c++ $(srcdir) $(cursesw_h) +cursslk c++ $(srcdir) $(cursslk_h) $(cursesapp_h) +cursesapp c++ $(srcdir) $(cursesapp_h) +cursesmain c++ $(srcdir) $(cursesapp_h) +demo c++ $(srcdir) $(cursesf_h) $(cursesm_h) $(cursesapp_h) diff --git a/ncurses-5.2/config.guess b/ncurses-5.2/config.guess new file mode 100755 index 0000000..b100dbe --- /dev/null +++ b/ncurses-5.2/config.guess @@ -0,0 +1,1276 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-06-13' + +# 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 +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of this system. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + i?86:OS/2:*:*) + echo "i386-unknown-os2" + exit 0;; + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + *:Linux:*:*) + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + exit 0 + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + sparclinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + armlinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c < /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ncurses-5.2/config.sub b/ncurses-5.2/config.sub new file mode 100755 index 0000000..f8ec622 --- /dev/null +++ b/ncurses-5.2/config.sub @@ -0,0 +1,1328 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-07-06' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -os2) + basic_machine=`echo $1 | sed -e 's/86-.*/86/'` + ;; + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[234567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4) + base_machine=sh-unknown + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -os2 \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/ncurses-5.2/configure b/ncurses-5.2/configure new file mode 100755 index 0000000..c18a988 --- /dev/null +++ b/ncurses-5.2/configure @@ -0,0 +1,8083 @@ +#! /bin/sh + +# From configure.in Revision: 1.220 + + + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13.20000819 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # 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 << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF +cat <&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ncurses/base/lib_initscr.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + +NCURSES_MAJOR="`egrep '^NCURSES_MAJOR[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +NCURSES_MINOR="`egrep '^NCURSES_MINOR[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +NCURSES_PATCH="`egrep '^NCURSES_PATCH[ ]*=' $srcdir/dist.mk | sed -e 's/^[^0-9]*//'`" +cf_cv_abi_version=${NCURSES_MAJOR} +cf_cv_rel_version=${NCURSES_MAJOR}.${NCURSES_MINOR} +echo "$ac_t""Configuring NCURSES $cf_cv_rel_version ABI $cf_cv_abi_version (`date`)" 1>&6 + + + + + + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +if test -f $srcdir/config.guess ; then + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:675: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:696: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:714: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + system_name="$host_os" +else + system_name="`(uname -s -r) 2>/dev/null`" + if test -z "$system_name" ; then + system_name="`(hostname) 2>/dev/null`" + fi +fi +test -n "$system_name" && cat >> confdefs.h <&6 +else + cf_cv_system_name="$system_name" +fi + + +test -z "$system_name" && system_name="$cf_cv_system_name" +test -n "$cf_cv_system_name" && echo "$ac_t"""Configuring for $cf_cv_system_name"" 1>&6 + +if test ".$system_name" != ".$cf_cv_system_name" ; then + echo "$ac_t""Cached system name ($system_name) does not agree with actual ($cf_cv_system_name)" 1>&6 + { echo "configure: error: "Please remove config.cache and try again."" 1>&2; exit 1; } +fi + + +# Check whether --with-system-type or --without-system-type was given. +if test "${with_system_type+set}" = set; then + withval="$with_system_type" + echo "configure: warning: overriding system type to $withval" 1>&2 + cf_cv_system_name=$withval +fi + + +# We need a configure script only when compiling as part of GNU C library. +# Here we have to generate one of the files we need while compiling. +# +# The only problem is that users of the package might think they have to +# run configure themself and find it irritating when nothing happens. +# +# So we try here to find out whether we are called from the glibc configure +# or by a user. +# + +# Check whether --enable-add-ons or --disable-add-ons was given. +if test "${enable_add_ons+set}" = set; then + enableval="$enable_add_ons" + glibc_add_on=yes +else + glibc_add_on= +fi + + +if test x"$glibc_add_on" = "xyes" ; then + rm -f $srcdir/Banner + # We are in glibc. + rm -f $srcdir/Makefile + cp $srcdir/Makefile.glibc $srcdir/Makefile + echo "ncurses `grep \"^[ ]*ncurses-version[ ]*=.*$\" \ + $srcdir/Makefile | sed -e \ + 's/^[ ]*ncurses-version[ ]*=[ ]*\([^ ^ ]*\)[ ]*$/\1/'`" > $srcdir/Banner + exit 0 +fi + +### Save the given $CFLAGS to allow user-override. +cf_user_CFLAGS="$CFLAGS" + +### Default install-location + +echo $ac_n "checking for prefix""... $ac_c" 1>&6 +echo "configure:807: checking for prefix" >&5 +if test "x$prefix" = "xNONE" ; then + case "$cf_cv_system_name" in + # non-vendor systems don't have a conflict + openbsd*|netbsd*|freebsd*|linux*) + prefix=/usr + ;; + *) prefix=$ac_default_prefix + ;; + esac +fi +echo "$ac_t""$prefix" 1>&6 + +if test "x$prefix" = "xNONE" ; then +echo $ac_n "checking for default include-directory""... $ac_c" 1>&6 +echo "configure:822: checking for default include-directory" >&5 +test -n "$verbose" && echo 1>&6 +for cf_symbol in \ + $includedir \ + $includedir/ncurses \ + $prefix/include \ + $prefix/include/ncurses \ + /usr/local/include \ + /usr/local/include/ncurses \ + /usr/include \ + /usr/include/ncurses +do + cf_dir=`eval echo $cf_symbol` + if test -f $cf_dir/curses.h ; then + if ( fgrep NCURSES_VERSION $cf_dir/curses.h 2>&1 >/dev/null ) ; then + includedir="$cf_symbol" + test -n "$verbose" && echo $ac_n " found " 1>&6 + break + fi + fi + test -n "$verbose" && echo " tested $cf_dir" 1>&6 +done +echo "$ac_t""$includedir" 1>&6 +fi + + +### Checks for programs. +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:852: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:882: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:933: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:965: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 976 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1007: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1012: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1040: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +if test "$GCC" = yes ; then + echo $ac_n "checking version of gcc""... $ac_c" 1>&6 +echo "configure:1073: checking version of gcc" >&5 + eval "$CC --version" +fi +if test "$host" != $build; then + for ac_prog in $CC gcc cc +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1082: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$BUILD_CC"; then + ac_cv_prog_BUILD_CC="$BUILD_CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_BUILD_CC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +BUILD_CC="$ac_cv_prog_BUILD_CC" +if test -n "$BUILD_CC"; then + echo "$ac_t""$BUILD_CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$BUILD_CC" && break +done + +else + BUILD_CC="$CC" +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1116: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1154: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1171: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 +echo "configure:1197: checking whether ${CC-cc} needs -traditional" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_pattern="Autoconf.*'x'" + cat > conftest.$ac_ext < +Autoconf TIOCGETP +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +else + rm -rf conftest* + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat > conftest.$ac_ext < +Autoconf TCGETA +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi + +echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 +echo "configure:1243: checking for POSIXized ISC" >&5 +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + echo "$ac_t""yes" 1>&6 + ISC=yes # If later tests want to check for ISC. + cat >> confdefs.h <<\EOF +#define _POSIX_SOURCE 1 +EOF + + if test "$GCC" = yes; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +else + echo "$ac_t""no" 1>&6 + ISC= +fi + + +echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6 +echo "configure:1265: checking for ${CC-cc} option to accept ANSI C" >&5 +if eval "test \"`echo '$''{'cf_cv_ansi_cc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cf_cv_ansi_cc=no +cf_save_CFLAGS="$CFLAGS" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX -Aa -D_HPUX_SOURCE +# SVR4 -Xc +# UnixWare 1.2 (cannot use -Xc, since ANSI/POSIX clashes) +for cf_arg in "-DCC_HAS_PROTOS" \ + "" \ + -qlanglvl=ansi \ + -std1 \ + -Ae \ + "-Aa -D_HPUX_SOURCE" \ + -Xc +do + CFLAGS="$cf_save_CFLAGS $cf_arg" + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_ansi_cc="$cf_arg"; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +CFLAGS="$cf_save_CFLAGS" + +fi + +echo "$ac_t""$cf_cv_ansi_cc" 1>&6 + +if test "$cf_cv_ansi_cc" != "no"; then +if test ".$cf_cv_ansi_cc" != ".-DCC_HAS_PROTOS"; then + CFLAGS="$CFLAGS $cf_cv_ansi_cc" +else + cat >> confdefs.h <<\EOF +#define CC_HAS_PROTOS 1 +EOF + +fi +fi + + +if test "$cf_cv_ansi_cc" = "no"; then + { echo "configure: error: Your compiler does not appear to recognize prototypes. +You have the following choices: + a. adjust your compiler options + b. get an up-to-date compiler + c. use a wrapper such as unproto" 1>&2; exit 1; } +fi + + + +PROG_EXT= +case $cf_cv_system_name in +os2*) + # We make sure -Zexe is not used -- it would interfere with @PROG_EXT@ + CFLAGS="$CFLAGS -Zmt -D__ST_MT_ERRNO__" + CXXFLAGS="$CXXFLAGS -Zmt -D__ST_MT_ERRNO__" + LDFLAGS=`echo "$LDFLAGS -Zmt -Zcrtdll" | sed "s/-Zexe//g"` + PROG_EXT=".exe" + ;; +cygwin*) + PROG_EXT=".exe" + ;; +esac + + + +case "$cf_cv_system_name" in +freebsd*) #(vi + test -z "$LDCONFIG" && LDCONFIG="/sbin/ldconfig -R" + ;; +*) LDPATH=$PATH:/sbin:/usr/sbin + # Extract the first word of "ldconfig", so it can be a program name with args. +set dummy ldconfig; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1366: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_LDCONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$LDCONFIG" in + /*) + ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$LDPATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_LDCONFIG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +LDCONFIG="$ac_cv_path_LDCONFIG" +if test -n "$LDCONFIG"; then + echo "$ac_t""$LDCONFIG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + ;; +esac + + +echo $ac_n "checking if you want to ensure bool is consistent with C++""... $ac_c" 1>&6 +echo "configure:1403: checking if you want to ensure bool is consistent with C++" >&5 + +# Check whether --with-cxx or --without-cxx was given. +if test "${with_cxx+set}" = set; then + withval="$with_cxx" + cf_with_cxx=$withval +else + cf_with_cxx=yes +fi + +echo "$ac_t""$cf_with_cxx" 1>&6 +if test "X$cf_with_cxx" = Xno ; then + CXX="" + GXX="" +else + for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1423: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CXX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CXX="$ac_cv_prog_CXX" +if test -n "$CXX"; then + echo "$ac_t""$CXX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$CXX" && break +done +test -n "$CXX" || CXX="gcc" + + +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1455: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 + +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + +cat > conftest.$ac_ext << EOF + +#line 1466 "configure" +#include "confdefs.h" + +int main(){return(0);} +EOF +if { (eval echo configure:1471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cxx_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cxx_cross=no + else + ac_cv_prog_cxx_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cxx_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 +if test $ac_cv_prog_cxx_works = no; then + echo "$ac_t""You don't have any C++ compiler, too bad" 1>&6; cf_with_cxx=no; CXX=""; GXX=""; +fi +echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1497: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 +cross_compiling=$ac_cv_prog_cxx_cross + +echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 +echo "configure:1502: checking whether we are using GNU C++" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gxx=yes +else + ac_cv_prog_gxx=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gxx" 1>&6 + +if test $ac_cv_prog_gxx = yes; then + GXX=yes +else + GXX= +fi + +ac_test_CXXFLAGS="${CXXFLAGS+set}" +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS= +echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 +echo "configure:1530: checking whether ${CXX-g++} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.cc +if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then + ac_cv_prog_cxx_g=yes +else + ac_cv_prog_cxx_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS="$ac_save_CXXFLAGS" +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi + + fi + +if test "$GXX" = yes; then + case "`${CXX-g++} --version`" in + 1*|2.[0-6]*) + GXX=""; CXX=""; ac_cv_prog_gxx=no + cf_cxx_library=no + echo No: templates do not work + ;; + esac +fi + +echo $ac_n "checking if you want to build C++ binding and demo""... $ac_c" 1>&6 +echo "configure:1574: checking if you want to build C++ binding and demo" >&5 + +# Check whether --with-cxx-binding or --without-cxx-binding was given. +if test "${with_cxx_binding+set}" = set; then + withval="$with_cxx_binding" + cf_with_cxx_binding=$withval +else + cf_with_cxx_binding=$cf_with_cxx +fi + +echo "$ac_t""$cf_with_cxx_binding" 1>&6 + +echo $ac_n "checking if you want to build with Ada95""... $ac_c" 1>&6 +echo "configure:1587: checking if you want to build with Ada95" >&5 + +# Check whether --with-ada or --without-ada was given. +if test "${with_ada+set}" = set; then + withval="$with_ada" + cf_with_ada=$withval +else + cf_with_ada=yes +fi + +echo "$ac_t""$cf_with_ada" 1>&6 + +echo $ac_n "checking if you want to build programs such as tic""... $ac_c" 1>&6 +echo "configure:1600: checking if you want to build programs such as tic" >&5 + +# Check whether --with-progs or --without-progs was given. +if test "${with_progs+set}" = set; then + withval="$with_progs" + cf_with_progs=$withval +else + cf_with_progs=yes +fi + +echo "$ac_t""$cf_with_progs" 1>&6 + +echo $ac_n "checking if you wish to install curses.h""... $ac_c" 1>&6 +echo "configure:1613: checking if you wish to install curses.h" >&5 + +# Check whether --with-curses-h or --without-curses-h was given. +if test "${with_curses_h+set}" = set; then + withval="$with_curses_h" + with_curses_h=$withval +else + with_curses_h=yes +fi + +echo "$ac_t""$with_curses_h" 1>&6 + +modules_to_build="ncurses" +if test "X$cf_with_progs" != Xno ; then +modules_to_build="$modules_to_build progs tack" +fi +modules_to_build="$modules_to_build panel menu form" + +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +for ac_prog in mawk gawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1655: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1685: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1723: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +case $INSTALL in +/*) + ;; +*) + cf_dir=`echo $INSTALL|sed -e 's%/[^/]*$%%'` + test -z "$cf_dir" && cf_dir=. + INSTALL=`cd $cf_dir && pwd`/`echo $INSTALL | sed -e 's:^.*/::'` + ;; +esac + +echo $ac_n "checking for long file names""... $ac_c" 1>&6 +echo "configure:1786: checking for long file names" >&5 +if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_sys_long_file_names=yes +# Test for long file names in all the places we know might matter: +# . the current directory, where building will happen +# $prefix/lib where we will be installing things +# $exec_prefix/lib likewise +# eval it to expand exec_prefix. +# $TMPDIR if set, where it might want to write temporary files +# if $TMPDIR is not set: +# /tmp where it might want to write temporary files +# /var/tmp likewise +# /usr/tmp likewise +if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then + ac_tmpdirs="$TMPDIR" +else + ac_tmpdirs='/tmp /var/tmp /usr/tmp' +fi +for ac_dir in . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do + test -d $ac_dir || continue + test -w $ac_dir || continue # It is less confusing to not echo anything here. + (echo 1 > $ac_dir/conftest9012345) 2>/dev/null + (echo 2 > $ac_dir/conftest9012346) 2>/dev/null + val=`cat $ac_dir/conftest9012345 2>/dev/null` + if test ! -f $ac_dir/conftest9012345 || test "$val" != 1; then + ac_cv_sys_long_file_names=no + rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null + break + fi + rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null +done +fi + +echo "$ac_t""$ac_cv_sys_long_file_names" 1>&6 +if test $ac_cv_sys_long_file_names = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LONG_FILE_NAMES 1 +EOF + +fi + + +echo $ac_n "checking if filesystem supports mixed-case filenames""... $ac_c" 1>&6 +echo "configure:1831: checking if filesystem supports mixed-case filenames" >&5 +if eval "test \"`echo '$''{'cf_cv_mixedcase'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + rm -f conftest CONFTEST + echo test >conftest + if test -f CONFTEST ; then + cf_cv_mixedcase=no + else + cf_cv_mixedcase=yes + fi + rm -f conftest CONFTEST + +fi + +echo "$ac_t""$cf_cv_mixedcase" 1>&6 +test "$cf_cv_mixedcase" = yes && cat >> confdefs.h <<\EOF +#define MIXEDCASE_FILENAMES 1 +EOF + + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1854: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1877: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "ctags", so it can be a program name with args. +set dummy ctags; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1909: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_MAKE_LOWER_TAGS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$MAKE_LOWER_TAGS"; then + ac_cv_prog_MAKE_LOWER_TAGS="$MAKE_LOWER_TAGS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_MAKE_LOWER_TAGS="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_MAKE_LOWER_TAGS" && ac_cv_prog_MAKE_LOWER_TAGS="no" +fi +fi +MAKE_LOWER_TAGS="$ac_cv_prog_MAKE_LOWER_TAGS" +if test -n "$MAKE_LOWER_TAGS"; then + echo "$ac_t""$MAKE_LOWER_TAGS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test "$cf_cv_mixedcase" = yes ; then + # Extract the first word of "etags", so it can be a program name with args. +set dummy etags; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1941: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_MAKE_UPPER_TAGS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$MAKE_UPPER_TAGS"; then + ac_cv_prog_MAKE_UPPER_TAGS="$MAKE_UPPER_TAGS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_MAKE_UPPER_TAGS="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_MAKE_UPPER_TAGS" && ac_cv_prog_MAKE_UPPER_TAGS="no" +fi +fi +MAKE_UPPER_TAGS="$ac_cv_prog_MAKE_UPPER_TAGS" +if test -n "$MAKE_UPPER_TAGS"; then + echo "$ac_t""$MAKE_UPPER_TAGS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + MAKE_UPPER_TAGS=no +fi + +if test "$MAKE_UPPER_TAGS" = yes ; then + MAKE_UPPER_TAGS= +else + MAKE_UPPER_TAGS="#" +fi + + +if test "$MAKE_LOWER_TAGS" = yes ; then + MAKE_LOWER_TAGS= +else + MAKE_LOWER_TAGS="#" +fi + + +for ac_prog in tdlint lint alint +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1991: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LINT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LINT"; then + ac_cv_prog_LINT="$LINT" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LINT="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +LINT="$ac_cv_prog_LINT" +if test -n "$LINT"; then + echo "$ac_t""$LINT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$LINT" && break +done + +for ac_prog in man man_db +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2025: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_MAN'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$MAN"; then + ac_cv_prog_MAN="$MAN" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_MAN="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +MAN="$ac_cv_prog_MAN" +if test -n "$MAN"; then + echo "$ac_t""$MAN" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$MAN" && break +done + + + +if eval "test \"`echo '$''{'cf_cv_subst_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +echo $ac_n "checking for loader (symbol LD)""... $ac_c" 1>&6 +echo "configure:2061: checking for loader (symbol LD)" >&5 +test -z "$LD" && LD=ld +echo "$ac_t""$LD" 1>&6 + +cf_cv_subst_LD=$LD +fi + +LD=${cf_cv_subst_LD} + +if eval "test \"`echo '$''{'cf_cv_subst_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +echo $ac_n "checking for archiver (symbol AR)""... $ac_c" 1>&6 +echo "configure:2075: checking for archiver (symbol AR)" >&5 +test -z "$AR" && AR=ar +echo "$ac_t""$AR" 1>&6 + +cf_cv_subst_AR=$AR +fi + +AR=${cf_cv_subst_AR} + +if eval "test \"`echo '$''{'cf_cv_subst_AR_OPTS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +echo $ac_n "checking for archiver options (symbol AR_OPTS)""... $ac_c" 1>&6 +echo "configure:2089: checking for archiver options (symbol AR_OPTS)" >&5 +test -z "$AR_OPTS" && AR_OPTS=rv +echo "$ac_t""$AR_OPTS" 1>&6 + +cf_cv_subst_AR_OPTS=$AR_OPTS +fi + +AR_OPTS=${cf_cv_subst_AR_OPTS} + + + +echo $ac_n "checking for makeflags variable""... $ac_c" 1>&6 +echo "configure:2101: checking for makeflags variable" >&5 +if eval "test \"`echo '$''{'cf_cv_makeflags'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cf_cv_makeflags='' + for cf_option in '-$(MAKEFLAGS)' '$(MFLAGS)' + do + cat >cf_makeflags.tmp </dev/null` + case "$cf_result" in + .*k) + cf_result=`${MAKE-make} -k -f cf_makeflags.tmp CC=cc 2>/dev/null` + case "$cf_result" in + .*CC=*) cf_cv_makeflags= + ;; + *) cf_cv_makeflags=$cf_option + ;; + esac + break + ;; + *) echo no match "$cf_result" + ;; + esac + done + rm -f cf_makeflags.tmp +fi + +echo "$ac_t""$cf_cv_makeflags" 1>&6 + + + +echo $ac_n "checking if you have specified an install-prefix""... $ac_c" 1>&6 +echo "configure:2137: checking if you have specified an install-prefix" >&5 + +# Check whether --with-install-prefix or --without-install-prefix was given. +if test "${with_install_prefix+set}" = set; then + withval="$with_install_prefix" + case "$withval" in #(vi + yes|no) #(vi + ;; + *) DESTDIR="$withval" + ;; + esac +fi + +echo "$ac_t""$DESTDIR" 1>&6 + + +############################################################################### + + +### Options to allow the user to specify the set of libraries which are used. +### Use "--without-normal --with-shared" to allow the default model to be +### shared, for example. +cf_list_models="" + +echo $ac_n "checking if you want to build libraries with libtool""... $ac_c" 1>&6 +echo "configure:2162: checking if you want to build libraries with libtool" >&5 + +# Check whether --with-libtool or --without-libtool was given. +if test "${with_libtool+set}" = set; then + withval="$with_libtool" + with_libtool=$withval +else + with_libtool=no +fi + +echo "$ac_t""$with_libtool" 1>&6 +if test "$with_libtool" = "yes"; then + cf_list_models="$cf_list_models libtool" + test -z "$LIBTOOL" && LIBTOOL=libtool +else + LIBTOOL="" +fi + + +echo $ac_n "checking if you want to build shared libraries""... $ac_c" 1>&6 +echo "configure:2182: checking if you want to build shared libraries" >&5 + +# Check whether --with-shared or --without-shared was given. +if test "${with_shared+set}" = set; then + withval="$with_shared" + with_shared=$withval +else + with_shared=no +fi + +echo "$ac_t""$with_shared" 1>&6 +test "$with_shared" = "yes" && cf_list_models="$cf_list_models shared" + +echo $ac_n "checking if you want to build static libraries""... $ac_c" 1>&6 +echo "configure:2196: checking if you want to build static libraries" >&5 + +# Check whether --with-normal or --without-normal was given. +if test "${with_normal+set}" = set; then + withval="$with_normal" + with_normal=$withval +else + with_normal=yes +fi + +echo "$ac_t""$with_normal" 1>&6 +test "$with_normal" = "yes" && cf_list_models="$cf_list_models normal" + +echo $ac_n "checking if you want to build debug libraries""... $ac_c" 1>&6 +echo "configure:2210: checking if you want to build debug libraries" >&5 + +# Check whether --with-debug or --without-debug was given. +if test "${with_debug+set}" = set; then + withval="$with_debug" + with_debug=$withval +else + with_debug=yes +fi + +echo "$ac_t""$with_debug" 1>&6 +test "$with_debug" = "yes" && cf_list_models="$cf_list_models debug" + +echo $ac_n "checking if you want to build profiling libraries""... $ac_c" 1>&6 +echo "configure:2224: checking if you want to build profiling libraries" >&5 + +# Check whether --with-profile or --without-profile was given. +if test "${with_profile+set}" = set; then + withval="$with_profile" + with_profile=$withval +else + with_profile=no +fi + +echo "$ac_t""$with_profile" 1>&6 +test "$with_profile" = "yes" && cf_list_models="$cf_list_models profile" + +############################################################################### + +echo $ac_n "checking for specified models""... $ac_c" 1>&6 +echo "configure:2240: checking for specified models" >&5 +test -z "$cf_list_models" && cf_list_models=normal +test "$with_libtool" = "yes" && cf_list_models=libtool +echo "$ac_t""$cf_list_models" 1>&6 + +### Use the first model as the default, and save its suffix for use in building +### up test-applications. +echo $ac_n "checking for default model""... $ac_c" 1>&6 +echo "configure:2248: checking for default model" >&5 +DFT_LWR_MODEL=`echo $cf_list_models | $AWK '{print $1}'` +echo "$ac_t""$DFT_LWR_MODEL" 1>&6 + + +DFT_UPR_MODEL=`echo "$DFT_LWR_MODEL" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + +TINFO_NAME=tinfo + + +LIB_NAME=ncurses + + +LIB_DIR=../lib + + case $cf_cv_system_name in + os2) LIB_PREFIX='' ;; + *) LIB_PREFIX='lib' ;; + esac +cf_prefix=$LIB_PREFIX + + +LIB_PREFIX=$cf_prefix + + +LIB_SUFFIX= + + +############################################################################### + +echo $ac_n "checking if you want to build a separate terminfo library""... $ac_c" 1>&6 +echo "configure:2280: checking if you want to build a separate terminfo library" >&5 + +# Check whether --with-termlib or --without-termlib was given. +if test "${with_termlib+set}" = set; then + withval="$with_termlib" + with_termlib=$withval +else + with_termlib=no +fi + +echo "$ac_t""$with_termlib" 1>&6 + +### Checks for special libraries, must be done up-front. +echo $ac_n "checking if you want to link with dbmalloc for testing""... $ac_c" 1>&6 +echo "configure:2294: checking if you want to link with dbmalloc for testing" >&5 + +# Check whether --with-dbmalloc or --without-dbmalloc was given. +if test "${with_dbmalloc+set}" = set; then + withval="$with_dbmalloc" + with_dbmalloc=$withval +else + with_dbmalloc=no +fi + +echo "$ac_t""$with_dbmalloc" 1>&6 +if test "$with_dbmalloc" = yes ; then + echo $ac_n "checking for debug_malloc in -ldbmalloc""... $ac_c" 1>&6 +echo "configure:2307: checking for debug_malloc in -ldbmalloc" >&5 +ac_lib_var=`echo dbmalloc'_'debug_malloc | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldbmalloc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dbmalloc | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +echo $ac_n "checking if you want to link with dmalloc for testing""... $ac_c" 1>&6 +echo "configure:2356: checking if you want to link with dmalloc for testing" >&5 + +# Check whether --with-dmalloc or --without-dmalloc was given. +if test "${with_dmalloc+set}" = set; then + withval="$with_dmalloc" + with_dmalloc=$withval +else + with_dmalloc=no +fi + +echo "$ac_t""$with_dmalloc" 1>&6 +if test "$with_dmalloc" = yes ; then + echo $ac_n "checking for dmalloc_debug in -ldmalloc""... $ac_c" 1>&6 +echo "configure:2369: checking for dmalloc_debug in -ldmalloc" >&5 +ac_lib_var=`echo dmalloc'_'dmalloc_debug | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldmalloc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo dmalloc | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + +SHLIB_LIST="" +echo $ac_n "checking if you want to link with the gpm mouse library""... $ac_c" 1>&6 +echo "configure:2419: checking if you want to link with the gpm mouse library" >&5 + +# Check whether --with-gpm or --without-gpm was given. +if test "${with_gpm+set}" = set; then + withval="$with_gpm" + with_gpm=$withval +else + with_gpm=no +fi + +echo "$ac_t""$with_gpm" 1>&6 +if test "$with_gpm" = yes ; then + echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6 +echo "configure:2432: checking for Gpm_Open in -lgpm" >&5 +ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgpm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + EXTRA_LIBS="-lgpm -lncurses $EXTRA_LIBS" + SHLIB_LIST="-lgpm $SHLIB_LIST" + cat >> confdefs.h <<\EOF +#define HAVE_LIBGPM 1 +EOF + + for ac_hdr in gpm.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2477: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +else + echo "$ac_t""no" 1>&6 +echo "configure: warning: Cannot link with gpm library - read the FAQ" 1>&2 +fi + +fi + + +if test X"$CC_G_OPT" = X"" ; then + CC_G_OPT='-g' + test -n "$GCC" && test "${ac_cv_prog_cc_g}" != yes && CC_G_OPT='' +fi + + +if test X"$CXX_G_OPT" = X"" ; then + CXX_G_OPT='-g' + test -n "$GXX" && test "${ac_cv_prog_cxx_g}" != yes && CXX_G_OPT='' +fi + + +echo $ac_n "checking for default loader flags""... $ac_c" 1>&6 +echo "configure:2535: checking for default loader flags" >&5 +case $DFT_LWR_MODEL in +libtool) LD_MODEL='' ;; +normal) LD_MODEL='' ;; +debug) LD_MODEL=$CC_G_OPT ;; +profile) LD_MODEL='-pg';; +shared) LD_MODEL='' ;; +esac +echo "$ac_t""$LD_MODEL" 1>&6 + +echo $ac_n "checking if rpath option should be used""... $ac_c" 1>&6 +echo "configure:2546: checking if rpath option should be used" >&5 + +# Check whether --enable-rpath or --disable-rpath was given. +if test "${enable_rpath+set}" = set; then + enableval="$enable_rpath" + cf_cv_ld_rpath=$enableval +else + cf_cv_ld_rpath=no +fi + +echo "$ac_t""$cf_cv_ld_rpath" 1>&6 + + + + LOCAL_LDFLAGS= + LOCAL_LDFLAGS2= + LD_SHARED_OPTS= + INSTALL_LIB="-m 644" + + cf_cv_do_symlinks=no + + echo $ac_n "checking if release/abi version should be used for shared libs""... $ac_c" 1>&6 +echo "configure:2568: checking if release/abi version should be used for shared libs" >&5 + +# Check whether --with-shlib-version or --without-shlib-version was given. +if test "${with_shlib_version+set}" = set; then + withval="$with_shlib_version" + test -z "$withval" && withval=auto + case $withval in #(vi + yes) #(vi + cf_cv_shlib_version=auto + ;; + rel|abi|auto|no) #(vi + cf_cv_shlib_version=$withval + ;; + *) + { echo "configure: error: option value must be one of: rel, abi, auto or no" 1>&2; exit 1; } + ;; + esac + +else + cf_cv_shlib_version=auto +fi + + echo "$ac_t""$cf_cv_shlib_version" 1>&6 + + cf_cv_rm_so_locs=no + + # Some less-capable ports of gcc support only -fpic + CC_SHARED_OPTS= + if test "$GCC" = yes + then + echo $ac_n "checking which $CC option to use""... $ac_c" 1>&6 +echo "configure:2599: checking which $CC option to use" >&5 + cf_save_CFLAGS="$CFLAGS" + for CC_SHARED_OPTS in -fPIC -fpic '' + do + CFLAGS="$cf_save_CFLAGS $CC_SHARED_OPTS" + cat > conftest.$ac_ext < +int main() { +int x = 1 +; return 0; } +EOF +if { (eval echo configure:2612: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* + done + echo "$ac_t""$CC_SHARED_OPTS" 1>&6 + CFLAGS="$cf_save_CFLAGS" + fi + + case $cf_cv_system_name in + beos*) + MK_SHARED_LIB='$(CC) -o $@ -Xlinker -soname=`basename $@` -nostart -e 0' + ;; + hpux*) + # (tested with gcc 2.7.2 -- I don't have c89) + if test "$GCC" = yes; then + LD_SHARED_OPTS='-Xlinker +b -Xlinker $(libdir)' + else + CC_SHARED_OPTS='+Z' + LD_SHARED_OPTS='-Wl,+b,$(libdir)' + fi + MK_SHARED_LIB='$(LD) +b $(libdir) -b -o $@' + # HP-UX shared libraries must be executable, and should be + # readonly to exploit a quirk in the memory manager. + INSTALL_LIB="-m 555" + ;; + irix*) + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-Wl,-rpath," + EXTRA_LDFLAGS="-Wl,-rpath,\$(libdir) $EXTRA_LDFLAGS" + fi + # tested with IRIX 5.2 and 'cc'. + if test "$GCC" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -shared -rdata_shared -soname `basename $@` -o $@' + cf_cv_rm_so_locs=yes + ;; + linux*|gnu*) + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-Wl,-rpath," + EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + MK_SHARED_LIB='$(CC) -shared -Wl,-soname,`basename $@ .$(REL_VERSION)`.$(ABI_VERSION),-stats,-lc -o $@' + ;; + openbsd2*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + MK_SHARED_LIB='$(LD) -Bshareable -soname,`basename $@.$(ABI_VERSION)` -o $@' + ;; + openbsd*|freebsd*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + MK_SHARED_LIB='$(LD) -Bshareable -o $@' + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + netbsd*) + CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC" + test "$cf_cv_ld_rpath" = yes && cf_ld_rpath_opt="-Wl,-rpath," + if test "$DFT_LWR_MODEL" = "shared" && test "$cf_cv_ld_rpath" = yes ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + EXTRA_LDFLAGS="-Wl,-rpath,\$(libdir) $EXTRA_LDFLAGS" + MK_SHARED_LIB='$(CC) -shared -Wl,-soname,`basename $@ .$(REL_VERSION)`.$(ABI_VERSION) -o $@' + if test "$cf_cv_shlib_version" = auto; then + if test ! -f /usr/libexec/ld.elf_so; then + cf_cv_shlib_version=rel + fi + fi + else + MK_SHARED_LIB='$(LD) -Bshareable -o $@' + fi + ;; + osf*|mls+*) + # tested with OSF/1 V3.2 and 'cc' + # tested with OSF/1 V3.2 and gcc 2.6.3 (but the c++ demo didn't + # link with shared libs). + MK_SHARED_LIB='$(LD) -set_version $(REL_VERSION):$(ABI_VERSION) -expect_unresolved "*" -shared -soname `basename $@`' + case $host_os in + osf4*) + MK_SHARED_LIB="${MK_SHARED_LIB} -msym" + ;; + esac + MK_SHARED_LIB="${MK_SHARED_LIB}"' -o $@' + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-Wl,-rpath,`pwd`/lib" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-rpath" + # EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + cf_cv_rm_so_locs=yes + ;; + sco3.2v5*) # (also uw2* and UW7) hops 13-Apr-98 + # tested with osr5.0.5 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-belf -KPIC' + fi + MK_SHARED_LIB='$(LD) -dy -G -h `basename $@ .$(REL_VERSION)`.$(ABI_VERSION) -o $@' + if test "$cf_cv_ld_rpath" = yes ; then + # only way is to set LD_RUN_PATH but no switch for it + RUN_PATH=$libdir + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + LINK_PROGS='LD_RUN_PATH=$(libdir)' + LINK_TESTS='Pwd=`pwd`;LD_RUN_PATH=`dirname $${Pwd}`/lib' + ;; + sunos4*) + # tested with SunOS 4.1.1 and gcc 2.7.0 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -assert pure-text -o $@' + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + solaris2*) + # tested with SunOS 5.5.1 (solaris 2.5.1) and gcc 2.7.2 + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -dy -G -h `basename $@ .$(REL_VERSION)`.$(ABI_VERSION) -o $@' + if test "$DFT_LWR_MODEL" = "shared" ; then + LOCAL_LDFLAGS="-R `pwd`/lib:\$(libdir)" + LOCAL_LDFLAGS2="$LOCAL_LDFLAGS" + fi + if test "$cf_cv_ld_rpath" = yes ; then + cf_ld_rpath_opt="-R" + EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS" + fi + test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel + ;; + sysv5uw7*|unix_sv*) + # tested with UnixWare 7.1.0 (gcc 2.95.2 and cc) + if test "$ac_cv_prog_gcc" != yes; then + CC_SHARED_OPTS='-KPIC' + fi + MK_SHARED_LIB='$(LD) -d y -G -o $@' + ;; + *) + CC_SHARED_OPTS='unknown' + MK_SHARED_LIB='echo unknown' + ;; + esac + + # This works if the last tokens in $MK_SHARED_LIB are the -o target. + case "$cf_cv_shlib_version" in #(vi + rel|abi) + case "$MK_SHARED_LIB" in #(vi + *'-o $@') + test "$cf_cv_do_symlinks" = no && cf_cv_do_symlinks=yes + ;; + *) + echo "configure: warning: ignored --with-shlib-version" 1>&2 + ;; + esac + ;; + esac + + if test -n "$cf_ld_rpath_opt" ; then + echo $ac_n "checking if we need a space after rpath option""... $ac_c" 1>&6 +echo "configure:2780: checking if we need a space after rpath option" >&5 + cf_save_LIBS="$LIBS" + LIBS="$LIBS ${cf_ld_rpath_opt}$libdir" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_rpath_space=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_rpath_space=yes +fi +rm -f conftest* + LIBS="$cf_save_LIBS" + echo "$ac_t""$cf_rpath_space" 1>&6 + test "$cf_rpath_space" = yes && cf_ld_rpath_opt="$cf_ld_rpath_opt " + MK_SHARED_LIB="$MK_SHARED_LIB $cf_ld_rpath_opt\$(libdir)" + fi + + + + + + + + + + + +if test "$CC_SHARED_OPTS" = "unknown"; then + for model in $cf_list_models; do + if test "$model" = "shared"; then + { echo "configure: error: Shared libraries are not supported in this version" 1>&2; exit 1; } + fi + done +fi + +############################################################################### + + +### use option --disable-overwrite to leave out the link to -lcurses +echo $ac_n "checking if you wish to install ncurses overwriting curses""... $ac_c" 1>&6 +echo "configure:2830: checking if you wish to install ncurses overwriting curses" >&5 + +# Check whether --enable-overwrite or --disable-overwrite was given. +if test "${enable_overwrite+set}" = set; then + enableval="$enable_overwrite" + with_overwrite=$enableval +else + with_overwrite=yes +fi + +echo "$ac_t""$with_overwrite" 1>&6 + +echo $ac_n "checking if external terminfo-database is used""... $ac_c" 1>&6 +echo "configure:2843: checking if external terminfo-database is used" >&5 + +# Check whether --enable-database or --disable-database was given. +if test "${enable_database+set}" = set; then + enableval="$enable_database" + use_database=$enableval +else + use_database=yes +fi + +echo "$ac_t""$use_database" 1>&6 + +case $host_os in #(vi +os2*) #(vi + TERMINFO_SRC='${top_srcdir}/misc/emx.src' + ;; +*) #(vi + TERMINFO_SRC='${top_srcdir}/misc/terminfo.src' + ;; +esac + + +if test "$use_database" != no ; then + cat >> confdefs.h <<\EOF +#define USE_DATABASE 1 +EOF + + echo $ac_n "checking which terminfo source-file will be installed""... $ac_c" 1>&6 +echo "configure:2871: checking which terminfo source-file will be installed" >&5 + +# Check whether --enable-database or --disable-database was given. +if test "${enable_database+set}" = set; then + enableval="$enable_database" + TERMINFO_SRC=$withval +fi + + echo "$ac_t""$TERMINFO_SRC" 1>&6 +fi + +echo $ac_n "checking for list of fallback descriptions""... $ac_c" 1>&6 +echo "configure:2883: checking for list of fallback descriptions" >&5 + +# Check whether --with-fallbacks or --without-fallbacks was given. +if test "${with_fallbacks+set}" = set; then + withval="$with_fallbacks" + with_fallback=$withval +else + with_fallback= +fi + +echo "$ac_t""$with_fallback" 1>&6 +FALLBACK_LIST=`echo $with_fallback|sed -e 's/,/ /g'` + + +if test "$use_database" = no ; then + if test -z $with_fallback ; then + { echo "configure: error: You have disabled the database w/o specifying fallbacks" 1>&2; exit 1; } + fi + TERMINFO="${datadir}/terminfo" +else + +echo $ac_n "checking for list of terminfo directories""... $ac_c" 1>&6 +echo "configure:2905: checking for list of terminfo directories" >&5 + + +# Check whether --with-terminfo-dirs or --without-terminfo-dirs was given. +if test "${with_terminfo_dirs+set}" = set; then + withval="$with_terminfo_dirs" + : +else + withval="${TERMINFO_DIRS-${datadir}/terminfo}" +fi + +IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" +cf_dst_path= +for cf_src_path in $withval +do + +case ".$cf_src_path" in #(vi +./*) #(vi + ;; +.a-zA-Z:\\/*) #(vi OS/2 EMX + ;; +.\${*prefix}*) #(vi + eval cf_src_path="$cf_src_path" + case ".$cf_src_path" in #(vi + .NONE/*) + cf_src_path=`echo $cf_src_path | sed -e s@NONE@$ac_default_prefix@` + ;; + esac + ;; #(vi +.NONE/*) + cf_src_path=`echo $cf_src_path | sed -e s@NONE@$ac_default_prefix@` + ;; +*) + { echo "configure: error: expected a pathname" 1>&2; exit 1; } + ;; +esac + + test -n "$cf_dst_path" && cf_dst_path="${cf_dst_path}:" + cf_dst_path="${cf_dst_path}${cf_src_path}" +done +IFS="$ac_save_ifs" + +eval TERMINFO_DIRS="$cf_dst_path" + +echo "$ac_t""$TERMINFO_DIRS" 1>&6 +test -n "$TERMINFO_DIRS" && cat >> confdefs.h <&6 +echo "configure:2956: checking for default terminfo directory" >&5 + +# Check whether --with-default-terminfo-dir or --without-default-terminfo-dir was given. +if test "${with_default_terminfo_dir+set}" = set; then + withval="$with_default_terminfo_dir" + : +else + withval="${TERMINFO-${datadir}/terminfo}" +fi + +case ".$withval" in #(vi +./*) #(vi + ;; +.a-zA-Z:\\/*) #(vi OS/2 EMX + ;; +.\${*prefix}*) #(vi + eval withval="$withval" + case ".$withval" in #(vi + .NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; + esac + ;; #(vi +.NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; +*) + { echo "configure: error: expected a pathname" 1>&2; exit 1; } + ;; +esac + +eval TERMINFO="$withval" + +echo "$ac_t""$TERMINFO" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3002: checking if big-core option selected" >&5 + +# Check whether --enable-big-core or --disable-big-core was given. +if test "${enable_big_core+set}" = set; then + enableval="$enable_big_core" + with_big_core=$enableval +else + if test "$cross_compiling" = yes; then + with_big_core=no +else + cat > conftest.$ac_ext < +#include +int main() { + unsigned long n = 6000000L; + char *s = malloc(n); + if (s != 0) + s[0] = s[n-1] = 0; + exit(s == 0); +} +EOF +if { (eval echo configure:3026: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + with_big_core=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + with_big_core=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$with_big_core" 1>&6 +test "$with_big_core" = "yes" && cat >> confdefs.h <<\EOF +#define HAVE_BIG_CORE 1 +EOF + + +### use option --enable-termcap to compile in the termcap fallback support +echo $ac_n "checking if you want termcap-fallback support""... $ac_c" 1>&6 +echo "configure:3048: checking if you want termcap-fallback support" >&5 + +# Check whether --enable-termcap or --disable-termcap was given. +if test "${enable_termcap+set}" = set; then + enableval="$enable_termcap" + with_termcap=$enableval +else + with_termcap=no +fi + +echo "$ac_t""$with_termcap" 1>&6 + +if test "$with_termcap" != "yes" ; then + cat >> confdefs.h <<\EOF +#define PURE_TERMINFO 1 +EOF + +else + +### use option --enable-getcap to use a hacked getcap for reading termcaps +echo $ac_n "checking if fast termcap-loader is needed""... $ac_c" 1>&6 +echo "configure:3069: checking if fast termcap-loader is needed" >&5 + +# Check whether --enable-getcap or --disable-getcap was given. +if test "${enable_getcap+set}" = set; then + enableval="$enable_getcap" + with_getcap=$enableval +else + with_getcap=no +fi + +echo "$ac_t""$with_getcap" 1>&6 +test "$with_getcap" = "yes" && cat >> confdefs.h <<\EOF +#define USE_GETCAP 1 +EOF + + +echo $ac_n "checking if translated termcaps will be cached in ~/.terminfo""... $ac_c" 1>&6 +echo "configure:3086: checking if translated termcaps will be cached in ~/.terminfo" >&5 + +# Check whether --enable-getcap-cache or --disable-getcap-cache was given. +if test "${enable_getcap_cache+set}" = set; then + enableval="$enable_getcap_cache" + with_getcap_cache=$enableval +else + with_getcap_cache=no +fi + +echo "$ac_t""$with_getcap_cache" 1>&6 +test "$with_getcap_cache" = "yes" && cat >> confdefs.h <<\EOF +#define USE_GETCAP_CACHE 1 +EOF + + +fi + +### Use option --enable-symlinks to make tic use symlinks, not hard links +### to reduce storage requirements for the terminfo database. + +for ac_func in \ + remove \ + unlink +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3112: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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(); + +int main() { + +/* 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 +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + +if test "$ac_cv_prog_cc_cross" = yes ; then + for ac_func in \ + link \ + symlink +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3171: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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(); + +int main() { + +/* 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 +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3199: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +else + echo $ac_n "checking if link/symlink functions work""... $ac_c" 1>&6 +echo "configure:3225: checking if link/symlink functions work" >&5 +if eval "test \"`echo '$''{'cf_cv_link_funcs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cf_cv_link_funcs= + for cf_func in link symlink ; do + if test "$cross_compiling" = yes; then + + eval 'ac_cv_func_'$cf_func'=error' +else + cat > conftest.$ac_ext < +#include +#ifdef HAVE_UNISTD_H +#include +#endif +int main() +{ + int fail = 0; + char *src = "config.log"; + char *dst = "conftest.chk"; + struct stat src_sb; + struct stat dst_sb; + + stat(src, &src_sb); + fail = ($cf_func("config.log", "conftest.chk") < 0) + || (stat(dst, &dst_sb) < 0) + || (dst_sb.st_mtime != src_sb.st_mtime); +#ifdef HAVE_UNLINK + unlink(dst); +#else + remove(dst); +#endif + exit (fail); +} + +EOF +if { (eval echo configure:3266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + + cf_cv_link_funcs="$cf_cv_link_funcs $cf_func" + eval 'ac_cv_func_'$cf_func'=yes' +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + + eval 'ac_cv_func_'$cf_func'=no' +fi +rm -fr conftest* +fi + + done + test -z "$cf_cv_link_funcs" && cf_cv_link_funcs=no + +fi + +echo "$ac_t""$cf_cv_link_funcs" 1>&6 + test "$ac_cv_func_link" = yes && cat >> confdefs.h <<\EOF +#define HAVE_LINK 1 +EOF + + test "$ac_cv_func_symlink" = yes && cat >> confdefs.h <<\EOF +#define HAVE_SYMLINK 1 +EOF + +fi + + +with_links=no +with_symlinks=no + +if test "$ac_cv_func_link" != yes ; then + echo $ac_n "checking if tic should use symbolic links""... $ac_c" 1>&6 +echo "configure:3303: checking if tic should use symbolic links" >&5 + if test "$ac_cv_func_symlink" = yes ; then + with_symlinks=yes + else + with_symlinks=no + fi + echo "$ac_t""$with_symlinks" 1>&6 +elif test "$ac_cv_func_symlink" != yes ; then + echo $ac_n "checking if tic should use hard links""... $ac_c" 1>&6 +echo "configure:3312: checking if tic should use hard links" >&5 + if test "$ac_cv_func_link" = yes ; then + with_links=yes + else + with_links=no + fi + echo "$ac_t""$with_links" 1>&6 +else + echo $ac_n "checking if tic should use symbolic links""... $ac_c" 1>&6 +echo "configure:3321: checking if tic should use symbolic links" >&5 + +# Check whether --enable-symlinks or --disable-symlinks was given. +if test "${enable_symlinks+set}" = set; then + enableval="$enable_symlinks" + with_symlinks=$enableval +else + with_symlinks=no +fi + + echo "$ac_t""$with_symlinks" 1>&6 +fi + +test "$with_links" = yes && cat >> confdefs.h <<\EOF +#define USE_LINKS 1 +EOF + +test "$with_symlinks" = yes && cat >> confdefs.h <<\EOF +#define USE_SYMLINKS 1 +EOF + + +### use option --enable-broken-linker to force on use of broken-linker support +echo $ac_n "checking if you want broken-linker support code""... $ac_c" 1>&6 +echo "configure:3345: checking if you want broken-linker support code" >&5 + +# Check whether --enable-broken_linker or --disable-broken_linker was given. +if test "${enable_broken_linker+set}" = set; then + enableval="$enable_broken_linker" + with_broken_linker=$enableval +else + with_broken_linker=$BROKEN_LINKER +fi + +echo "$ac_t""$with_broken_linker" 1>&6 +test "$with_broken_linker" = yes && cat >> confdefs.h <<\EOF +#define BROKEN_LINKER 1 +EOF + + +### use option --enable-bsdpad to have tputs process BSD-style prefix padding +echo $ac_n "checking if tputs should process BSD-style prefix padding""... $ac_c" 1>&6 +echo "configure:3363: checking if tputs should process BSD-style prefix padding" >&5 + +# Check whether --enable-bsdpad or --disable-bsdpad was given. +if test "${enable_bsdpad+set}" = set; then + enableval="$enable_bsdpad" + with_bsdpad=$enableval +else + with_bsdpad=no +fi + +echo "$ac_t""$with_bsdpad" 1>&6 +test "$with_bsdpad" = yes && cat >> confdefs.h <<\EOF +#define BSD_TPUTS 1 +EOF + + +### Enable compiling-in rcs id's +echo $ac_n "checking if RCS identifiers should be compiled-in""... $ac_c" 1>&6 +echo "configure:3381: checking if RCS identifiers should be compiled-in" >&5 + +# Check whether --with-rcs-ids or --without-rcs-ids was given. +if test "${with_rcs_ids+set}" = set; then + withval="$with_rcs_ids" + with_rcs_ids=$withval +else + with_rcs_ids=no +fi + +echo "$ac_t""$with_rcs_ids" 1>&6 +test "$with_rcs_ids" = yes && cat >> confdefs.h <<\EOF +#define USE_RCS_IDS 1 +EOF + + +############################################################################### + + + echo $ac_n "checking format of man-pages""... $ac_c" 1>&6 +echo "configure:3401: checking format of man-pages" >&5 + + +# Check whether --with-manpage-format or --without-manpage-format was given. +if test "${with_manpage_format+set}" = set; then + withval="$with_manpage_format" + cf_manpage_form=$withval +else + cf_manpage_form=unknown +fi + + +case ".$cf_manpage_form" in +.gzip|.compress|.BSDI|.normal|.formatted) # (vi + ;; +.unknown|.) # (vi + if test -z "$MANPATH" ; then + MANPATH="/usr/man:/usr/share/man" + fi + # look for the 'date' man-page (it's most likely to be installed!) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + cf_manpage_form=unknown + for cf_dir in $MANPATH; do + test -z "$cf_dir" && cf_dir=/usr/man + for cf_name in $cf_dir/*/date.[01]* $cf_dir/*/date + do + cf_test=`echo $cf_name | sed -e 's/*//'` + if test "x$cf_test" = "x$cf_name" ; then + case "$cf_name" in + *.gz) cf_manpage_form=gzip;; + *.Z) cf_manpage_form=compress;; + *.0) cf_manpage_form=BSDI,formatted;; + *) cf_manpage_form=normal;; + esac + break + fi + done + if test "$cf_manpage_form" != "unknown" ; then + break + fi + done + IFS="$ac_save_ifs" + ;; +.*) # (vi + echo "configure: warning: Unexpected manpage-format" 1>&2 + ;; +esac + +echo "$ac_t""$cf_manpage_form" 1>&6 + + +echo $ac_n "checking for manpage renaming""... $ac_c" 1>&6 +echo "configure:3453: checking for manpage renaming" >&5 + + +# Check whether --with-manpage-renames or --without-manpage-renames was given. +if test "${with_manpage_renames+set}" = set; then + withval="$with_manpage_renames" + cf_manpage_renames=$withval +else + cf_manpage_renames=yes +fi + + +case ".$cf_manpage_renames" in #(vi +.no) #(vi + ;; +.|.yes) + # Debian 'man' program? + if test -f /etc/debian_version ; then + cf_manpage_renames=`cd $srcdir && pwd`/man/man_db.renames + else + cf_manpage_renames=no + fi + ;; +esac + +if test "$cf_manpage_renames" != no ; then + if test ! -f $cf_manpage_renames ; then + { echo "configure: error: not a filename: $cf_manpage_renames" 1>&2; exit 1; } + fi + + test ! -d man && mkdir man + + # Construct a sed-script to perform renaming within man-pages + if test -n "$cf_manpage_renames" ; then + test ! -d man && mkdir man + $srcdir/man/make_sed.sh $cf_manpage_renames >man/edit_man.sed + fi +fi + +echo "$ac_t""$cf_manpage_renames" 1>&6 + + +echo $ac_n "checking for manpage symlinks""... $ac_c" 1>&6 +echo "configure:3496: checking for manpage symlinks" >&5 + + +# Check whether --with-manpage-symlinks or --without-manpage-symlinks was given. +if test "${with_manpage_symlinks+set}" = set; then + withval="$with_manpage_symlinks" + cf_manpage_symlinks=$withval +else + cf_manpage_symlinks=yes +fi + + +echo "$ac_t""$cf_manpage_symlinks" 1>&6 + + +echo $ac_n "checking for manpage tbl""... $ac_c" 1>&6 +echo "configure:3512: checking for manpage tbl" >&5 + + +# Check whether --with-manpage-tbl or --without-manpage-tbl was given. +if test "${with_manpage_tbl+set}" = set; then + withval="$with_manpage_tbl" + cf_manpage_tbl=$withval +else + cf_manpage_tbl=no +fi + + +echo "$ac_t""$cf_manpage_tbl" 1>&6 + + + if test "$prefix" = "NONE" ; then + cf_prefix="$ac_default_prefix" + else + cf_prefix="$prefix" + fi + + case "$cf_manpage_form" in # (vi + *formatted*) # (vi + cf_subdir='$mandir/cat' + cf_format=yes + ;; + *) + cf_subdir='$mandir/man' + cf_format=no + ;; + esac + +test ! -d man && mkdir man +cat >man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <\$TMP +CF_EOF +else +cat >>man/edit_man.sh <\$TMP +CF_EOF +fi +if test $cf_manpage_tbl = yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +if test $with_curses_h != yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +if test $cf_format = yes ; then +cat >>man/edit_man.sh <\$TMP.out + mv \$TMP.out \$TMP +CF_EOF +fi +case "$cf_manpage_form" in #(vi +*compress*) #(vi +cat >>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <>man/edit_man.sh <&6 +echo "configure:3751: checking if you want to build with function extensions" >&5 + +# Check whether --enable-ext-funcs or --disable-ext-funcs was given. +if test "${enable_ext_funcs+set}" = set; then + enableval="$enable_ext_funcs" + with_ext_funcs=$enableval +else + with_ext_funcs=yes +fi + +echo "$ac_t""$with_ext_funcs" 1>&6 +if test "$with_ext_funcs" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_CURSES_VERSION 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_HAS_KEY 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_RESIZETERM 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_USE_DEFAULT_COLORS 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_WRESIZE 1 +EOF + + cat >> confdefs.h <<\EOF +#define NCURSES_EXT_FUNCS 1 +EOF + +fi + +### use option --enable-const to turn on use of const beyond that in XSI. +echo $ac_n "checking for extended use of const keyword""... $ac_c" 1>&6 +echo "configure:3791: checking for extended use of const keyword" >&5 + +# Check whether --enable-const or --disable-const was given. +if test "${enable_const+set}" = set; then + enableval="$enable_const" + with_ext_const=$enableval +else + with_ext_const=no +fi + +echo "$ac_t""$with_ext_const" 1>&6 +NCURSES_CONST='/*nothing*/' +if test "$with_ext_const" = yes ; then + NCURSES_CONST=const +fi + + +echo $ac_n "checking if you want \$NCURSES_NO_PADDING code""... $ac_c" 1>&6 +echo "configure:3809: checking if you want \$NCURSES_NO_PADDING code" >&5 + +# Check whether --enable-no-padding or --disable-no-padding was given. +if test "${enable_no_padding+set}" = set; then + enableval="$enable_no_padding" + with_no_padding=$enableval +else + with_no_padding=$with_ext_funcs +fi + +echo "$ac_t""$with_no_padding" 1>&6 +test "$with_no_padding" = yes && cat >> confdefs.h <<\EOF +#define NCURSES_NO_PADDING 1 +EOF + + +### use option --enable-sigwinch to turn on use of SIGWINCH logic +echo $ac_n "checking if you want SIGWINCH handler""... $ac_c" 1>&6 +echo "configure:3827: checking if you want SIGWINCH handler" >&5 + +# Check whether --enable-sigwinch or --disable-sigwinch was given. +if test "${enable_sigwinch+set}" = set; then + enableval="$enable_sigwinch" + with_sigwinch=$enableval +else + with_sigwinch=$with_ext_funcs +fi + +echo "$ac_t""$with_sigwinch" 1>&6 +test "$with_sigwinch" = yes && cat >> confdefs.h <<\EOF +#define USE_SIGWINCH 1 +EOF + + +### use option --enable-tcap-names to allow user to define new capabilities +echo $ac_n "checking if you want user-definable terminal capabilities like termcap""... $ac_c" 1>&6 +echo "configure:3845: checking if you want user-definable terminal capabilities like termcap" >&5 + +# Check whether --enable-tcap-names or --disable-tcap-names was given. +if test "${enable_tcap_names+set}" = set; then + enableval="$enable_tcap_names" + with_tcap_names=$enableval +else + with_tcap_names=$with_ext_funcs +fi + +echo "$ac_t""$with_tcap_names" 1>&6 +NCURSES_XNAMES=0 +test "$with_tcap_names" = yes && NCURSES_XNAMES=1 + + +############################################################################### +# These options are relatively safe to experiment with. + +echo $ac_n "checking if you want all development code""... $ac_c" 1>&6 +echo "configure:3864: checking if you want all development code" >&5 + +# Check whether --with-develop or --without-develop was given. +if test "${with_develop+set}" = set; then + withval="$with_develop" + with_develop=$withval +else + with_develop=no +fi + +echo "$ac_t""$with_develop" 1>&6 + +### use option --enable-colorfgbg to turn on use of $COLORFGBG environment +echo $ac_n "checking if you want colorfgbg code""... $ac_c" 1>&6 +echo "configure:3878: checking if you want colorfgbg code" >&5 + +# Check whether --enable-hard-tabs or --disable-hard-tabs was given. +if test "${enable_hard_tabs+set}" = set; then + enableval="$enable_hard_tabs" + with_colorfgbg=$enableval +else + with_colorfgbg=$with_develop +fi + +echo "$ac_t""$with_colorfgbg" 1>&6 +test "$with_colorfgbg" = yes && cat >> confdefs.h <<\EOF +#define USE_COLORFGBG 1 +EOF + + +### use option --enable-hard-tabs to turn on use of hard-tabs optimize +echo $ac_n "checking if you want hard-tabs code""... $ac_c" 1>&6 +echo "configure:3896: checking if you want hard-tabs code" >&5 + +# Check whether --enable-hard-tabs or --disable-hard-tabs was given. +if test "${enable_hard_tabs+set}" = set; then + enableval="$enable_hard_tabs" + with_hardtabs=$enableval +else + with_hardtabs=$with_develop +fi + +echo "$ac_t""$with_hardtabs" 1>&6 +test "$with_hardtabs" = yes && cat >> confdefs.h <<\EOF +#define USE_HARD_TABS 1 +EOF + + +echo $ac_n "checking if you want to use restrict environment when running as root""... $ac_c" 1>&6 +echo "configure:3913: checking if you want to use restrict environment when running as root" >&5 + +# Check whether --enable-root-environ or --disable-root-environ was given. +if test "${enable_root_environ+set}" = set; then + enableval="$enable_root_environ" + with_root_environ=$enableval +else + with_root_environ=yes +fi + +echo "$ac_t""$with_root_environ" 1>&6 +test "$with_root_environ" = yes && cat >> confdefs.h <<\EOF +#define USE_ROOT_ENVIRON 1 +EOF + + +### use option --enable-xmc-glitch to turn on use of magic-cookie optimize +echo $ac_n "checking if you want limited support for xmc""... $ac_c" 1>&6 +echo "configure:3931: checking if you want limited support for xmc" >&5 + +# Check whether --enable-xmc-glitch or --disable-xmc-glitch was given. +if test "${enable_xmc_glitch+set}" = set; then + enableval="$enable_xmc_glitch" + with_xmc_glitch=$enableval +else + with_xmc_glitch=$with_develop +fi + +echo "$ac_t""$with_xmc_glitch" 1>&6 +test "$with_xmc_glitch" = yes && cat >> confdefs.h <<\EOF +#define USE_XMC_SUPPORT 1 +EOF + + +############################################################################### +# These are just experimental, probably should not be in a package: + + +echo $ac_n "checking if you do not want to assume colors are white-on-black""... $ac_c" 1>&6 +echo "configure:3952: checking if you do not want to assume colors are white-on-black" >&5 + +# Check whether --enable-assumed-color or --disable-assumed-color was given. +if test "${enable_assumed_color+set}" = set; then + enableval="$enable_assumed_color" + with_assumed_color=$enableval +else + with_assumed_color=yes +fi + +echo "$ac_t""$with_assumed_color" 1>&6 +test "$with_assumed_color" = yes && cat >> confdefs.h <<\EOF +#define USE_ASSUMED_COLOR 1 +EOF + + +### use option --enable-hashmap to turn on use of hashmap scrolling logic +echo $ac_n "checking if you want hashmap scrolling-optimization code""... $ac_c" 1>&6 +echo "configure:3970: checking if you want hashmap scrolling-optimization code" >&5 + +# Check whether --enable-hashmap or --disable-hashmap was given. +if test "${enable_hashmap+set}" = set; then + enableval="$enable_hashmap" + with_hashmap=$enableval +else + with_hashmap=yes +fi + +echo "$ac_t""$with_hashmap" 1>&6 +test "$with_hashmap" = yes && cat >> confdefs.h <<\EOF +#define USE_HASHMAP 1 +EOF + + +echo $ac_n "checking if you want experimental safe-sprintf code""... $ac_c" 1>&6 +echo "configure:3987: checking if you want experimental safe-sprintf code" >&5 + +# Check whether --enable-safe-sprintf or --disable-safe-sprintf was given. +if test "${enable_safe_sprintf+set}" = set; then + enableval="$enable_safe_sprintf" + with_safe_sprintf=$enableval +else + with_safe_sprintf=no +fi + +echo "$ac_t""$with_safe_sprintf" 1>&6 +test "$with_safe_sprintf" = yes && cat >> confdefs.h <<\EOF +#define USE_SAFE_SPRINTF 1 +EOF + + +### use option --disable-scroll-hints to turn off use of scroll-hints scrolling logic +# when hashmap is used scroll hints are useless +if test "$with_hashmap" = no ; then +echo $ac_n "checking if you want to experiment without scrolling-hints code""... $ac_c" 1>&6 +echo "configure:4007: checking if you want to experiment without scrolling-hints code" >&5 + +# Check whether --enable-scroll-hints or --disable-scroll-hints was given. +if test "${enable_scroll_hints+set}" = set; then + enableval="$enable_scroll_hints" + with_scroll_hints=$enableval +else + with_scroll_hints=yes +fi + +echo "$ac_t""$with_scroll_hints" 1>&6 +test "$with_scroll_hints" = yes && cat >> confdefs.h <<\EOF +#define USE_SCROLL_HINTS 1 +EOF + +fi + +### use option --enable-widec to turn on use of wide-character support +echo $ac_n "checking if you want experimental wide-character code""... $ac_c" 1>&6 +echo "configure:4026: checking if you want experimental wide-character code" >&5 + +# Check whether --enable-widec or --disable-widec was given. +if test "${enable_widec+set}" = set; then + enableval="$enable_widec" + with_widec=$enableval +else + with_widec=no +fi + +echo "$ac_t""$with_widec" 1>&6 +if test "$with_widec" = yes ; then + LIB_SUFFIX="w${LIB_SUFFIX}" + cat >> confdefs.h <<\EOF +#define USE_WIDEC_SUPPORT 1 +EOF + +fi + +############################################################################### + + +### use option --disable-echo to suppress full display compiling commands +echo $ac_n "checking if you want to display full commands during build""... $ac_c" 1>&6 +echo "configure:4050: checking if you want to display full commands during build" >&5 + +# Check whether --enable-echo or --disable-echo was given. +if test "${enable_echo+set}" = set; then + enableval="$enable_echo" + with_echo=$enableval +else + with_echo=yes +fi + +if test "$with_echo" = yes; then + ECHO_LINK= +else + ECHO_LINK='@ echo linking $@ ... ;' + test -n "$LIBTOOL" && LIBTOOL="$LIBTOOL --silent" +fi +echo "$ac_t""$with_echo" 1>&6 + + +### use option --enable-warnings to turn on all gcc warnings +echo $ac_n "checking if you want to see compiler warnings""... $ac_c" 1>&6 +echo "configure:4071: checking if you want to see compiler warnings" >&5 + +# Check whether --enable-warnings or --disable-warnings was given. +if test "${enable_warnings+set}" = set; then + enableval="$enable_warnings" + with_warnings=$enableval +fi + +echo "$ac_t""$with_warnings" 1>&6 + +if test -n "$with_warnings"; then + ADAFLAGS="$ADAFLAGS -gnatg" + +if test "$GCC" = yes +then + cat > conftest.$ac_ext <&6 +echo "configure:4091: checking for $CC warning options" >&5 + cf_save_CFLAGS="$CFLAGS" + EXTRA_CFLAGS="-W -Wall" + cf_warn_CONST="" + test "$with_ext_const" = yes && cf_warn_CONST="Wwrite-strings" + for cf_opt in \ + Wbad-function-cast \ + Wcast-align \ + Wcast-qual \ + Winline \ + Wmissing-declarations \ + Wmissing-prototypes \ + Wnested-externs \ + Wpointer-arith \ + Wshadow \ + Wstrict-prototypes $cf_warn_CONST + do + CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt" + if { (eval echo configure:4109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + test -n "$verbose" && echo "$ac_t""... -$cf_opt" 1>&6 + EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt" + test "$cf_opt" = Wcast-qual && EXTRA_CFLAGS="$EXTRA_CFLAGS -DXTSTRINGDEFINES" + fi + done + rm -f conftest* + CFLAGS="$cf_save_CFLAGS" +fi + + +fi + +if test "$GCC" = yes +then +cat > conftest.i <&6 +echo "configure:4141: checking for $CC __attribute__ directives" >&5 + cat > conftest.$ac_ext <&5 + case $cf_attribute in + scanf|printf) + cat >conftest.h <conftest.h <&5; (eval $ac_compile) 2>&5; }; then + test -n "$verbose" && echo "$ac_t""... $cf_attribute" 1>&6 + cat conftest.h >>confdefs.h +# else +# sed -e 's/__attr.*/\/*nothing*\//' conftest.h >>confdefs.h + fi + done +else + fgrep define conftest.i >>confdefs.h +fi +rm -rf conftest* +fi + + +### use option --enable-assertions to turn on generation of assertion code +echo $ac_n "checking if you want to enable runtime assertions""... $ac_c" 1>&6 +echo "configure:4197: checking if you want to enable runtime assertions" >&5 + +# Check whether --enable-assertions or --disable-assertions was given. +if test "${enable_assertions+set}" = set; then + enableval="$enable_assertions" + with_assertions=$enableval +else + with_assertions=no +fi + +echo "$ac_t""$with_assertions" 1>&6 +if test -n "$GCC" +then + if test "$with_assertions" = no + then + cat >> confdefs.h <<\EOF +#define NDEBUG 1 +EOF + + CPPFLAGS="$CPPFLAGS -DNDEBUG" + else + ADAFLAGS="$ADAFLAGS -gnata" + fi +fi + +### use option --disable-leaks to suppress "permanent" leaks, for testing + +# Check whether --enable-leaks or --disable-leaks was given. +if test "${enable_leaks+set}" = set; then + enableval="$enable_leaks" + test "$enableval" = no && cat >> confdefs.h <<\EOF +#define NO_LEAKS 1 +EOF + +fi + +cat >> confdefs.h <<\EOF +#define HAVE_NC_ALLOC_H 1 +EOF + + +### use option --enable-expanded to generate certain macros as functions + +# Check whether --enable-expanded or --disable-expanded was given. +if test "${enable_expanded+set}" = set; then + enableval="$enable_expanded" + test "$enableval" = yes && cat >> confdefs.h <<\EOF +#define NCURSES_EXPANDED 1 +EOF + +fi + + +### use option --disable-macros to suppress macros in favor of functions + +# Check whether --enable-macros or --disable-macros was given. +if test "${enable_macros+set}" = set; then + enableval="$enable_macros" + test "$enableval" = no && cat >> confdefs.h <<\EOF +#define NCURSES_NOMACROS 1 +EOF + +fi + + +### Checks for libraries. +echo $ac_n "checking for gettimeofday""... $ac_c" 1>&6 +echo "configure:4264: checking for gettimeofday" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gettimeofday'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gettimeofday(); + +int main() { + +/* 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_gettimeofday) || defined (__stub___gettimeofday) +choke me +#else +gettimeofday(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4292: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gettimeofday=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gettimeofday=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gettimeofday`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETTIMEOFDAY 1 +EOF + +else + echo "$ac_t""no" 1>&6 + + +echo $ac_n "checking for gettimeofday in -lbsd""... $ac_c" 1>&6 +echo "configure:4315: checking for gettimeofday in -lbsd" >&5 +ac_lib_var=`echo bsd'_'gettimeofday | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbsd $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GETTIMEOFDAY 1 +EOF + + LIBS="$LIBS -lbsd" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +echo $ac_n "checking if -lm needed for math functions""... $ac_c" 1>&6 +echo "configure:4362: checking if -lm needed for math functions" >&5 +if eval "test \"`echo '$''{'cf_cv_need_libm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < + #include + +int main() { +double x = rand(); printf("result = %g\n", sin(x)) +; return 0; } +EOF +if { (eval echo configure:4378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_need_libm=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_need_libm=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$cf_cv_need_libm" 1>&6 +if test "$cf_cv_need_libm" = yes +then +MATH_LIB=-lm +fi + + + +### Checks for header files. +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:4400: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4413: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + 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 < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + 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 < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#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); } + +EOF +if { (eval echo configure:4480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 +echo "configure:4508: checking for $ac_hdr that defines DIR" >&5 +if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include <$ac_hdr> +int main() { +DIR *dirp = 0; +; return 0; } +EOF +if { (eval echo configure:4521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_dirent_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then +echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 +echo "configure:4546: checking for opendir in -ldir" >&5 +ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldir $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -ldir" +else + echo "$ac_t""no" 1>&6 +fi + +else +echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 +echo "configure:4587: checking for opendir in -lx" >&5 +ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lx $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lx" +else + echo "$ac_t""no" 1>&6 +fi + +fi + + +echo $ac_n "checking for regular-expression headers""... $ac_c" 1>&6 +echo "configure:4630: checking for regular-expression headers" >&5 +if eval "test \"`echo '$''{'cf_cv_regex'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +#include +int main() { + + regex_t *p; + int x = regcomp(p, "", 0); + int y = regexec(p, "", 0, 0, 0); + regfree(p); + +; return 0; } +EOF +if { (eval echo configure:4649: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_regex="regex.h" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cat > conftest.$ac_ext < +int main() { + + char *p = compile("", "", "", 0); + int x = step("", ""); + +; return 0; } +EOF +if { (eval echo configure:4668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_regex="regexp.h" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cf_save_LIBS="$LIBS" + LIBS="-lgen $LIBS" + cat > conftest.$ac_ext < +int main() { + + char *p = compile("", "", ""); + int x = step("", ""); + +; return 0; } +EOF +if { (eval echo configure:4689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_regex="regexpr.h" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + LIBS="$cf_save_LIBS" +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + +fi + +echo "$ac_t""$cf_cv_regex" 1>&6 +case $cf_cv_regex in + regex.h) cat >> confdefs.h <<\EOF +#define HAVE_REGEX_H_FUNCS 1 +EOF + ;; + regexp.h) cat >> confdefs.h <<\EOF +#define HAVE_REGEXP_H_FUNCS 1 +EOF + ;; + regexpr.h) cat >> confdefs.h <<\EOF +#define HAVE_REGEXPR_H_FUNCS 1 +EOF + ;; +esac + + +for ac_hdr in \ +fcntl.h \ +getopt.h \ +libc.h \ +limits.h \ +locale.h \ +poll.h \ +sys/bsdtypes.h \ +sys/ioctl.h \ +sys/param.h \ +sys/poll.h \ +sys/select.h \ +sys/time.h \ +sys/times.h \ +ttyent.h \ +unistd.h \ + +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:4743: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:4753: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +# check for ISC (this may also define _POSIX_SOURCE) +# Note: even non-Posix ISC needs to declare fd_set +if test "$ISC" = yes ; then + echo $ac_n "checking for main in -lcposix""... $ac_c" 1>&6 +echo "configure:4784: checking for main in -lcposix" >&5 +ac_lib_var=`echo cposix'_'main | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcposix $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo cposix | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + echo $ac_n "checking for bzero in -linet""... $ac_c" 1>&6 +echo "configure:4827: checking for bzero in -linet" >&5 +ac_lib_var=`echo inet'_'bzero | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-linet $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -linet" +else + echo "$ac_t""no" 1>&6 +fi +fi + + +echo $ac_n "checking if sys/time.h works with sys/select.h""... $ac_c" 1>&6 +echo "configure:4869: checking if sys/time.h works with sys/select.h" >&5 +if eval "test \"`echo '$''{'cf_cv_sys_time_select'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +int main() { + +; return 0; } +EOF +if { (eval echo configure:4890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_sys_time_select=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_sys_time_select=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$cf_cv_sys_time_select" 1>&6 +test "$cf_cv_sys_time_select" = yes && cat >> confdefs.h <<\EOF +#define HAVE_SYS_TIME_SELECT 1 +EOF + + + +### checks for compiler characteristics +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:4919: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:4973: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:4994: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <> confdefs.h <<\EOF +#define CC_HAS_INLINE_FUNCS 1 +EOF + + + +echo $ac_n "checking if unsigned literals are legal""... $ac_c" 1>&6 +echo "configure:5040: checking if unsigned literals are legal" >&5 +if eval "test \"`echo '$''{'cf_cv_unsigned_literals'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_unsigned_literals=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_unsigned_literals=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$cf_cv_unsigned_literals" 1>&6 + + + +echo $ac_n "checking for type of chtype""... $ac_c" 1>&6 +echo "configure:5071: checking for type of chtype" >&5 +if eval "test \"`echo '$''{'cf_cv_typeof_chtype'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$cross_compiling" = yes; then + cf_cv_typeof_chtype=long +else + cat > conftest.$ac_ext < /* we want wchar_t */ +#define WANT_BITS 39 +#else +#define WANT_BITS 31 +#endif +#include +int main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + char *result = "long"; +#ifdef USE_WIDEC_SUPPORT + /* + * If wchar_t is smaller than a long, it must be an int or a + * short. We prefer not to use a short anyway. + */ + if (sizeof(unsigned long) > sizeof(wchar_t)) + result = "int"; +#endif + if (sizeof(unsigned long) > sizeof(unsigned int)) { + int n; + unsigned int x; + for (n = 0; n < WANT_BITS; n++) { + unsigned int y = (x >> n); + if (y != 1 || x == 0) { + x = 0; + break; + } + } + /* + * If x is nonzero, an int is big enough for the bits + * that we want. + */ + result = (x != 0) ? "int" : "long"; + } + fputs(result, fp); + fclose(fp); + } + exit(0); +} + +EOF +if { (eval echo configure:5126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_typeof_chtype=`cat cf_test.out` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_typeof_chtype=long +fi +rm -fr conftest* +fi + + rm -f cf_test.out + +fi + +echo "$ac_t""$cf_cv_typeof_chtype" 1>&6 + + +cat >> confdefs.h <&6 +echo "configure:5159: checking for number of bits in chtype" >&5 +if eval "test \"`echo '$''{'cf_cv_shift_limit'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$cross_compiling" = yes; then + cf_cv_shift_limit=32 +else + cat > conftest.$ac_ext < +int main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + int n; + unsigned TYPEOF_CHTYPE x = 1L; + for (n = 0; ; n++) { + unsigned long y = (x >> n); + if (y != 1 || x == 0) + break; + x <<= 1; + } + fprintf(fp, "%d", n); + fclose(fp); + } + exit(0); +} + +EOF +if { (eval echo configure:5191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_shift_limit=`cat cf_test.out` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_shift_limit=32 +fi +rm -fr conftest* +fi + + rm -f cf_test.out + +fi + +echo "$ac_t""$cf_cv_shift_limit" 1>&6 + + +echo $ac_n "checking for width of character-index""... $ac_c" 1>&6 +echo "configure:5211: checking for width of character-index" >&5 +if eval "test \"`echo '$''{'cf_cv_widec_shift'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +if test ".$with_widec" = ".yes" ; then + cf_attrs_width=39 + if ( expr $cf_cv_shift_limit \> $cf_attrs_width >/dev/null ) + then + cf_cv_widec_shift=`expr 16 + $cf_cv_shift_limit - $cf_attrs_width` + else + cf_cv_widec_shift=16 + fi +else + cf_cv_widec_shift=8 +fi + +fi + +echo "$ac_t""$cf_cv_widec_shift" 1>&6 + + + +### Checks for external-data + + +echo $ac_n "checking if external errno is declared""... $ac_c" 1>&6 +echo "configure:5238: checking if external errno is declared" >&5 +if eval "test \"`echo '$''{'cf_cv_dcl_errno'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#endif +#include +#include +#include +int main() { +long x = (long) errno +; return 0; } +EOF +if { (eval echo configure:5257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval 'cf_cv_dcl_'errno'=yes' +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval 'cf_cv_dcl_'errno'=no' +fi +rm -f conftest* + +fi + + +eval 'cf_result=$cf_cv_dcl_'errno +echo "$ac_t""$cf_result" 1>&6 + +if test "$cf_result" = no ; then + eval 'cf_result=DECL_'errno + +cf_result=`echo "$cf_result" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + cat >> confdefs.h <&6 +echo "configure:5288: checking if external errno exists" >&5 +if eval "test \"`echo '$''{'cf_cv_have_errno'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval 'cf_cv_have_'errno'=yes' +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval 'cf_cv_have_'errno'=no' +fi +rm -f conftest* +fi + + +eval 'cf_result=$cf_cv_have_'errno +echo "$ac_t""$cf_result" 1>&6 + +if test "$cf_result" = yes ; then + eval 'cf_result=HAVE_'errno + +cf_result=`echo "$cf_result" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + cat >> confdefs.h <&6 +echo "configure:5336: checking if data-only library module links" >&5 +if eval "test \"`echo '$''{'cf_cv_link_dataonly'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + rm -f conftest.a + cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; } ; then + mv conftest.o data.o && \ + ( $AR $AR_OPTS conftest.a data.o ) 2>&5 1>/dev/null + fi + rm -f conftest.$ac_ext data.o + cat >conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + mv conftest.o func.o && \ + ( $AR $AR_OPTS conftest.a func.o ) 2>&5 1>/dev/null + fi + rm -f conftest.$ac_ext func.o + ( eval $ac_cv_prog_RANLIB conftest.a ) 2>&5 >/dev/null + cf_saveLIBS="$LIBS" + LIBS="conftest.a $LIBS" + if test "$cross_compiling" = yes; then + cf_cv_link_dataonly=unknown +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_link_dataonly=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_link_dataonly=no +fi +rm -fr conftest* +fi + + LIBS="$cf_saveLIBS" + +fi + +echo "$ac_t""$cf_cv_link_dataonly" 1>&6 +test "$cf_cv_link_dataonly" = no && cat >> confdefs.h <<\EOF +#define BROKEN_LINKER 1 +EOF + + + +### Checks for library functions. +for ac_func in \ +getcwd \ +getegid \ +geteuid \ +getttynam \ +issetugid \ +memccpy \ +mkstemp \ +nanosleep \ +poll \ +remove \ +select \ +setbuf \ +setbuffer \ +setvbuf \ +sigaction \ +sigvec \ +strdup \ +strstr \ +tcgetpgrp \ +times \ +vfscanf \ +vsnprintf \ +vsscanf \ + +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:5438: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* 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(); + +int main() { + +/* 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 +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:5466: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +if test "$with_getcap" = "yes" ; then + +echo $ac_n "checking for terminal-capability database functions""... $ac_c" 1>&6 +echo "configure:5493: checking for terminal-capability database functions" >&5 +if eval "test \"`echo '$''{'cf_cv_cgetent'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +int main() { + + char temp[128]; + char *buf = temp; + char *db_array = temp; + cgetent(&buf, /* int *, */ &db_array, "vt100"); + cgetcap(buf, "tc", '='); + cgetmatch(buf, "tc"); + +; return 0; } +EOF +if { (eval echo configure:5514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_cgetent=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_cgetent=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$cf_cv_cgetent" 1>&6 +test "$cf_cv_cgetent" = yes && cat >> confdefs.h <<\EOF +#define HAVE_BSD_CGETENT 1 +EOF + + +fi + + +echo $ac_n "checking for isascii""... $ac_c" 1>&6 +echo "configure:5537: checking for isascii" >&5 +if eval "test \"`echo '$''{'cf_cv_have_isascii'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +int x = isascii(' ') +; return 0; } +EOF +if { (eval echo configure:5550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_have_isascii=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_have_isascii=no +fi +rm -f conftest* + +fi +echo "$ac_t""$cf_cv_have_isascii" 1>&6 +test "$cf_cv_have_isascii" = yes && cat >> confdefs.h <<\EOF +#define HAVE_ISASCII 1 +EOF + + + +if test "$ac_cv_func_sigaction" = yes; then +echo $ac_n "checking whether sigaction needs _POSIX_SOURCE""... $ac_c" 1>&6 +echo "configure:5571: checking whether sigaction needs _POSIX_SOURCE" >&5 +cat > conftest.$ac_ext < +#include +int main() { +struct sigaction act +; return 0; } +EOF +if { (eval echo configure:5582: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sigact_bad=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + +cat > conftest.$ac_ext < +#include +int main() { +struct sigaction act +; return 0; } +EOF +if { (eval echo configure:5601: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + sigact_bad=yes + cat >> confdefs.h <<\EOF +#define SVR4_ACTION 1 +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + sigact_bad=unknown +fi +rm -f conftest* +fi +rm -f conftest* +echo "$ac_t""$sigact_bad" 1>&6 +fi + + +for ac_hdr in \ +termio.h \ +termios.h \ +unistd.h \ + +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:5629: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +if test "$ISC" = yes ; then + for ac_hdr in sys/termio.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:5670: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:5680: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +fi +if test "$ac_cv_header_termios_h" = yes ; then + case "$CFLAGS" in + *-D_POSIX_SOURCE*) + termios_bad=dunno ;; + *) termios_bad=maybe ;; + esac + if test "$termios_bad" = maybe ; then + echo $ac_n "checking whether termios.h needs _POSIX_SOURCE""... $ac_c" 1>&6 +echo "configure:5715: checking whether termios.h needs _POSIX_SOURCE" >&5 + cat > conftest.$ac_ext < +int main() { +struct termios foo; int x = foo.c_iflag +; return 0; } +EOF +if { (eval echo configure:5724: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + termios_bad=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + cat > conftest.$ac_ext < +int main() { +struct termios foo; int x = foo.c_iflag +; return 0; } +EOF +if { (eval echo configure:5742: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + termios_bad=unknown +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + termios_bad=yes cat >> confdefs.h <<\EOF +#define SVR4_TERMIO 1 +EOF + +fi +rm -f conftest* + +fi +rm -f conftest* + echo "$ac_t""$termios_bad" 1>&6 + fi +fi + + + +echo $ac_n "checking for tcgetattr""... $ac_c" 1>&6 +echo "configure:5765: checking for tcgetattr" >&5 +if eval "test \"`echo '$''{'cf_cv_have_tcgetattr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_TERMIOS_H +#include +#define TTY struct termios +#else +#ifdef HAVE_TERMIO_H +#include +#define TTY struct termio +#endif +#endif + +int main() { + +TTY foo; +tcgetattr(1, &foo); +; return 0; } +EOF +if { (eval echo configure:5794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_have_tcgetattr=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_have_tcgetattr=no +fi +rm -f conftest* +fi + +echo "$ac_t""$cf_cv_have_tcgetattr" 1>&6 +test "$cf_cv_have_tcgetattr" = yes && cat >> confdefs.h <<\EOF +#define HAVE_TCGETATTR 1 +EOF + + + +if test "$cross_compiling" = yes ; then + echo "configure: warning: cross compiling: assume setvbuf params not reversed" 1>&2 +else + echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6 +echo "configure:5817: checking whether setvbuf arguments are reversed" >&5 +if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +/* If setvbuf has the reversed format, exit 0. */ +main () { + /* This call has the arguments reversed. + A reversed system may check and see that the address of main + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0) + exit(1); + putc('\r', stdout); + exit(0); /* Non-reversed systems segv here. */ +} +EOF +if { (eval echo configure:5839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_setvbuf_reversed=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_setvbuf_reversed=no +fi +rm -fr conftest* +fi + +rm -f core core.* *.core +fi + +echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6 +if test $ac_cv_func_setvbuf_reversed = yes; then + cat >> confdefs.h <<\EOF +#define SETVBUF_REVERSED 1 +EOF + +fi + +fi +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:5864: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:5886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <&6 +echo "configure:5906: checking for type sigaction_t" >&5 +if eval "test \"`echo '$''{'cf_cv_type_sigaction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +int main() { +sigaction_t x +; return 0; } +EOF +if { (eval echo configure:5920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_type_sigaction=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_type_sigaction=no +fi +rm -f conftest* +fi + +echo "$ac_t""$cf_cv_type_sigaction" 1>&6 +test "$cf_cv_type_sigaction" = yes && cat >> confdefs.h <<\EOF +#define HAVE_TYPE_SIGACTION 1 +EOF + + + + +echo $ac_n "checking declaration of size-change""... $ac_c" 1>&6 +echo "configure:5941: checking declaration of size-change" >&5 +if eval "test \"`echo '$''{'cf_cv_sizechange'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cf_cv_sizechange=unknown + cf_save_CFLAGS="$CFLAGS" + +for cf_opts in "" "NEED_PTEM_H" +do + + CFLAGS="$cf_save_CFLAGS" + test -n "$cf_opts" && CFLAGS="$CFLAGS -D$cf_opts" + cat > conftest.$ac_ext < +#ifdef HAVE_TERMIOS_H +#include +#else +#ifdef HAVE_TERMIO_H +#include +#endif +#endif +#ifdef NEED_PTEM_H +/* This is a workaround for SCO: they neglected to define struct winsize in + * termios.h -- it's only in termio.h and ptem.h + */ +#include +#include +#endif +#if !defined(sun) || !defined(HAVE_TERMIOS_H) +#include +#endif + +int main() { + +#ifdef TIOCGSIZE + struct ttysize win; /* FIXME: what system is this? */ + int y = win.ts_lines; + int x = win.ts_cols; +#else +#ifdef TIOCGWINSZ + struct winsize win; + int y = win.ws_row; + int x = win.ws_col; +#else + no TIOCGSIZE or TIOCGWINSZ +#endif /* TIOCGWINSZ */ +#endif /* TIOCGSIZE */ + +; return 0; } +EOF +if { (eval echo configure:5994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_sizechange=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_sizechange=no +fi +rm -f conftest* + + CFLAGS="$cf_save_CFLAGS" + if test "$cf_cv_sizechange" = yes ; then + echo "size-change succeeded ($cf_opts)" >&5 + test -n "$cf_opts" && cf_cv_sizechange="$cf_opts" + break + fi +done + +fi + +echo "$ac_t""$cf_cv_sizechange" 1>&6 +if test "$cf_cv_sizechange" != no ; then + cat >> confdefs.h <<\EOF +#define HAVE_SIZECHANGE 1 +EOF + + case $cf_cv_sizechange in #(vi + NEED*) + cat >> confdefs.h <&6 +echo "configure:6033: checking for memmove" >&5 +if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char memmove(); + +int main() { + +/* 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_memmove) || defined (__stub___memmove) +choke me +#else +memmove(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_memmove=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_memmove=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + +echo $ac_n "checking for bcopy""... $ac_c" 1>&6 +echo "configure:6080: checking for bcopy" >&5 +if eval "test \"`echo '$''{'ac_cv_func_bcopy'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bcopy(); + +int main() { + +/* 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_bcopy) || defined (__stub___bcopy) +choke me +#else +bcopy(); +#endif + +; return 0; } +EOF +if { (eval echo configure:6108: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_bcopy=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_bcopy=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'bcopy`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + echo $ac_n "checking if bcopy does overlapping moves""... $ac_c" 1>&6 +echo "configure:6124: checking if bcopy does overlapping moves" >&5 +if eval "test \"`echo '$''{'cf_cv_good_bcopy'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + if test "$cross_compiling" = yes; then + cf_cv_good_bcopy=unknown +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_good_bcopy=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_good_bcopy=no +fi +rm -fr conftest* +fi + + +fi + +echo "$ac_t""$cf_cv_good_bcopy" 1>&6 + +else + echo "$ac_t""no" 1>&6 +cf_cv_good_bcopy=no +fi + + if test "$cf_cv_good_bcopy" = yes ; then + cat >> confdefs.h <<\EOF +#define USE_OK_BCOPY 1 +EOF + + else + cat >> confdefs.h <<\EOF +#define USE_MY_MEMMOVE 1 +EOF + + fi + +fi + + +echo $ac_n "checking if poll really works""... $ac_c" 1>&6 +echo "configure:6184: checking if poll really works" >&5 +if eval "test \"`echo '$''{'cf_cv_working_poll'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +if test "$cross_compiling" = yes; then + cf_cv_working_poll=unknown +else + cat > conftest.$ac_ext < +#ifdef HAVE_POLL_H +#include +#else +#include +#endif +int main() { + struct pollfd myfds; + int ret; + + myfds.fd = 0; + myfds.events = POLLIN; + + ret = poll(&myfds, 1, 100); + exit(ret != 0); +} +EOF +if { (eval echo configure:6213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_working_poll=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_working_poll=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$cf_cv_working_poll" 1>&6 +test "$cf_cv_working_poll" = "yes" && cat >> confdefs.h <<\EOF +#define HAVE_WORKING_POLL 1 +EOF + + + +if test -z "$cf_user_CFLAGS" ; then + CFLAGS=`echo ${CFLAGS} | sed -e 's/-g //' -e 's/-g$//'` + CXXFLAGS=`echo ${CXXFLAGS} | sed -e 's/-g //' -e 's/-g$//'` +fi + + +echo $ac_n "checking for builtin bool type""... $ac_c" 1>&6 +echo "configure:6241: checking for builtin bool type" >&5 +if eval "test \"`echo '$''{'cf_cv_cc_bool_type'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { +bool x = false +; return 0; } +EOF +if { (eval echo configure:6257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_cc_bool_type=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_cc_bool_type=0 +fi +rm -f conftest* + +fi + +if test "$cf_cv_cc_bool_type" = 1 +then echo "$ac_t""yes" 1>&6 +else echo "$ac_t""no" 1>&6 +fi + +if test -n "$CXX" ; then + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + + +if test -n "$GXX" ; then +case $cf_cv_system_name in #(vi +os2*) #(vi + cf_stdcpp_libname=stdcpp + ;; +*) + cf_stdcpp_libname=stdc++ + ;; +esac +echo $ac_n "checking for library $cf_stdcpp_libname""... $ac_c" 1>&6 +echo "configure:6294: checking for library $cf_stdcpp_libname" >&5 +if eval "test \"`echo '$''{'cf_cv_libstdcpp'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cf_save="$LIBS" + LIBS="$LIBS -l$cf_stdcpp_libname" +cat > conftest.$ac_ext < +int main() { + +char buf[80]; +strstreambuf foo(buf, sizeof(buf)) + +; return 0; } +EOF +if { (eval echo configure:6313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_libstdcpp=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_libstdcpp=no +fi +rm -f conftest* + LIBS="$cf_save" + +fi + +echo "$ac_t""$cf_cv_libstdcpp" 1>&6 +test "$cf_cv_libstdcpp" = yes && CXXLIBS="$CXXLIBS -l$cf_stdcpp_libname" +fi + + if test "$GXX" = yes; then + case "`${CXX-g++} --version`" in + 1*|2.0-6*) + cf_cxx_library=yes + ;; + 2.7*) + +cf_cxx_library=unknown +case $cf_cv_system_name in #(vi +os2*) #(vi + cf_gpp_libname=gpp + ;; +*) + cf_gpp_libname=g++ + ;; +esac +if test "$ac_cv_prog_gxx" = yes; then + echo $ac_n "checking for lib$cf_gpp_libname""... $ac_c" 1>&6 +echo "configure:6349: checking for lib$cf_gpp_libname" >&5 + cf_save="$LIBS" + LIBS="$LIBS -l$cf_gpp_libname" + cat > conftest.$ac_ext < + +int main() { +two_arg_error_handler_t foo2 = lib_error_handler +; return 0; } +EOF +if { (eval echo configure:6362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cxx_library=yes + CXXLIBS="$CXXLIBS -l$cf_gpp_libname" + if test "$cf_gpp_libname" = cpp ; then + cat >> confdefs.h <<\EOF +#define HAVE_GPP_BUILTIN_H 1 +EOF + + else + cat >> confdefs.h <<\EOF +#define HAVE_GXX_BUILTIN_H 1 +EOF + + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cat > conftest.$ac_ext < + +int main() { +two_arg_error_handler_t foo2 = lib_error_handler +; return 0; } +EOF +if { (eval echo configure:6391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cxx_library=yes + CXXLIBS="$CXXLIBS -l$cf_gpp_libname" + cat >> confdefs.h <<\EOF +#define HAVE_BUILTIN_H 1 +EOF + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cxx_library=no +fi +rm -f conftest* +fi +rm -f conftest* + LIBS="$cf_save" + echo "$ac_t""$cf_cxx_library" 1>&6 +fi + + ;; + *) + cf_cxx_library=no + ;; + esac + else + cf_cxx_library=no + fi + echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 +echo "configure:6421: checking how to run the C++ preprocessor" >&5 +if test -z "$CXXCPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + CXXCPP="${CXX-g++} -E" + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6439: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CXXCPP=/lib/cpp +fi +rm -f conftest* + ac_cv_prog_CXXCPP="$CXXCPP" +ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross +fi +fi +CXXCPP="$ac_cv_prog_CXXCPP" +echo "$ac_t""$CXXCPP" 1>&6 + +for ac_hdr in typeinfo +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:6467: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6477: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for builtin bool type""... $ac_c" 1>&6 +echo "configure:6505: checking for builtin bool type" >&5 +if eval "test \"`echo '$''{'cf_cv_builtin_bool'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cat > conftest.$ac_ext < +#include + +int main() { +bool x = false +; return 0; } +EOF +if { (eval echo configure:6521: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_builtin_bool=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_builtin_bool=0 +fi +rm -f conftest* + +fi + +if test "$cf_cv_builtin_bool" = 1 +then echo "$ac_t""yes" 1>&6 +else echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking for size of bool""... $ac_c" 1>&6 +echo "configure:6541: checking for size of bool" >&5 +if eval "test \"`echo '$''{'cf_cv_type_of_bool'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + rm -f cf_test.out + if test "$cross_compiling" = yes; then + cf_cv_type_of_bool=unknown +else + cat > conftest.$ac_ext < +#include +#ifdef HAVE_GXX_BUILTIN_H +#include +#elif HAVE_GPP_BUILTIN_H +#include +#elif HAVE_BUILTIN_H +#include +#endif +main() +{ + FILE *fp = fopen("cf_test.out", "w"); + if (fp != 0) { + bool x = true; + if ((bool)(-x) >= 0) + fputs("unsigned ", fp); + if (sizeof(x) == sizeof(int)) fputs("int", fp); + else if (sizeof(x) == sizeof(char)) fputs("char", fp); + else if (sizeof(x) == sizeof(short))fputs("short",fp); + else if (sizeof(x) == sizeof(long)) fputs("long", fp); + fclose(fp); + } + exit(0); +} + +EOF +if { (eval echo configure:6583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_type_of_bool=`cat cf_test.out` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_type_of_bool=unknown +fi +rm -fr conftest* +fi + + +fi + + rm -f cf_test.out +echo "$ac_t""$cf_cv_type_of_bool" 1>&6 +if test "$cf_cv_type_of_bool" = unknown ; then + echo "configure: warning: Assuming unsigned for type of bool" 1>&2 + cf_cv_type_of_bool=unsigned +fi + + +echo $ac_n "checking for special defines needed for etip.h""... $ac_c" 1>&6 +echo "configure:6607: checking for special defines needed for etip.h" >&5 +cf_save_CXXFLAGS="$CXXFLAGS" +cf_result="none" +for cf_math in "" MATH_H +do +for cf_excp in "" MATH_EXCEPTION +do + CXXFLAGS="$cf_save_CXXFLAGS -I${srcdir}/c++ -I${srcdir}/menu" + test -n "$cf_math" && CXXFLAGS="$CXXFLAGS -DETIP_NEEDS_${cf_math}" + test -n "$cf_excp" && CXXFLAGS="$CXXFLAGS -DETIP_NEEDS_${cf_excp}" +cat > conftest.$ac_ext < + +int main() { + +; return 0; } +EOF +if { (eval echo configure:6627: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + test -n "$cf_math" && cat >> confdefs.h <> confdefs.h <&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done +done +echo "$ac_t""$cf_result" 1>&6 +CXXFLAGS="$cf_save_CXXFLAGS" + + +if test "$CXX" = yes ; then +echo $ac_n "checking if $CXX accepts parameter initialization""... $ac_c" 1>&6 +echo "configure:6654: checking if $CXX accepts parameter initialization" >&5 +if eval "test \"`echo '$''{'cf_cv_cpp_param_init'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_ext=C +# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cxx_cross + + if test "$cross_compiling" = yes; then + cf_cv_cpp_param_init=unknown +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_cpp_param_init=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_cpp_param_init=no +fi +rm -fr conftest* +fi + + +fi + +echo "$ac_t""$cf_cv_cpp_param_init" 1>&6 +fi +test "$cf_cv_cpp_param_init" = yes && cat >> confdefs.h <<\EOF +#define CPP_HAS_PARAM_INIT 1 +EOF + + + case $cf_cv_system_name in #(vi + sco3.2v5*) + CXXLDFLAGS="-u main" + ;; + esac + +else + cf_cxx_library=no + cf_cv_builtin_bool=1 + + # Just because we are not configuring against C++ right now does not + # mean that a user will not want to use C++. Some distributors disable + # the C++ portion of this configuration as a shortcut (or just to avoid + # compiling the demo in the c++ directory). So we need a reasonable + # default for the 'bool' type. + # + # Caveat: since the storage of the bool type is not standardized, it + # may change. + + echo $ac_n "checking for fallback type of bool""... $ac_c" 1>&6 +echo "configure:6733: checking for fallback type of bool" >&5 + case "$host_cpu" in #(vi + i?86) cf_cv_type_of_bool=char ;; #(vi + *) cf_cv_type_of_bool=int ;; + esac + echo "$ac_t""$cf_cv_type_of_bool" 1>&6 +fi + + + + +if test "$cf_with_ada" != "no" ; then +cf_ada_make=gnatmake +# Extract the first word of "$cf_ada_make", so it can be a program name with args. +set dummy $cf_ada_make; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6749: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnat_exists'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$gnat_exists"; then + ac_cv_prog_gnat_exists="$gnat_exists" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_gnat_exists="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_gnat_exists" && ac_cv_prog_gnat_exists="no" +fi +fi +gnat_exists="$ac_cv_prog_gnat_exists" +if test -n "$gnat_exists"; then + echo "$ac_t""$gnat_exists" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test "$ac_cv_prog_gnat_exists" = no; then + cf_ada_make= +else + +cf_cv_gnat_version=`$cf_ada_make -v 2>&1 | grep '[0-9].[0-9][0-9]*' |\ + sed -e 's/[^0-9 \.]//g' | $AWK '{print $1;}'` +case $cf_cv_gnat_version in + 3.1[1-9]*|3.[2-9]*|[4-9].*) + cf_cv_prog_gnat_correct=yes + ;; + *) echo Unsupported GNAT version $cf_cv_gnat_version. Required is 3.11 or better. Disabling Ada95 binding. + cf_cv_prog_gnat_correct=no + ;; +esac +case $cf_cv_gnat_version in + 3.1*|[4-9].*) + cf_compile_generics=generics + cf_generic_objects="\$(GENOBJS)" + ;; + *) cf_compile_generics= + cf_generic_objects= + ;; +esac + + # Extract the first word of "m4", so it can be a program name with args. +set dummy m4; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:6803: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_M4_exists'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$M4_exists"; then + ac_cv_prog_M4_exists="$M4_exists" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_M4_exists="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_M4_exists" && ac_cv_prog_M4_exists="no" +fi +fi +M4_exists="$ac_cv_prog_M4_exists" +if test -n "$M4_exists"; then + echo "$ac_t""$M4_exists" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$ac_cv_prog_M4_exists" = no; then + cf_cv_prog_gnat_correct=no + echo Ada95 binding required program m4 not found. Ada95 binding disabled. + fi + if test "$cf_cv_prog_gnat_correct" = yes; then + echo $ac_n "checking if GNAT works""... $ac_c" 1>&6 +echo "configure:6836: checking if GNAT works" >&5 + +rm -f conftest* +cat >>conftest.ads <>conftest.adb <&5 2>&1 ) ; then + if ( ./conftest 1>&5 2>&1 ) ; then + cf_cv_prog_gnat_correct=yes + else + cf_cv_prog_gnat_correct=no + fi +else + cf_cv_prog_gnat_correct=no +fi +rm -f conftest* + + echo "$ac_t""$cf_cv_prog_gnat_correct" 1>&6 + fi +fi +if test "$cf_cv_prog_gnat_correct" = yes; then + ADAFLAGS="-O3 -gnatpn $ADAFLAGS" + + +# Check whether --with-ada-compiler or --without-ada-compiler was given. +if test "${with_ada_compiler+set}" = set; then + withval="$with_ada_compiler" + cf_ada_compiler=$withval +else + cf_ada_compiler=gnatmake +fi + + + cf_ada_package=terminal_interface + + + + + + + + + +# Check whether --with-ada-include or --without-ada-include was given. +if test "${with_ada_include+set}" = set; then + withval="$with_ada_include" + : +else + withval="${ADA_INCLUDE-$prefix/lib/ada/adainclude}" +fi + +case ".$withval" in #(vi +./*) #(vi + ;; +.a-zA-Z:\\/*) #(vi OS/2 EMX + ;; +.\${*prefix}*) #(vi + eval withval="$withval" + case ".$withval" in #(vi + .NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; + esac + ;; #(vi +.NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; +*) + { echo "configure: error: expected a pathname" 1>&2; exit 1; } + ;; +esac + +eval ADA_INCLUDE="$withval" + + + + +# Check whether --with-ada-objects or --without-ada-objects was given. +if test "${with_ada_objects+set}" = set; then + withval="$with_ada_objects" + : +else + withval="${ADA_OBJECTS-$prefix/lib/ada/adalib}" +fi + +case ".$withval" in #(vi +./*) #(vi + ;; +.a-zA-Z:\\/*) #(vi OS/2 EMX + ;; +.\${*prefix}*) #(vi + eval withval="$withval" + case ".$withval" in #(vi + .NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; + esac + ;; #(vi +.NONE/*) + withval=`echo $withval | sed -e s@NONE@$ac_default_prefix@` + ;; +*) + { echo "configure: error: expected a pathname" 1>&2; exit 1; } + ;; +esac + +eval ADA_OBJECTS="$withval" + + + +fi +fi + +### It's not possible to appease gcc 2.6.3's conversion-warnings if we're +### using a 'char' for bools. gcc 2.7.0's conversion-warnings are broken too +### badly to consider using for development purposes, but 2.5.8 is okay. +if test -n "$with_warnings"; then + if test "$GCC" = yes; then + case "`$CC --version`" in + 2.6.3) + if test "$cf_cv_type_of_bool" != "char"; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wconversion" + fi + ;; + 2.5*) + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wconversion" + ;; + esac + fi +fi + +### Construct the library-subsets, if any, from this set of keywords: +### none, base, ext_funcs, termlib. +echo $ac_n "checking for library subsets""... $ac_c" 1>&6 +echo "configure:6980: checking for library subsets" >&5 +if test "$with_termlib" = yes ; then + LIB_SUBSETS="termlib " +else + LIB_SUBSETS="termlib+" +fi +LIB_SUBSETS="${LIB_SUBSETS}base" +test "$with_ext_funcs" = yes && LIB_SUBSETS="${LIB_SUBSETS}+ext_funcs" +echo "$ac_t""$LIB_SUBSETS" 1>&6 + +LIB_TRACING=DEBUG +case "$CFLAGS" in +*-DTRACE*) + LIB_TRACING=all + ;; +esac + +### Construct the list of include-directories to be generated + +CPPFLAGS="$CPPFLAGS -I. -I../include" +if test "$srcdir" != "."; then + CPPFLAGS="$CPPFLAGS -I\$(srcdir)/../include" +fi +if test "$GCC" != yes; then + CPPFLAGS="$CPPFLAGS -I\$(includedir)" +elif test "$includedir" != "/usr/include"; then + if test "$includedir" = '${prefix}/include' ; then + if test $prefix != /usr ; then + CPPFLAGS="$CPPFLAGS -I\$(includedir)" + fi + else + CPPFLAGS="$CPPFLAGS -I\$(includedir)" + fi +fi + + + +ACPPFLAGS="$ACPPFLAGS -I. -I../../include" +if test "$srcdir" != "."; then + ACPPFLAGS="$ACPPFLAGS -I\$(srcdir)/../../include" +fi +if test "$GCC" != yes; then + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" +elif test "$includedir" != "/usr/include"; then + if test "$includedir" = '${prefix}/include' ; then + if test $prefix != /usr ; then + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" + fi + else + ACPPFLAGS="$ACPPFLAGS -I\$(includedir)" + fi +fi + + + +### Build up pieces for makefile rules +echo $ac_n "checking default library suffix""... $ac_c" 1>&6 +echo "configure:7037: checking default library suffix" >&5 + + case $DFT_LWR_MODEL in + libtool) DFT_ARG_SUFFIX='' ;; + normal) DFT_ARG_SUFFIX='' ;; + debug) DFT_ARG_SUFFIX='_g' ;; + profile) DFT_ARG_SUFFIX='_p' ;; + shared) DFT_ARG_SUFFIX='' ;; + esac + test -n "$LIB_SUFFIX" && DFT_ARG_SUFFIX="${LIB_SUFFIX}${DFT_ARG_SUFFIX}" +echo "$ac_t""$DFT_ARG_SUFFIX" 1>&6 + +echo $ac_n "checking default library-dependency suffix""... $ac_c" 1>&6 +echo "configure:7050: checking default library-dependency suffix" >&5 + + + case $DFT_LWR_MODEL in + libtool) DFT_DEP_SUFFIX='.la' ;; + normal) DFT_DEP_SUFFIX='.a' ;; + debug) DFT_DEP_SUFFIX='_g.a' ;; + profile) DFT_DEP_SUFFIX='_p.a' ;; + shared) + case $cf_cv_system_name in + hpux*) DFT_DEP_SUFFIX='.sl' ;; + *) DFT_DEP_SUFFIX='.so' ;; + esac + esac + test -n "$LIB_SUFFIX" && DFT_DEP_SUFFIX="${LIB_SUFFIX}${DFT_DEP_SUFFIX}" +echo "$ac_t""$DFT_DEP_SUFFIX" 1>&6 + +echo $ac_n "checking default object directory""... $ac_c" 1>&6 +echo "configure:7068: checking default object directory" >&5 + + case $DFT_LWR_MODEL in + libtool) DFT_OBJ_SUBDIR='obj_lo' ;; + normal) DFT_OBJ_SUBDIR='objects' ;; + debug) DFT_OBJ_SUBDIR='obj_g' ;; + profile) DFT_OBJ_SUBDIR='obj_p' ;; + shared) DFT_OBJ_SUBDIR='obj_s' ;; + esac +echo "$ac_t""$DFT_OBJ_SUBDIR" 1>&6 + +# libtool thinks it can make c++ shared libraries (perhaps only g++) +echo $ac_n "checking c++ library-dependency suffux""... $ac_c" 1>&6 +echo "configure:7081: checking c++ library-dependency suffux" >&5 +if test "$with_libtool" = "yes"; then + CXX_LIB_SUFFIX=$DFT_DEP_SUFFIX +else + + + case normal in + libtool) CXX_LIB_SUFFIX='.la' ;; + normal) CXX_LIB_SUFFIX='.a' ;; + debug) CXX_LIB_SUFFIX='_g.a' ;; + profile) CXX_LIB_SUFFIX='_p.a' ;; + shared) + case $cf_cv_system_name in + hpux*) CXX_LIB_SUFFIX='.sl' ;; + *) CXX_LIB_SUFFIX='.so' ;; + esac + esac + test -n "$LIB_SUFFIX" && CXX_LIB_SUFFIX="${LIB_SUFFIX}${CXX_LIB_SUFFIX}" +fi +echo "$ac_t""$CXX_LIB_SUFFIX" 1>&6 + + +TINFO_LIST="$SHLIB_LIST" +test "$with_termlib" = yes && SHLIB_LIST="$SHLIB_LIST -ltinfo${LIB_SUFFIX}" + +echo $ac_n "checking where we will install curses.h""... $ac_c" 1>&6 +echo "configure:7107: checking where we will install curses.h" >&5 +test "$with_overwrite" = no && \ +test "x$includedir" = 'x${prefix}/include' && \ + includedir='$(prefix)/include/ncurses'${LIB_SUFFIX} +echo "$ac_t""$includedir" 1>&6 + + + + + +### Set up low-level terminfo dependencies for makefiles. Note that we +### could override this. +if test "$with_termlib" = yes ; then + TEST_DEPS="${LIB_DIR}/${LIB_PREFIX}${TINFO_NAME}${DFT_DEP_SUFFIX}" + if test "$DFT_LWR_MODEL" = "libtool"; then + TEST_ARGS="${TEST_DEPS}" + else + TEST_ARGS="-l${TINFO_NAME}${DFT_ARG_SUFFIX}" + fi +fi +PROG_DEPS="$TEST_DEPS" +PROG_ARGS="$TEST_ARGS" + +### Construct the list of subdirectories for which we'll customize makefiles +### with the appropriate compile-rules. + + +echo $ac_n "checking for src modules""... $ac_c" 1>&6 +echo "configure:7135: checking for src modules" >&5 + +# dependencies and linker-arguments for test-programs +TEST_DEPS="${LIB_DIR}/${LIB_PREFIX}${LIB_NAME}${DFT_DEP_SUFFIX} $TEST_DEPS" +if test "$DFT_LWR_MODEL" = "libtool"; then + TEST_ARGS="${TEST_DEPS}" +else + TEST_ARGS="-l${LIB_NAME}${DFT_ARG_SUFFIX} $TEST_ARGS" +fi + +# dependencies and linker-arguments for utility-programs +PROG_ARGS="$TEST_ARGS" + +cf_cv_src_modules= +for cf_dir in $modules_to_build +do + if test -f $srcdir/$cf_dir/modules; then + + # We may/may not have tack in the distribution, though the + # makefile is. + if test $cf_dir = tack ; then + if test ! -f $srcdir/${cf_dir}/${cf_dir}.h; then + continue + fi + fi + + if test -z "$cf_cv_src_modules"; then + cf_cv_src_modules=$cf_dir + else + cf_cv_src_modules="$cf_cv_src_modules $cf_dir" + fi + + # Make the ncurses_cfg.h file record the library interface files as + # well. These are header files that are the same name as their + # directory. Ncurses is the only library that does not follow + # that pattern. + if test $cf_dir = tack ; then + continue + elif test -f $srcdir/${cf_dir}/${cf_dir}.h; then + +cf_have_include=`echo "$cf_dir" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + cat >> confdefs.h <> confdefs.h <&6 +TEST_ARGS="-L${LIB_DIR} -L\$(libdir) $TEST_ARGS" + + + +PROG_ARGS="-L${LIB_DIR} -L\$(libdir) $PROG_ARGS" + + +SRC_SUBDIRS="man include" +for cf_dir in $cf_cv_src_modules +do + SRC_SUBDIRS="$SRC_SUBDIRS $cf_dir" +done +SRC_SUBDIRS="$SRC_SUBDIRS misc test" +test "$cf_with_cxx_binding" != no && SRC_SUBDIRS="$SRC_SUBDIRS c++" + +ADA_SUBDIRS= +if test "$cf_cv_prog_gnat_correct" = yes && test -f $srcdir/Ada95/Makefile.in; then + SRC_SUBDIRS="$SRC_SUBDIRS Ada95" + ADA_SUBDIRS="gen src samples" +fi + +SUB_MAKEFILES= +for cf_dir in $SRC_SUBDIRS +do + SUB_MAKEFILES="$SUB_MAKEFILES $cf_dir/Makefile" +done + +if test -n "$ADA_SUBDIRS"; then + for cf_dir in $ADA_SUBDIRS + do + SUB_MAKEFILES="$SUB_MAKEFILES Ada95/$cf_dir/Makefile" + done + +fi + + +DIRS_TO_MAKE="lib" +for cf_item in $cf_list_models +do + + case $cf_item in + libtool) cf_subdir='obj_lo' ;; + normal) cf_subdir='objects' ;; + debug) cf_subdir='obj_g' ;; + profile) cf_subdir='obj_p' ;; + shared) cf_subdir='obj_s' ;; + esac + + DIRS_TO_MAKE="$DIRS_TO_MAKE $cf_subdir" +done +for cf_dir in $DIRS_TO_MAKE +do + test ! -d $cf_dir && mkdir $cf_dir +done + + + +### Now that we're done running tests, add the compiler-warnings, if any +CFLAGS="$CFLAGS $EXTRA_CFLAGS" + +################################################################################ +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13.20000819" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "\ + include/MKterm.h.awk \ + include/curses.h \ + include/termcap.h \ + include/unctrl.h \ + misc/run_tic.sh:misc/run_tic.in \ + $SUB_MAKEFILES \ + Makefile include/ncurses_cfg.h:include/ncurses_cfg.hin" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@NCURSES_MAJOR@%$NCURSES_MAJOR%g +s%@NCURSES_MINOR@%$NCURSES_MINOR%g +s%@NCURSES_PATCH@%$NCURSES_PATCH%g +s%@cf_cv_rel_version@%$cf_cv_rel_version%g +s%@cf_cv_abi_version@%$cf_cv_abi_version%g +s%@cf_cv_cc_bool_type@%$cf_cv_cc_bool_type%g +s%@cf_cv_builtin_bool@%$cf_cv_builtin_bool%g +s%@cf_cv_type_of_bool@%$cf_cv_type_of_bool%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@BUILD_CC@%$BUILD_CC%g +s%@CPP@%$CPP%g +s%@PROG_EXT@%$PROG_EXT%g +s%@LDCONFIG@%$LDCONFIG%g +s%@CXX@%$CXX%g +s%@AWK@%$AWK%g +s%@SET_MAKE@%$SET_MAKE%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@LN_S@%$LN_S%g +s%@RANLIB@%$RANLIB%g +s%@MAKE_LOWER_TAGS@%$MAKE_LOWER_TAGS%g +s%@MAKE_UPPER_TAGS@%$MAKE_UPPER_TAGS%g +s%@LINT@%$LINT%g +s%@MAN@%$MAN%g +s%@LINT_OPTS@%$LINT_OPTS%g +s%@LD@%$LD%g +s%@AR@%$AR%g +s%@AR_OPTS@%$AR_OPTS%g +s%@cf_cv_makeflags@%$cf_cv_makeflags%g +s%@DESTDIR@%$DESTDIR%g +s%@cf_list_models@%$cf_list_models%g +s%@LIBTOOL@%$LIBTOOL%g +s%@DFT_LWR_MODEL@%$DFT_LWR_MODEL%g +s%@DFT_UPR_MODEL@%$DFT_UPR_MODEL%g +s%@TINFO_NAME@%$TINFO_NAME%g +s%@LIB_NAME@%$LIB_NAME%g +s%@LIB_PREFIX@%$LIB_PREFIX%g +s%@LIB_SUFFIX@%$LIB_SUFFIX%g +s%@CC_G_OPT@%$CC_G_OPT%g +s%@CXX_G_OPT@%$CXX_G_OPT%g +s%@LD_MODEL@%$LD_MODEL%g +s%@CC_SHARED_OPTS@%$CC_SHARED_OPTS%g +s%@LD_SHARED_OPTS@%$LD_SHARED_OPTS%g +s%@MK_SHARED_LIB@%$MK_SHARED_LIB%g +s%@LINK_PROGS@%$LINK_PROGS%g +s%@LINK_TESTS@%$LINK_TESTS%g +s%@EXTRA_LDFLAGS@%$EXTRA_LDFLAGS%g +s%@LOCAL_LDFLAGS@%$LOCAL_LDFLAGS%g +s%@LOCAL_LDFLAGS2@%$LOCAL_LDFLAGS2%g +s%@INSTALL_LIB@%$INSTALL_LIB%g +s%@TERMINFO_SRC@%$TERMINFO_SRC%g +s%@FALLBACK_LIST@%$FALLBACK_LIST%g +s%@TERMINFO_DIRS@%$TERMINFO_DIRS%g +s%@TERMINFO@%$TERMINFO%g +s%@NCURSES_CONST@%$NCURSES_CONST%g +s%@NCURSES_XNAMES@%$NCURSES_XNAMES%g +s%@ECHO_LINK@%$ECHO_LINK%g +s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g +s%@MATH_LIB@%$MATH_LIB%g +s%@cf_cv_typeof_chtype@%$cf_cv_typeof_chtype%g +s%@cf_cv_1UL@%$cf_cv_1UL%g +s%@cf_cv_shift_limit@%$cf_cv_shift_limit%g +s%@cf_cv_widec_shift@%$cf_cv_widec_shift%g +s%@CXXCPP@%$CXXCPP%g +s%@CXXLDFLAGS@%$CXXLDFLAGS%g +s%@CXXLIBS@%$CXXLIBS%g +s%@gnat_exists@%$gnat_exists%g +s%@M4_exists@%$M4_exists%g +s%@cf_ada_make@%$cf_ada_make%g +s%@cf_ada_compiler@%$cf_ada_compiler%g +s%@cf_ada_package@%$cf_ada_package%g +s%@ADAFLAGS@%$ADAFLAGS%g +s%@cf_compile_generics@%$cf_compile_generics%g +s%@cf_generic_objects@%$cf_generic_objects%g +s%@ADA_INCLUDE@%$ADA_INCLUDE%g +s%@ADA_OBJECTS@%$ADA_OBJECTS%g +s%@ACPPFLAGS@%$ACPPFLAGS%g +s%@DFT_ARG_SUFFIX@%$DFT_ARG_SUFFIX%g +s%@DFT_DEP_SUFFIX@%$DFT_DEP_SUFFIX%g +s%@DFT_OBJ_SUBDIR@%$DFT_OBJ_SUBDIR%g +s%@CXX_LIB_SUFFIX@%$CXX_LIB_SUFFIX%g +s%@EXTRA_LIBS@%$EXTRA_LIBS%g +s%@TINFO_LIST@%$TINFO_LIST%g +s%@SHLIB_LIST@%$SHLIB_LIST%g +s%@TEST_DEPS@%$TEST_DEPS%g +s%@TEST_ARGS@%$TEST_ARGS%g +s%@PROG_ARGS@%$PROG_ARGS%g +s%@ADA_SUBDIRS@%$ADA_SUBDIRS%g +s%@DIRS_TO_MAKE@%$DIRS_TO_MAKE%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + + +# Transform confdefs.h into a list of #define's. We won't use it as a sed +# script, but as data to insert where we see @DEFS@. We expect AC_SAVE_DEFS to +# be either 'cat' or 'sort'. +sort confdefs.h >conftest.vals + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +echo ' rm -f conftest.frag' >> $CONFIG_STATUS +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write chunks of a limited-size here document to conftest.frag. + echo ' cat >> conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +# Run sed to substitute the contents of conftest.frag into conftest.in at the +# marker @DEFS@. +echo ' cat >> conftest.edit < conftest.out +rm -f conftest.in +mv conftest.out conftest.in +rm -f conftest.edit conftest.frag +' >> $CONFIG_STATUS + + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +# Extra commands, if any + + + + case $cf_cv_system_name in + os2) LIB_PREFIX='' ;; + *) LIB_PREFIX='lib' ;; + esac +cf_prefix=$LIB_PREFIX + + + +for cf_dir in $SRC_SUBDIRS +do + if test -f $srcdir/$cf_dir/modules; then + + cf_libs_to_make= + for cf_item in $CF_LIST_MODELS + do + + + case $cf_item in + libtool) cf_suffix='.la' ;; + normal) cf_suffix='.a' ;; + debug) cf_suffix='_g.a' ;; + profile) cf_suffix='_p.a' ;; + shared) + case $cf_cv_system_name in + hpux*) cf_suffix='.sl' ;; + *) cf_suffix='.so' ;; + esac + esac + test -n "$LIB_SUFFIX" && cf_suffix="${LIB_SUFFIX}${cf_suffix}" + + if test $cf_item = shared ; then + if test "$cf_cv_do_symlinks" = yes ; then + case "$cf_cv_shlib_version" in #(vi + rel) cf_suffix="$cf_suffix"'.$(REL_VERSION)' ;; #(vi + abi) cf_suffix="$cf_suffix"'.$(ABI_VERSION)' ;; + esac + fi + fi + cf_libs_to_make="$cf_libs_to_make ../lib/${cf_prefix}${cf_dir}${cf_suffix}" + done + + if test $cf_dir = ncurses ; then + case "$LIB_SUBSETS" in #(vi + termlib+*) #(vi + ;; + *) #(vi + cf_item=`echo $cf_libs_to_make |sed -e s/$LIB_NAME/$TINFO_NAME/g` + cf_libs_to_make="$cf_item $cf_libs_to_make" + ;; + esac + fi + + sed -e "s@\@LIBS_TO_MAKE\@@$cf_libs_to_make@" \ + $cf_dir/Makefile >$cf_dir/Makefile.out + mv $cf_dir/Makefile.out $cf_dir/Makefile + + $AWK -f $srcdir/mk-0th.awk \ + name=$cf_dir \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + + for cf_item in $CF_LIST_MODELS + do + echo 'Appending rules for '$cf_item' model ('$cf_dir')' + +CF_ITEM=`echo "$cf_item" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + + + case $cf_item in + libtool) cf_suffix='.la' ;; + normal) cf_suffix='.a' ;; + debug) cf_suffix='_g.a' ;; + profile) cf_suffix='_p.a' ;; + shared) + case $cf_cv_system_name in + hpux*) cf_suffix='.sl' ;; + *) cf_suffix='.so' ;; + esac + esac + test -n "$LIB_SUFFIX" && cf_suffix="${LIB_SUFFIX}${cf_suffix}" + + + case $cf_item in + libtool) cf_subdir='obj_lo' ;; + normal) cf_subdir='objects' ;; + debug) cf_subdir='obj_g' ;; + profile) cf_subdir='obj_p' ;; + shared) cf_subdir='obj_s' ;; + esac + + + # These dependencies really are for development, not + # builds, but they are useful in porting, too. + cf_depend="../include/ncurses_cfg.h" + if test "$srcdir" = "."; then + cf_reldir="." + else + cf_reldir="\$(srcdir)" + fi + + if test -f $srcdir/$cf_dir/$cf_dir.priv.h; then + cf_depend="$cf_depend $cf_reldir/$cf_dir.priv.h" + elif test -f $srcdir/$cf_dir/curses.priv.h; then + cf_depend="$cf_depend $cf_reldir/curses.priv.h" + fi + + for cf_subset in $LIB_SUBSETS + do + $AWK -f $srcdir/mk-1st.awk \ + name=$cf_dir \ + traces=$LIB_TRACING \ + MODEL=$CF_ITEM \ + model=$cf_subdir \ + prefix=$cf_prefix \ + suffix=$cf_suffix \ + subset=$cf_subset \ + ShlibVer=$cf_cv_shlib_version \ + DoLinks=$cf_cv_do_symlinks \ + rmSoLocs=$cf_cv_rm_so_locs \ + ldconfig="$LDCONFIG" \ + overwrite=$WITH_OVERWRITE \ + depend="$cf_depend" \ + target="$target" \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + test $cf_dir = ncurses && WITH_OVERWRITE=no + $AWK -f $srcdir/mk-2nd.awk \ + name=$cf_dir \ + traces=$LIB_TRACING \ + MODEL=$CF_ITEM \ + model=$cf_subdir \ + subset=$cf_subset \ + srcdir=$srcdir \ + echo=$WITH_ECHO \ + $srcdir/$cf_dir/modules >>$cf_dir/Makefile + done + done + fi + + echo ' cd '$cf_dir' && $(MAKE) $(CF_MFLAGS) $@' >>Makefile +done + +for cf_dir in $SRC_SUBDIRS +do + if test -f $cf_dir/Makefile ; then + case "$cf_dir" in + Ada95) #(vi + echo 'libs \' >> Makefile + echo 'install.libs \' >> Makefile + echo 'uninstall.libs ::' >> Makefile + echo ' cd '$cf_dir' && $(MAKE) $(CF_MFLAGS) $@' >> Makefile + ;; + esac + fi + + if test -f $srcdir/$cf_dir/modules; then + echo >> Makefile + if test -f $srcdir/$cf_dir/headers; then +cat >> Makefile <> Makefile +fi +cat >> Makefile <> Makefile <> Makefile <> Makefile <headers.sh <>headers.sh </<\$END\/\$NAME>/" >> \$TMPSED + done + ;; +*) + echo "" >> \$TMPSED + ;; +esac +CF_EOF +else + cat >>headers.sh <//" >> \$TMPSED + NAME=ncurses.h + fi + echo "s/<\$NAME>/<\$END\/\$NAME>/" >> \$TMPSED + done + ;; +*) + echo "s///" >> \$TMPSED + ;; +esac +CF_EOF +fi +cat >>headers.sh < \$TMPSRC +NAME=\`basename \$SRC\` +CF_EOF +if test $WITH_CURSES_H != yes; then + cat >>headers.sh <>headers.sh <>$cf_dir/Makefile <>$cf_dir/Makefile + j=$i + done + echo " $j" >>$cf_dir/Makefile + for i in `cat $srcdir/$cf_dir/headers |fgrep -v "#"` + do + echo " @ (cd \$(DESTDIR)\$(includedir) && rm -f `basename $i`) ; ../headers.sh \$(INSTALL_DATA) \$(DESTDIR)\$(includedir) \$(srcdir) $i" >>$cf_dir/Makefile + test $i = curses.h && test $WITH_CURSES_H = yes && echo " @ (cd \$(DESTDIR)\$(includedir) && rm -f ncurses.h && \$(LN_S) curses.h ncurses.h)" >>$cf_dir/Makefile + done + + cat >>$cf_dir/Makefile <>$cf_dir/Makefile + test $i = curses.h && echo " -@ (cd \$(DESTDIR)\$(includedir) && rm -f ncurses.h)" >>$cf_dir/Makefile + done + fi +done + + + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 +${MAKE-make} preinstall diff --git a/ncurses-5.2/configure.in b/ncurses-5.2/configure.in new file mode 100644 index 0000000..f8fcaf1 --- /dev/null +++ b/ncurses-5.2/configure.in @@ -0,0 +1,1171 @@ +dnl*************************************************************************** +dnl Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * +dnl * +dnl Permission is hereby granted, free of charge, to any person obtaining a * +dnl copy of this software and associated documentation files (the * +dnl "Software"), to deal in the Software without restriction, including * +dnl without limitation the rights to use, copy, modify, merge, publish, * +dnl distribute, distribute with modifications, sublicense, and/or sell * +dnl copies of the Software, and to permit persons to whom the Software is * +dnl furnished to do so, subject to the following conditions: * +dnl * +dnl The above copyright notice and this permission notice shall be included * +dnl in all copies or substantial portions of the Software. * +dnl * +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * +dnl IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * +dnl THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +dnl * +dnl Except as contained in this notice, the name(s) of the above copyright * +dnl holders shall not be used in advertising or otherwise to promote the * +dnl sale, use or other dealings in this Software without prior written * +dnl authorization. * +dnl*************************************************************************** +dnl +dnl Author: Thomas E. Dickey 1996,1997 +dnl +dnl $Id$ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl See http://dickey.his.com/autoconf/ for additional information. +dnl +dnl --------------------------------------------------------------------------- +AC_PREREQ(2.13.20000819) +AC_REVISION($Revision$) +AC_INIT(ncurses/base/lib_initscr.c) +AC_CONFIG_HEADER(include/ncurses_cfg.h:include/ncurses_cfg.hin) + +CF_SUBST_NCURSES_VERSION +CF_CHECK_CACHE([AC_CANONICAL_SYSTEM]) +AC_ARG_WITH(system-type, +[ --with-system-type=XXX test: override derived host system-type], +[AC_MSG_WARN(overriding system type to $withval) + cf_cv_system_name=$withval]) + +# We need a configure script only when compiling as part of GNU C library. +# Here we have to generate one of the files we need while compiling. +# +# The only problem is that users of the package might think they have to +# run configure themself and find it irritating when nothing happens. +# +# So we try here to find out whether we are called from the glibc configure +# or by a user. +# +dnl Check if we are a drop-in addition to glibc. +AC_ARG_ENABLE(add-ons, dnl +[ --enable-add-ons=DIR... used to check if we are a glibc add-on.], + [glibc_add_on=yes], + [glibc_add_on=]) + +dnl We need to use [ and ] for other purposes for a while now. +changequote(,)dnl +if test x"$glibc_add_on" = "xyes" ; then + rm -f $srcdir/Banner + # We are in glibc. + rm -f $srcdir/Makefile + cp $srcdir/Makefile.glibc $srcdir/Makefile + echo "ncurses `grep \"^[ ]*ncurses-version[ ]*=.*$\" \ + $srcdir/Makefile | sed -e \ + 's/^[ ]*ncurses-version[ ]*=[ ]*\([^ ^ ]*\)[ ]*$/\1/'`" > $srcdir/Banner + exit 0 +fi +changequote([,])dnl + +### Save the given $CFLAGS to allow user-override. +cf_user_CFLAGS="$CFLAGS" + +### Default install-location +CF_CFG_DEFAULTS + +### Checks for programs. +AC_PROG_CC +if test "$GCC" = yes ; then + AC_MSG_CHECKING(version of gcc) + eval "$CC --version" +fi +if test "$host" != $build; then + AC_CHECK_PROGS(BUILD_CC, $CC gcc cc) +else + BUILD_CC="$CC" +fi +AC_SUBST(BUILD_CC) +AC_PROG_CPP +AC_PROG_GCC_TRADITIONAL +AC_ISC_POSIX +CF_ANSI_CC_REQD +CF_PROG_EXT + +case "$cf_cv_system_name" in +freebsd*) #(vi + test -z "$LDCONFIG" && LDCONFIG="/sbin/ldconfig -R" + ;; +*) LDPATH=$PATH:/sbin:/usr/sbin + AC_PATH_PROG(LDCONFIG,ldconfig,,$LDPATH) + ;; +esac +AC_SUBST(LDCONFIG) + +dnl DEFECT in autoconf 2.12: an attempt to set policy, this breaks the +dnl configure script by not letting us test if C++ +dnl is present, making this option necessary. +AC_MSG_CHECKING(if you want to ensure bool is consistent with C++) +AC_ARG_WITH(cxx, + [ --without-cxx do not adjust ncurses bool to match C++], + [cf_with_cxx=$withval], + [cf_with_cxx=yes]) +AC_MSG_RESULT($cf_with_cxx) +if test "X$cf_with_cxx" = Xno ; then + CXX="" + GXX="" +else + pushdef([AC_MSG_ERROR], + [AC_MSG_RESULT([You don't have any C++ compiler, too bad]); dnl + cf_with_cxx=no; CXX=""; GXX="";])dnl + AC_PROG_CXX + popdef([AC_MSG_ERROR])dnl +fi + +changequote(,)dnl +if test "$GXX" = yes; then + case "`${CXX-g++} --version`" in + 1*|2.[0-6]*) + GXX=""; CXX=""; ac_cv_prog_gxx=no + cf_cxx_library=no + echo No: templates do not work + ;; + esac +fi +changequote([,])dnl + +AC_MSG_CHECKING(if you want to build C++ binding and demo) +AC_ARG_WITH(cxx-binding, + [ --without-cxx-binding do not build C++ binding and demo], + [cf_with_cxx_binding=$withval], + [cf_with_cxx_binding=$cf_with_cxx]) +AC_MSG_RESULT($cf_with_cxx_binding) + +AC_MSG_CHECKING(if you want to build with Ada95) +AC_ARG_WITH(ada, + [ --without-ada suppress check for Ada95, don't build demo], + [cf_with_ada=$withval], + [cf_with_ada=yes]) +AC_MSG_RESULT($cf_with_ada) + +AC_MSG_CHECKING(if you want to build programs such as tic) +AC_ARG_WITH(progs, + [ --without-progs suppress build with programs (e.g., tic)], + [cf_with_progs=$withval], + [cf_with_progs=yes]) +AC_MSG_RESULT($cf_with_progs) + +AC_MSG_CHECKING(if you wish to install curses.h) +AC_ARG_WITH(curses-h, + [ --without-curses-h install curses.h as ncurses.h only], + [with_curses_h=$withval], + [with_curses_h=yes]) +AC_MSG_RESULT($with_curses_h) + +modules_to_build="ncurses" +if test "X$cf_with_progs" != Xno ; then +modules_to_build="$modules_to_build progs tack" +fi +modules_to_build="$modules_to_build panel menu form" + +AC_ARG_PROGRAM +AC_PROG_AWK +AC_PROG_MAKE_SET +CF_PROG_INSTALL +AC_SYS_LONG_FILE_NAMES +CF_MIXEDCASE_FILENAMES +AC_PROG_LN_S +AC_PROG_RANLIB +CF_MAKE_TAGS +AC_CHECK_PROGS(LINT, tdlint lint alint) +AC_CHECK_PROGS(MAN, man man_db) +AC_SUBST(LINT_OPTS) + +dnl These are standard among *NIX systems, but not when cross-compiling +CF_SUBST(loader,LD,ld) +CF_SUBST(archiver,AR,ar) +CF_SUBST(archiver options,AR_OPTS,rv) + +CF_MAKEFLAGS + +dnl Special option for use by system-builders: the install-prefix is used to +dnl adjust the location into which the actual install is done, so that an +dnl archive can be built without modifying the host system's configuration. +AC_MSG_CHECKING(if you have specified an install-prefix) +AC_ARG_WITH(install-prefix, + [ --with-install-prefix prefixes actual install-location], + [case "$withval" in #(vi + yes|no) #(vi + ;; + *) DESTDIR="$withval" + ;; + esac]) +AC_MSG_RESULT($DESTDIR) +AC_SUBST(DESTDIR) + +############################################################################### +CF_HELP_MESSAGE(Options to Specify the Libraries Built/Used:) + +### Options to allow the user to specify the set of libraries which are used. +### Use "--without-normal --with-shared" to allow the default model to be +### shared, for example. +cf_list_models="" +AC_SUBST(cf_list_models)dnl the complete list of models ("normal debug") + +AC_MSG_CHECKING(if you want to build libraries with libtool) +AC_ARG_WITH(libtool, + [ --with-libtool generate libraries with libtool], + [with_libtool=$withval], + [with_libtool=no]) +AC_MSG_RESULT($with_libtool) +if test "$with_libtool" = "yes"; then + cf_list_models="$cf_list_models libtool" + test -z "$LIBTOOL" && LIBTOOL=libtool +else + LIBTOOL="" +fi +AC_SUBST(LIBTOOL) + +AC_MSG_CHECKING(if you want to build shared libraries) +AC_ARG_WITH(shared, + [ --with-shared generate shared-libraries], + [with_shared=$withval], + [with_shared=no]) +AC_MSG_RESULT($with_shared) +test "$with_shared" = "yes" && cf_list_models="$cf_list_models shared" + +AC_MSG_CHECKING(if you want to build static libraries) +AC_ARG_WITH(normal, + [ --with-normal generate normal-libraries (default)], + [with_normal=$withval], + [with_normal=yes]) +AC_MSG_RESULT($with_normal) +test "$with_normal" = "yes" && cf_list_models="$cf_list_models normal" + +AC_MSG_CHECKING(if you want to build debug libraries) +AC_ARG_WITH(debug, + [ --with-debug generate debug-libraries (default)], + [with_debug=$withval], + [with_debug=yes]) +AC_MSG_RESULT($with_debug) +test "$with_debug" = "yes" && cf_list_models="$cf_list_models debug" + +AC_MSG_CHECKING(if you want to build profiling libraries) +AC_ARG_WITH(profile, + [ --with-profile generate profile-libraries], + [with_profile=$withval], + [with_profile=no]) +AC_MSG_RESULT($with_profile) +test "$with_profile" = "yes" && cf_list_models="$cf_list_models profile" + +############################################################################### + +AC_MSG_CHECKING(for specified models) +test -z "$cf_list_models" && cf_list_models=normal +dnl If we use libtool to generate libraries, then it must be the only +dnl specified model. +test "$with_libtool" = "yes" && cf_list_models=libtool +AC_MSG_RESULT($cf_list_models) + +### Use the first model as the default, and save its suffix for use in building +### up test-applications. +AC_MSG_CHECKING(for default model) +DFT_LWR_MODEL=`echo $cf_list_models | $AWK '{print $1}'` +AC_MSG_RESULT($DFT_LWR_MODEL) + +CF_UPPER(DFT_UPR_MODEL,$DFT_LWR_MODEL)dnl + +AC_SUBST(DFT_LWR_MODEL)dnl the default model ("normal") +AC_SUBST(DFT_UPR_MODEL)dnl the default model ("NORMAL") + +TINFO_NAME=tinfo +AC_SUBST(TINFO_NAME) + +LIB_NAME=ncurses +AC_SUBST(LIB_NAME) + +LIB_DIR=../lib +CF_LIB_PREFIX(cf_prefix) +LIB_PREFIX=$cf_prefix +AC_SUBST(LIB_PREFIX) + +LIB_SUFFIX= +AC_SUBST(LIB_SUFFIX) + +############################################################################### + +AC_MSG_CHECKING(if you want to build a separate terminfo library) +AC_ARG_WITH(termlib, + [ --with-termlib generate separate terminfo library], + [with_termlib=$withval], + [with_termlib=no]) +AC_MSG_RESULT($with_termlib) + +### Checks for special libraries, must be done up-front. +AC_MSG_CHECKING(if you want to link with dbmalloc for testing) +AC_ARG_WITH(dbmalloc, + [ --with-dbmalloc test: use Conor Cahill's dbmalloc library], + [with_dbmalloc=$withval], + [with_dbmalloc=no]) +AC_MSG_RESULT($with_dbmalloc) +if test "$with_dbmalloc" = yes ; then + AC_CHECK_LIB(dbmalloc,debug_malloc) +fi + +AC_MSG_CHECKING(if you want to link with dmalloc for testing) +AC_ARG_WITH(dmalloc, + [ --with-dmalloc test: use Gray Watson's dmalloc library], + [with_dmalloc=$withval], + [with_dmalloc=no]) +AC_MSG_RESULT($with_dmalloc) +if test "$with_dmalloc" = yes ; then + AC_CHECK_LIB(dmalloc,dmalloc_debug) +fi + +SHLIB_LIST="" +AC_MSG_CHECKING(if you want to link with the gpm mouse library) +AC_ARG_WITH(gpm, + [ --with-gpm use Alessandro Rubini's GPM library], + [with_gpm=$withval], + [with_gpm=no]) +AC_MSG_RESULT($with_gpm) +if test "$with_gpm" = yes ; then + AC_CHECK_LIB(gpm,Gpm_Open,[ + EXTRA_LIBS="-lgpm -lncurses $EXTRA_LIBS" + SHLIB_LIST="-lgpm $SHLIB_LIST" + AC_DEFINE(HAVE_LIBGPM) + AC_CHECK_HEADERS(gpm.h) + ],AC_MSG_WARN(Cannot link with gpm library - read the FAQ)) +fi + +dnl Not all ports of gcc support the -g option + +if test X"$CC_G_OPT" = X"" ; then + CC_G_OPT='-g' + test -n "$GCC" && test "${ac_cv_prog_cc_g}" != yes && CC_G_OPT='' +fi +AC_SUBST(CC_G_OPT) + +if test X"$CXX_G_OPT" = X"" ; then + CXX_G_OPT='-g' + test -n "$GXX" && test "${ac_cv_prog_cxx_g}" != yes && CXX_G_OPT='' +fi +AC_SUBST(CXX_G_OPT) + +AC_MSG_CHECKING(for default loader flags) +case $DFT_LWR_MODEL in +libtool) LD_MODEL='' ;; +normal) LD_MODEL='' ;; +debug) LD_MODEL=$CC_G_OPT ;; +profile) LD_MODEL='-pg';; +shared) LD_MODEL='' ;; +esac +AC_SUBST(LD_MODEL)dnl the type of link (e.g., -g or -pg) +AC_MSG_RESULT($LD_MODEL) + +AC_MSG_CHECKING(if rpath option should be used) +AC_ARG_ENABLE(rpath, +[ --enable-rpath use rpath option when generating shared libraries], +[cf_cv_ld_rpath=$enableval], +[cf_cv_ld_rpath=no]) +AC_MSG_RESULT($cf_cv_ld_rpath) + +CF_SHARED_OPTS +if test "$CC_SHARED_OPTS" = "unknown"; then + for model in $cf_list_models; do + if test "$model" = "shared"; then + AC_ERROR(Shared libraries are not supported in this version) + fi + done +fi + +############################################################################### +CF_HELP_MESSAGE(Fine-Tuning Your Configuration:) + +### use option --disable-overwrite to leave out the link to -lcurses +AC_MSG_CHECKING(if you wish to install ncurses overwriting curses) +AC_ARG_ENABLE(overwrite, + [ --disable-overwrite leave out the link to -lcurses], + [with_overwrite=$enableval], + [with_overwrite=yes]) +AC_MSG_RESULT($with_overwrite) + +AC_MSG_CHECKING(if external terminfo-database is used) +AC_ARG_ENABLE(database, + [ --disable-database use only built-in data], + [use_database=$enableval], + [use_database=yes]) +AC_MSG_RESULT($use_database) + +case $host_os in #(vi +os2*) #(vi + TERMINFO_SRC='${top_srcdir}/misc/emx.src' + ;; +*) #(vi + TERMINFO_SRC='${top_srcdir}/misc/terminfo.src' + ;; +esac +AC_SUBST(TERMINFO_SRC) + +if test "$use_database" != no ; then + AC_DEFINE(USE_DATABASE) + AC_MSG_CHECKING(which terminfo source-file will be installed) + AC_ARG_ENABLE(database, + [ --with-database=XXX specify terminfo source to install], + [TERMINFO_SRC=$withval]) + AC_MSG_RESULT($TERMINFO_SRC) +fi + +AC_MSG_CHECKING(for list of fallback descriptions) +AC_ARG_WITH(fallbacks, + [ --with-fallbacks=XXX specify list of fallback terminal descriptions], + [with_fallback=$withval], + [with_fallback=]) +AC_MSG_RESULT($with_fallback) +FALLBACK_LIST=`echo $with_fallback|sed -e 's/,/ /g'` +AC_SUBST(FALLBACK_LIST) + +if test "$use_database" = no ; then + if test -z $with_fallback ; then + AC_ERROR(You have disabled the database w/o specifying fallbacks) + fi + TERMINFO="${datadir}/terminfo" +else + +AC_MSG_CHECKING(for list of terminfo directories) +CF_WITH_PATHLIST(terminfo-dirs, + [ --with-terminfo-dirs=XXX specify list of terminfo directories], + TERMINFO_DIRS, + DATADIR/terminfo, + ${datadir}/terminfo) +AC_MSG_RESULT($TERMINFO_DIRS) +test -n "$TERMINFO_DIRS" && AC_DEFINE_UNQUOTED(TERMINFO_DIRS,"$TERMINFO_DIRS") + +AC_MSG_CHECKING(for default terminfo directory) +CF_WITH_PATH(default-terminfo-dir, + [ --with-default-terminfo-dir=DIR default terminfo directory], + TERMINFO, + DATADIR/terminfo, + ${datadir}/terminfo) +AC_MSG_RESULT($TERMINFO) +AC_DEFINE_UNQUOTED(TERMINFO,"$TERMINFO") + +fi + +AC_SUBST(TERMINFO) + +### use option --disable-big-core to make tic run on small machines +### We need 4Mb, check if we can allocate 50% more than that. +AC_MSG_CHECKING(if big-core option selected) +AC_ARG_ENABLE(big-core, + [ --disable-big-core assume machine has little memory], + [with_big_core=$enableval], + [AC_TRY_RUN([ +#include +#include +int main() { + unsigned long n = 6000000L; + char *s = malloc(n); + if (s != 0) + s[0] = s[n-1] = 0; + exit(s == 0); +}], + [with_big_core=yes], + [with_big_core=no], + [with_big_core=no])]) +AC_MSG_RESULT($with_big_core) +test "$with_big_core" = "yes" && AC_DEFINE(HAVE_BIG_CORE) + +### use option --enable-termcap to compile in the termcap fallback support +AC_MSG_CHECKING(if you want termcap-fallback support) +AC_ARG_ENABLE(termcap, + [ --enable-termcap compile in termcap fallback support], + [with_termcap=$enableval], + [with_termcap=no]) +AC_MSG_RESULT($with_termcap) + +if test "$with_termcap" != "yes" ; then + AC_DEFINE(PURE_TERMINFO) +else + +### use option --enable-getcap to use a hacked getcap for reading termcaps +AC_MSG_CHECKING(if fast termcap-loader is needed) +AC_ARG_ENABLE(getcap, + [ --enable-getcap fast termcap load, no xrefs to terminfo], + [with_getcap=$enableval], + [with_getcap=no]) +AC_MSG_RESULT($with_getcap) +test "$with_getcap" = "yes" && AC_DEFINE(USE_GETCAP) + +AC_MSG_CHECKING(if translated termcaps will be cached in ~/.terminfo) +AC_ARG_ENABLE(getcap-cache, + [ --enable-getcap-cache cache translated termcaps in ~/.terminfo], + [with_getcap_cache=$enableval], + [with_getcap_cache=no]) +AC_MSG_RESULT($with_getcap_cache) +test "$with_getcap_cache" = "yes" && AC_DEFINE(USE_GETCAP_CACHE) + +fi + +### Use option --enable-symlinks to make tic use symlinks, not hard links +### to reduce storage requirements for the terminfo database. +CF_LINK_FUNCS + +with_links=no +with_symlinks=no + +if test "$ac_cv_func_link" != yes ; then + AC_MSG_CHECKING(if tic should use symbolic links) + if test "$ac_cv_func_symlink" = yes ; then + with_symlinks=yes + else + with_symlinks=no + fi + AC_MSG_RESULT($with_symlinks) +elif test "$ac_cv_func_symlink" != yes ; then + AC_MSG_CHECKING(if tic should use hard links) + if test "$ac_cv_func_link" = yes ; then + with_links=yes + else + with_links=no + fi + AC_MSG_RESULT($with_links) +else + AC_MSG_CHECKING(if tic should use symbolic links) + AC_ARG_ENABLE(symlinks, + [ --enable-symlinks make tic use symbolic links not hard links], + [with_symlinks=$enableval], + [with_symlinks=no]) + AC_MSG_RESULT($with_symlinks) +fi + +test "$with_links" = yes && AC_DEFINE(USE_LINKS) +test "$with_symlinks" = yes && AC_DEFINE(USE_SYMLINKS) + +### use option --enable-broken-linker to force on use of broken-linker support +AC_MSG_CHECKING(if you want broken-linker support code) +AC_ARG_ENABLE(broken_linker, + [ --enable-broken_linker compile with broken-linker support code], + [with_broken_linker=$enableval], + [with_broken_linker=$BROKEN_LINKER]) +AC_MSG_RESULT($with_broken_linker) +test "$with_broken_linker" = yes && AC_DEFINE(BROKEN_LINKER) + +### use option --enable-bsdpad to have tputs process BSD-style prefix padding +AC_MSG_CHECKING(if tputs should process BSD-style prefix padding) +AC_ARG_ENABLE(bsdpad, + [ --enable-bsdpad recognize BSD-style prefix padding], + [with_bsdpad=$enableval], + [with_bsdpad=no]) +AC_MSG_RESULT($with_bsdpad) +test "$with_bsdpad" = yes && AC_DEFINE(BSD_TPUTS) + +### Enable compiling-in rcs id's +AC_MSG_CHECKING(if RCS identifiers should be compiled-in) +AC_ARG_WITH(rcs-ids, + [ --with-rcs-ids compile-in RCS identifiers], + [with_rcs_ids=$withval], + [with_rcs_ids=no]) +AC_MSG_RESULT($with_rcs_ids) +test "$with_rcs_ids" = yes && AC_DEFINE(USE_RCS_IDS) + +############################################################################### +CF_MAN_PAGES([ captoinfo clear infocmp infotocap tic toe tput ]) + +############################################################################### +CF_HELP_MESSAGE(Extensions:) + +### Note that some functions (such as const) are normally disabled anyway. +AC_MSG_CHECKING(if you want to build with function extensions) +AC_ARG_ENABLE(ext-funcs, + [ --disable-ext-funcs disable function-extensions], + [with_ext_funcs=$enableval], + [with_ext_funcs=yes]) +AC_MSG_RESULT($with_ext_funcs) +if test "$with_ext_funcs" = yes ; then + AC_DEFINE(HAVE_CURSES_VERSION) + AC_DEFINE(HAVE_HAS_KEY) + AC_DEFINE(HAVE_RESIZETERM) + AC_DEFINE(HAVE_USE_DEFAULT_COLORS) + AC_DEFINE(HAVE_WRESIZE) + AC_DEFINE(NCURSES_EXT_FUNCS) +fi + +### use option --enable-const to turn on use of const beyond that in XSI. +AC_MSG_CHECKING(for extended use of const keyword) +AC_ARG_ENABLE(const, + [ --enable-const compile with extra/non-standard const], + [with_ext_const=$enableval], + [with_ext_const=no]) +AC_MSG_RESULT($with_ext_const) +NCURSES_CONST='/*nothing*/' +if test "$with_ext_const" = yes ; then + NCURSES_CONST=const +fi +AC_SUBST(NCURSES_CONST) + +AC_MSG_CHECKING(if you want \$NCURSES_NO_PADDING code) +AC_ARG_ENABLE(no-padding, + [ --enable-no-padding compile with \$NCURSES_NO_PADDING code], + [with_no_padding=$enableval], + [with_no_padding=$with_ext_funcs]) +AC_MSG_RESULT($with_no_padding) +test "$with_no_padding" = yes && AC_DEFINE(NCURSES_NO_PADDING) + +### use option --enable-sigwinch to turn on use of SIGWINCH logic +AC_MSG_CHECKING(if you want SIGWINCH handler) +AC_ARG_ENABLE(sigwinch, + [ --enable-sigwinch compile with SIGWINCH handler], + [with_sigwinch=$enableval], + [with_sigwinch=$with_ext_funcs]) +AC_MSG_RESULT($with_sigwinch) +test "$with_sigwinch" = yes && AC_DEFINE(USE_SIGWINCH) + +### use option --enable-tcap-names to allow user to define new capabilities +AC_MSG_CHECKING(if you want user-definable terminal capabilities like termcap) +AC_ARG_ENABLE(tcap-names, + [ --enable-tcap-names compile with user-definable terminal capabilities], + [with_tcap_names=$enableval], + [with_tcap_names=$with_ext_funcs]) +AC_MSG_RESULT($with_tcap_names) +NCURSES_XNAMES=0 +test "$with_tcap_names" = yes && NCURSES_XNAMES=1 +AC_SUBST(NCURSES_XNAMES) + +############################################################################### +# These options are relatively safe to experiment with. +CF_HELP_MESSAGE(Development Code:) +AC_MSG_CHECKING(if you want all development code) +AC_ARG_WITH(develop, + [ --with-develop enable all development options], + [with_develop=$withval], + [with_develop=no]) +AC_MSG_RESULT($with_develop) + +### use option --enable-colorfgbg to turn on use of $COLORFGBG environment +AC_MSG_CHECKING(if you want colorfgbg code) +AC_ARG_ENABLE(hard-tabs, + [ --enable-colorfgbg compile with \$COLORFGBG code], + [with_colorfgbg=$enableval], + [with_colorfgbg=$with_develop]) +AC_MSG_RESULT($with_colorfgbg) +test "$with_colorfgbg" = yes && AC_DEFINE(USE_COLORFGBG) + +### use option --enable-hard-tabs to turn on use of hard-tabs optimize +AC_MSG_CHECKING(if you want hard-tabs code) +AC_ARG_ENABLE(hard-tabs, + [ --enable-hard-tabs compile with hard-tabs code], + [with_hardtabs=$enableval], + [with_hardtabs=$with_develop]) +AC_MSG_RESULT($with_hardtabs) +test "$with_hardtabs" = yes && AC_DEFINE(USE_HARD_TABS) + +AC_MSG_CHECKING(if you want to use restrict environment when running as root) +AC_ARG_ENABLE(root-environ, + [ --disable-root-environ limit environment when running as root], + [with_root_environ=$enableval], + [with_root_environ=yes]) +AC_MSG_RESULT($with_root_environ) +test "$with_root_environ" = yes && AC_DEFINE(USE_ROOT_ENVIRON) + +### use option --enable-xmc-glitch to turn on use of magic-cookie optimize +AC_MSG_CHECKING(if you want limited support for xmc) +AC_ARG_ENABLE(xmc-glitch, + [ --enable-xmc-glitch compile with limited support for xmc], + [with_xmc_glitch=$enableval], + [with_xmc_glitch=$with_develop]) +AC_MSG_RESULT($with_xmc_glitch) +test "$with_xmc_glitch" = yes && AC_DEFINE(USE_XMC_SUPPORT) + +############################################################################### +# These are just experimental, probably should not be in a package: +CF_HELP_MESSAGE(Experimental Code:) + +AC_MSG_CHECKING(if you do not want to assume colors are white-on-black) +AC_ARG_ENABLE(assumed-color, + [ --disable-assumed-color do not assume anything about default-colors], + [with_assumed_color=$enableval], + [with_assumed_color=yes]) +AC_MSG_RESULT($with_assumed_color) +test "$with_assumed_color" = yes && AC_DEFINE(USE_ASSUMED_COLOR) + +### use option --enable-hashmap to turn on use of hashmap scrolling logic +AC_MSG_CHECKING(if you want hashmap scrolling-optimization code) +AC_ARG_ENABLE(hashmap, + [ --disable-hashmap compile without hashmap scrolling-optimization], + [with_hashmap=$enableval], + [with_hashmap=yes]) +AC_MSG_RESULT($with_hashmap) +test "$with_hashmap" = yes && AC_DEFINE(USE_HASHMAP) + +AC_MSG_CHECKING(if you want experimental safe-sprintf code) +AC_ARG_ENABLE(safe-sprintf, + [ --enable-safe-sprintf compile with experimental safe-sprintf code], + [with_safe_sprintf=$enableval], + [with_safe_sprintf=no]) +AC_MSG_RESULT($with_safe_sprintf) +test "$with_safe_sprintf" = yes && AC_DEFINE(USE_SAFE_SPRINTF) + +### use option --disable-scroll-hints to turn off use of scroll-hints scrolling logic +# when hashmap is used scroll hints are useless +if test "$with_hashmap" = no ; then +AC_MSG_CHECKING(if you want to experiment without scrolling-hints code) +AC_ARG_ENABLE(scroll-hints, + [ --disable-scroll-hints compile without scroll-hints code], + [with_scroll_hints=$enableval], + [with_scroll_hints=yes]) +AC_MSG_RESULT($with_scroll_hints) +test "$with_scroll_hints" = yes && AC_DEFINE(USE_SCROLL_HINTS) +fi + +### use option --enable-widec to turn on use of wide-character support +AC_MSG_CHECKING(if you want experimental wide-character code) +AC_ARG_ENABLE(widec, + [ --enable-widec compile with experimental wide-char/UTF-8 code], + [with_widec=$enableval], + [with_widec=no]) +AC_MSG_RESULT($with_widec) +if test "$with_widec" = yes ; then + LIB_SUFFIX="w${LIB_SUFFIX}" + AC_DEFINE(USE_WIDEC_SUPPORT) +fi + +############################################################################### +CF_HELP_MESSAGE(Testing/development Options:) + +### use option --disable-echo to suppress full display compiling commands +AC_MSG_CHECKING(if you want to display full commands during build) +AC_ARG_ENABLE(echo, + [ --enable-echo build: display "compiling" commands (default)], + [with_echo=$enableval], + [with_echo=yes]) +if test "$with_echo" = yes; then + ECHO_LINK= +else + ECHO_LINK='@ echo linking $@ ... ;' + test -n "$LIBTOOL" && LIBTOOL="$LIBTOOL --silent" +fi +AC_MSG_RESULT($with_echo) +AC_SUBST(ECHO_LINK) + +### use option --enable-warnings to turn on all gcc warnings +AC_MSG_CHECKING(if you want to see compiler warnings) +AC_ARG_ENABLE(warnings, + [ --enable-warnings build: turn on GCC compiler warnings], + [with_warnings=$enableval]) +AC_MSG_RESULT($with_warnings) + +if test -n "$with_warnings"; then + ADAFLAGS="$ADAFLAGS -gnatg" + CF_GCC_WARNINGS +fi +CF_GCC_ATTRIBUTES + +### use option --enable-assertions to turn on generation of assertion code +AC_MSG_CHECKING(if you want to enable runtime assertions) +AC_ARG_ENABLE(assertions, + [ --enable-assertions test: turn on generation of assertion code], + [with_assertions=$enableval], + [with_assertions=no]) +AC_MSG_RESULT($with_assertions) +if test -n "$GCC" +then + if test "$with_assertions" = no + then + AC_DEFINE(NDEBUG) + CPPFLAGS="$CPPFLAGS -DNDEBUG" + else + ADAFLAGS="$ADAFLAGS -gnata" + fi +fi + +### use option --disable-leaks to suppress "permanent" leaks, for testing +AC_ARG_ENABLE(leaks, + [ --disable-leaks test: suppress permanent memory-leaks], + [test "$enableval" = no && AC_DEFINE(NO_LEAKS)]) +AC_DEFINE(HAVE_NC_ALLOC_H) + +### use option --enable-expanded to generate certain macros as functions +AC_ARG_ENABLE(expanded, + [ --enable-expanded test: generate functions for certain macros], + [test "$enableval" = yes && AC_DEFINE(NCURSES_EXPANDED)]) + +### use option --disable-macros to suppress macros in favor of functions +AC_ARG_ENABLE(macros, + [ --disable-macros test: use functions rather than macros], + [test "$enableval" = no && AC_DEFINE(NCURSES_NOMACROS)]) + +### Checks for libraries. +AC_CHECK_FUNC(gettimeofday, + AC_DEFINE(HAVE_GETTIMEOFDAY),[ + +AC_CHECK_LIB(bsd, gettimeofday, + AC_DEFINE(HAVE_GETTIMEOFDAY) + LIBS="$LIBS -lbsd")])dnl CLIX: bzero, select, gettimeofday + +CF_MATH_LIB(MATH_LIB,sin(x)) +AC_SUBST(MATH_LIB) + +### Checks for header files. +AC_STDC_HEADERS +AC_HEADER_DIRENT +CF_REGEX + +dnl These are some other potentially nonportable headers. +AC_CHECK_HEADERS( \ +fcntl.h \ +getopt.h \ +libc.h \ +limits.h \ +locale.h \ +poll.h \ +sys/bsdtypes.h \ +sys/ioctl.h \ +sys/param.h \ +sys/poll.h \ +sys/select.h \ +sys/time.h \ +sys/times.h \ +ttyent.h \ +unistd.h \ +) + +# check for ISC (this may also define _POSIX_SOURCE) +# Note: even non-Posix ISC needs to declare fd_set +if test "$ISC" = yes ; then + AC_CHECK_LIB(cposix,main) + AC_CHECK_LIB(inet,bzero,LIBS="$LIBS -linet")dnl also 'select()' +fi + +CF_SYS_TIME_SELECT + +### checks for compiler characteristics +AC_LANG_C +AC_C_CONST +AC_C_INLINE +test "$ac_cv_c_inline" != no && AC_DEFINE(CC_HAS_INLINE_FUNCS) + +CF_TYPEOF_CHTYPE +CF_WIDEC_SHIFT + +### Checks for external-data +CF_ERRNO +CF_LINK_DATAONLY + +### Checks for library functions. +AC_CHECK_FUNCS( \ +getcwd \ +getegid \ +geteuid \ +getttynam \ +issetugid \ +memccpy \ +mkstemp \ +nanosleep \ +poll \ +remove \ +select \ +setbuf \ +setbuffer \ +setvbuf \ +sigaction \ +sigvec \ +strdup \ +strstr \ +tcgetpgrp \ +times \ +vfscanf \ +vsnprintf \ +vsscanf \ +) +if test "$with_getcap" = "yes" ; then + CF_CGETENT +fi + +CF_ISASCII +CF_STRUCT_SIGACTION +CF_FUNC_TERMIOS + +dnl FIXME (may need this) AC_SYS_RESTARTABLE_SYSCALLS +if test "$cross_compiling" = yes ; then + AC_MSG_WARN(cross compiling: assume setvbuf params not reversed) +else + AC_FUNC_SETVBUF_REVERSED +fi +AC_TYPE_SIGNAL +CF_TYPE_SIGACTION +CF_SIZECHANGE +CF_FUNC_MEMMOVE +CF_FUNC_POLL + +dnl We'll do our own -g libraries, unless the user's overridden via $CFLAGS +if test -z "$cf_user_CFLAGS" ; then + CF_STRIP_G_OPT(CFLAGS) + CF_STRIP_G_OPT(CXXFLAGS) +fi + +dnl Check for C++ compiler characteristics (and ensure that it's there!) +CF_BOOL_DECL(cf_cv_cc_bool_type) +if test -n "$CXX" ; then + AC_LANG_CPLUSPLUS + CF_STDCPP_LIBRARY + if test "$GXX" = yes; then + case "`${CXX-g++} --version`" in + 1*|2.[0-6]*) + cf_cxx_library=yes + ;; + 2.7*) + CF_GPP_LIBRARY + ;; + *) + cf_cxx_library=no + ;; + esac + else + cf_cxx_library=no + fi + AC_CHECK_HEADERS(typeinfo) + CF_BOOL_DECL + CF_BOOL_SIZE + CF_ETIP_DEFINES + CF_CPP_PARAM_INIT + case $cf_cv_system_name in #(vi + sco3.2v5*) + CXXLDFLAGS="-u main" + ;; + esac + AC_SUBST(CXXLDFLAGS) +else + cf_cxx_library=no + cf_cv_builtin_bool=1 + + # Just because we are not configuring against C++ right now does not + # mean that a user will not want to use C++. Some distributors disable + # the C++ portion of this configuration as a shortcut (or just to avoid + # compiling the demo in the c++ directory). So we need a reasonable + # default for the 'bool' type. + # + # Caveat: since the storage of the bool type is not standardized, it + # may change. + + AC_MSG_CHECKING(for fallback type of bool) + case "$host_cpu" in #(vi + i?86) cf_cv_type_of_bool=char ;; #(vi + *) cf_cv_type_of_bool=int ;; + esac + AC_MSG_RESULT($cf_cv_type_of_bool) +fi +AC_SUBST(CXXLIBS) + +CF_HELP_MESSAGE(Ada95 Binding Options:) + +dnl Check for availability of GNU Ada Translator (GNAT). +dnl At the moment we support no other Ada95 compiler. +if test "$cf_with_ada" != "no" ; then +cf_ada_make=gnatmake +AC_CHECK_PROG(gnat_exists, $cf_ada_make, yes, no) +if test "$ac_cv_prog_gnat_exists" = no; then + cf_ada_make= +else + CF_GNAT_VERSION + AC_CHECK_PROG(M4_exists, m4, yes, no) + if test "$ac_cv_prog_M4_exists" = no; then + cf_cv_prog_gnat_correct=no + echo Ada95 binding required program m4 not found. Ada95 binding disabled. + fi + if test "$cf_cv_prog_gnat_correct" = yes; then + AC_MSG_CHECKING(if GNAT works) + CF_GNAT_TRY_RUN([procedure conftest;], +[with Text_IO; +with GNAT.OS_Lib; +procedure conftest is +begin + Text_IO.Put ("Hello World"); + Text_IO.New_Line; + GNAT.OS_Lib.OS_Exit (0); +end conftest;],[cf_cv_prog_gnat_correct=yes],[cf_cv_prog_gnat_correct=no]) + AC_MSG_RESULT($cf_cv_prog_gnat_correct) + fi +fi +if test "$cf_cv_prog_gnat_correct" = yes; then + ADAFLAGS="-O3 -gnatpn $ADAFLAGS" + + AC_ARG_WITH(ada-compiler, + [ --with-ada-compiler=CMD specify Ada95 compiler command (default gnatmake)], + [cf_ada_compiler=$withval], + [cf_ada_compiler=gnatmake]) + + cf_ada_package=terminal_interface + + AC_SUBST(cf_ada_make) + AC_SUBST(cf_ada_compiler) + AC_SUBST(cf_ada_package) + AC_SUBST(ADAFLAGS) + AC_SUBST(cf_compile_generics) + AC_SUBST(cf_generic_objects) + + CF_WITH_PATH(ada-include, + [ --with-ada-include=DIR Ada includes are in DIR], + ADA_INCLUDE, + PREFIX/lib/ada/adainclude, + [$]prefix/lib/ada/adainclude) + AC_SUBST(ADA_INCLUDE) + + CF_WITH_PATH(ada-objects, + [ --with-ada-objects=DIR Ada objects are in DIR], + ADA_OBJECTS, + PREFIX/lib/ada/adalib, + [$]prefix/lib/ada/adalib) + AC_SUBST(ADA_OBJECTS) + +fi +fi + +### It's not possible to appease gcc 2.6.3's conversion-warnings if we're +### using a 'char' for bools. gcc 2.7.0's conversion-warnings are broken too +### badly to consider using for development purposes, but 2.5.8 is okay. +if test -n "$with_warnings"; then + if test "$GCC" = yes; then + case "`$CC --version`" in + 2.6.3) + if test "$cf_cv_type_of_bool" != "char"; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wconversion" + fi + ;; + 2.5*) + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wconversion" + ;; + esac + fi +fi + +### Construct the library-subsets, if any, from this set of keywords: +### none, base, ext_funcs, termlib. +AC_MSG_CHECKING(for library subsets) +if test "$with_termlib" = yes ; then + LIB_SUBSETS="termlib " +else + LIB_SUBSETS="termlib+" +fi +LIB_SUBSETS="${LIB_SUBSETS}base" +test "$with_ext_funcs" = yes && LIB_SUBSETS="${LIB_SUBSETS}+ext_funcs" +AC_MSG_RESULT($LIB_SUBSETS) + +LIB_TRACING=DEBUG +case "$CFLAGS" in +*-DTRACE*) + LIB_TRACING=all + ;; +esac + +### Construct the list of include-directories to be generated +CF_INCLUDE_DIRS +CF_ADA_INCLUDE_DIRS + +### Build up pieces for makefile rules +AC_MSG_CHECKING(default library suffix) +CF_LIB_TYPE($DFT_LWR_MODEL,DFT_ARG_SUFFIX)dnl +AC_SUBST(DFT_ARG_SUFFIX)dnl the string to append to "-lncurses" ("") +AC_MSG_RESULT($DFT_ARG_SUFFIX) + +AC_MSG_CHECKING(default library-dependency suffix) +CF_LIB_SUFFIX($DFT_LWR_MODEL,DFT_DEP_SUFFIX)dnl +AC_SUBST(DFT_DEP_SUFFIX)dnl the corresponding library-suffix (".a") +AC_MSG_RESULT($DFT_DEP_SUFFIX) + +AC_MSG_CHECKING(default object directory) +CF_OBJ_SUBDIR($DFT_LWR_MODEL,DFT_OBJ_SUBDIR)dnl +AC_SUBST(DFT_OBJ_SUBDIR)dnl the default object-directory ("obj") +AC_MSG_RESULT($DFT_OBJ_SUBDIR) + +# libtool thinks it can make c++ shared libraries (perhaps only g++) +AC_MSG_CHECKING(c++ library-dependency suffux) +if test "$with_libtool" = "yes"; then + CXX_LIB_SUFFIX=$DFT_DEP_SUFFIX +else + CF_LIB_SUFFIX(normal,CXX_LIB_SUFFIX)dnl we normally make a static library +fi +AC_MSG_RESULT($CXX_LIB_SUFFIX) +AC_SUBST(CXX_LIB_SUFFIX) + +TINFO_LIST="$SHLIB_LIST" +test "$with_termlib" = yes && SHLIB_LIST="$SHLIB_LIST -ltinfo${LIB_SUFFIX}" + +AC_MSG_CHECKING(where we will install curses.h) +test "$with_overwrite" = no && \ +test "x$includedir" = 'x${prefix}/include' && \ + includedir='$(prefix)/include/ncurses'${LIB_SUFFIX} +AC_MSG_RESULT($includedir) + +AC_SUBST(EXTRA_LIBS) +AC_SUBST(TINFO_LIST) +AC_SUBST(SHLIB_LIST) + +### Set up low-level terminfo dependencies for makefiles. Note that we +### could override this. +if test "$with_termlib" = yes ; then + TEST_DEPS="${LIB_DIR}/${LIB_PREFIX}${TINFO_NAME}${DFT_DEP_SUFFIX}" + if test "$DFT_LWR_MODEL" = "libtool"; then + TEST_ARGS="${TEST_DEPS}" + else + TEST_ARGS="-l${TINFO_NAME}${DFT_ARG_SUFFIX}" + fi +fi +PROG_DEPS="$TEST_DEPS" +PROG_ARGS="$TEST_ARGS" + +### Construct the list of subdirectories for which we'll customize makefiles +### with the appropriate compile-rules. + +CF_SRC_MODULES($modules_to_build) +CF_DIRS_TO_MAKE + +### Now that we're done running tests, add the compiler-warnings, if any +CFLAGS="$CFLAGS $EXTRA_CFLAGS" + +################################################################################ +AC_OUTPUT( \ + include/MKterm.h.awk \ + include/curses.h \ + include/termcap.h \ + include/unctrl.h \ + misc/run_tic.sh:misc/run_tic.in \ + $SUB_MAKEFILES \ + Makefile,[ +CF_LIB_RULES +],[ +### Special initialization commands, used to pass information from the +### configuration-run into config.status + +AWK="$AWK" +CF_LIST_MODELS="$cf_list_models" +DFT_LWR_MODEL="$DFT_LWR_MODEL" +LDCONFIG="$LDCONFIG" +LIB_NAME="$LIB_NAME" +LIB_SUFFIX="$LIB_SUFFIX" +LIB_SUBSETS="$LIB_SUBSETS" +LIB_TRACING="$LIB_TRACING" +SRC_SUBDIRS="$SRC_SUBDIRS" +TERMINFO="$TERMINFO" +TINFO_NAME="$TINFO_NAME" +WITH_ECHO="$with_echo" +WITH_OVERWRITE="$with_overwrite" +WITH_CURSES_H="$with_curses_h" +cf_cv_abi_version="$cf_cv_abi_version" +cf_cv_do_symlinks="$cf_cv_do_symlinks" +cf_cv_rel_version="$cf_cv_rel_version" +cf_cv_rm_so_locs="$cf_cv_rm_so_locs" +cf_cv_system_name="$cf_cv_system_name" +cf_with_cxx_binding="$cf_with_cxx_binding" +cf_cv_shlib_version="$cf_cv_shlib_version" +target="$target" + +],sort)dnl +${MAKE-make} preinstall diff --git a/ncurses-5.2/convert_configure.pl b/ncurses-5.2/convert_configure.pl new file mode 100644 index 0000000..dea92ca --- /dev/null +++ b/ncurses-5.2/convert_configure.pl @@ -0,0 +1,90 @@ +extproc perl -S -w + +# The converted script is written to stdout, so run this script as +# convert_configure configure > configure.cmd +# +# When the converted script runs, it expects that /tmp dir is +# available (so we create it). +# +# run the result like this: +# .\configure + +# Some frequent manual intervention: +# a) Some makefiles hardwire SHELL = /bin/sh ==> change to: sh +# b) Some makefiles recognize that exe files terminate on .exe +# You need to give this script -no-zexe option... + +shift, $no_zexe = 1 if @ARGV and $ARGV[0] eq '-no-zexe'; + +mkdir '/tmp', 0777 unless -d '/tmp'; + +print <) { + if (/for\s+(\w+)\s+in\s*\$(PATH|ac_dummy)\s*;/) { + $checking_path = 1; + $varname = $1; + $subst= < $@ + +ANNOUNCE : doc/html/announce.html + $(DUMP) doc/html/announce.html > $@ + +doc/ncurses-intro.doc: doc/html/ncurses-intro.html + $(DUMP2) doc/html/ncurses-intro.html > $@ +doc/hackguide.doc: doc/html/hackguide.html + $(DUMP2) doc/html/hackguide.html > $@ + +MANPROG = tbl | nroff -man + +manhtml: MANIFEST + @rm -f doc/html/man/*.html + @mkdir -p doc/html/man + @rm -f subst.tmp ; + @for f in man/*.[0-9]*; do \ + m=`basename $$f` ;\ + x=`echo $$m | awk -F. '{print $$2;}'` ;\ + xu=`echo $$x | dd conv=ucase 2>/dev/null` ;\ + if [ "$${x}" != "$${xu}" ]; then \ + echo "s/$${xu}/$${x}/g" >> subst.tmp ;\ + fi ;\ + done + @sort < subst.tmp | uniq > subst.sed + @rm -f subst.tmp + @for f in man/*.[0-9]* ; do \ + m=`basename $$f` ;\ + g=$${m}.html ;\ + if [ -f doc/html/$$g ]; then chmod +w doc/html/$$g; fi;\ + echo "Converting $$m to HTML" ;\ + man/edit_man.sh editing /usr/man man $$f | $(MANPROG) | tr '\255' '-' | $(MAN2HTML) | \ + sed -f subst.sed |\ + sed -e 's/"curses.3x.html"/"ncurses.3x.html"/g' \ + > doc/html/man/$$g ;\ + done + @rm -f subst.sed + @sed -e "\%./doc/html/man/%d" < MANIFEST > MANIFEST.tmp + @find ./doc/html/man -type f -print >> MANIFEST.tmp + @chmod u+w MANIFEST + @sort -u < MANIFEST.tmp > MANIFEST + @rm -f MANIFEST.tmp + +# +# Please note that this target can only be properly built if the build of the +# Ada95 subdir has been done. The reason is, that the gnathtml tool uses the +# .ali files generated by the Ada95 compiler during the build process. These +# .ali files contain cross referencing information required by gnathtml. +adahtml: MANIFEST + if [ ! -z "$(GNATHTML)" ]; then \ + (cd ./Ada95/gen ; make html) ;\ + sed -e "\%./doc/html/ada/%d" < MANIFEST > MANIFEST.tmp ;\ + find ./doc/html/ada -type f -print >> MANIFEST.tmp ;\ + sort -u < MANIFEST.tmp > MANIFEST ;\ + rm -f MANIFEST.tmp ;\ + fi + +# Prepare distribution for version control +vcprepare: + find . -type d -exec mkdir {}/RCS \; + +# Write-lock almost all files not under version control. +ADA_EXCEPTIONS=$(shell eval 'a="\\\\\|";for x in Ada95/gen/terminal*.m4; do echo -n $${a}Ada95/ada_include/`basename $${x} .m4`; done') +EXCEPTIONS = 'announce.html$\\|ANNOUNCE\\|misc/.*\\.doc\\|man/terminfo.5\\|lib_gen.c'$(ADA_EXCEPTIONS) +writelock: + for x in `grep -v $(EXCEPTIONS) MANIFEST`; do if [ ! -f `dirname $$x`/RCS/`basename $$x`,v ]; then chmod a-w $${x}; fi; done + +# This only works on a clean source tree, of course. +MANIFEST: + -rm -f $@ + touch $@ + find . -type f -print |sort | fgrep -v .lsm |fgrep -v .spec >$@ + +TAGS: + etags */*.[ch] + +# Makefile ends here diff --git a/ncurses-5.2/doc/hackguide.doc b/ncurses-5.2/doc/hackguide.doc new file mode 100644 index 0000000..e9828d2 --- /dev/null +++ b/ncurses-5.2/doc/hackguide.doc @@ -0,0 +1,687 @@ + + A Hacker's Guide to NCURSES + + Contents + + * Abstract + * Objective of the Package + + Why System V Curses? + + How to Design Extensions + * Portability and Configuration + * Documentation Conventions + * How to Report Bugs + * A Tour of the Ncurses Library + + Library Overview + + The Engine Room + + Keyboard Input + + Mouse Events + + Output and Screen Updating + * The Forms and Menu Libraries + * A Tour of the Terminfo Compiler + + Translation of Non-use Capabilities + + Use Capability Resolution + + Source-Form Translation + * Other Utilities + * Style Tips for Developers + * Porting Hints + + Abstract + + This document is a hacker's tour of the ncurses library and utilities. + It discusses design philosophy, implementation methods, and the + conventions used for coding and documentation. It is recommended + reading for anyone who is interested in porting, extending or + improving the package. + + Objective of the Package + + The objective of the ncurses package is to provide a free software API + for character-cell terminals and terminal emulators with the following + characteristics: + * Source-compatible with historical curses implementations + (including the original BSD curses and System V curses. + * Conformant with the XSI Curses standard issued as part of XPG4 by + X/Open. + * High-quality -- stable and reliable code, wide portability, good + packaging, superior documentation. + * Featureful -- should eliminate as much of the drudgery of C + interface programming as possible, freeing programmers to think at + a higher level of design. + + These objectives are in priority order. So, for example, source + compatibility with older version must trump featurefulness -- we + cannot add features if it means breaking the portion of the API + corresponding to historical curses versions. + +Why System V Curses? + + We used System V curses as a model, reverse-engineering their API, in + order to fulfill the first two objectives. + + System V curses implementations can support BSD curses programs with + just a recompilation, so by capturing the System V API we also capture + BSD's. + + More importantly for the future, the XSI Curses standard issued by + X/Open is explicitly and closely modeled on System V. So conformance + with System V took us most of the way to base-level XSI conformance. + +How to Design Extensions + + The third objective (standards conformance) requires that it be easy + to condition source code using ncurses so that the absence of + nonstandard extensions does not break the code. + + Accordingly, we have a policy of associating with each nonstandard + extension a feature macro, so that ncurses client code can use this + macro to condition in or out the code that requires the ncurses + extension. + + For example, there is a macro NCURSES_MOUSE_VERSION which XSI Curses + does not define, but which is defined in the ncurses library header. + You can use this to condition the calls to the mouse API calls. + + Portability and Configuration + + Code written for ncurses may assume an ANSI-standard C compiler and + POSIX-compatible OS interface. It may also assume the presence of a + System-V-compatible select(2) call. + + We encourage (but do not require) developers to make the code friendly + to less-capable UNIX environments wherever possible. + + We encourage developers to support OS-specific optimizations and + methods not available under POSIX/ANSI, provided only that: + * All such code is properly conditioned so the build process does + not attempt to compile it under a plain ANSI/POSIX environment. + * Adding such implementation methods does not introduce + incompatibilities in the ncurses API between platforms. + + We use GNU autoconf(1) as a tool to deal with portability issues. The + right way to leverage an OS-specific feature is to modify the autoconf + specification files (configure.in and aclocal.m4) to set up a new + feature macro, which you then use to condition your code. + + Documentation Conventions + + There are three kinds of documentation associated with this package. + Each has a different preferred format: + * Package-internal files (README, INSTALL, TO-DO etc.) + * Manual pages. + * Everything else (i.e., narrative documentation). + + Our conventions are simple: + 1. Maintain package-internal files in plain text. The expected viewer + for them more(1) or an editor window; there's no point in + elaborate mark-up. + 2. Mark up manual pages in the man macros. These have to be viewable + through traditional man(1) programs. + 3. Write everything else in HTML. + + When in doubt, HTMLize a master and use lynx(1) to generate plain + ASCII (as we do for the announcement document). + + The reason for choosing HTML is that it's (a) well-adapted for on-line + browsing through viewers that are everywhere; (b) more easily readable + as plain text than most other mark-ups, if you don't have a viewer; + and (c) carries enough information that you can generate a + nice-looking printed version from it. Also, of course, it make + exporting things like the announcement document to WWW pretty trivial. + + How to Report Bugs + + The reporting address for bugs is bug-ncurses@gnu.org. This is a + majordomo list; to join, write to bug-ncurses-request@gnu.org with a + message containing the line: + subscribe @ + + The ncurses code is maintained by a small group of volunteers. While + we try our best to fix bugs promptly, we simply don't have a lot of + hours to spend on elementary hand-holding. We rely on intelligent + cooperation from our users. If you think you have found a bug in + ncurses, there are some steps you can take before contacting us that + will help get the bug fixed quickly. + + In order to use our bug-fixing time efficiently, we put people who + show us they've taken these steps at the head of our queue. This means + that if you don't, you'll probably end up at the tail end and have to + wait a while. + 1. Develop a recipe to reproduce the bug. + Bugs we can reproduce are likely to be fixed very quickly, often + within days. The most effective single thing you can do to get a + quick fix is develop a way we can duplicate the bad behavior -- + ideally, by giving us source for a small, portable test program + that breaks the library. (Even better is a keystroke recipe using + one of the test programs provided with the distribution.) + 2. Try to reproduce the bug on a different terminal type. + In our experience, most of the behaviors people report as library + bugs are actually due to subtle problems in terminal descriptions. + This is especially likely to be true if you're using a traditional + asynchronous terminal or PC-based terminal emulator, rather than + xterm or a UNIX console entry. + It's therefore extremely helpful if you can tell us whether or not + your problem reproduces on other terminal types. Usually you'll + have both a console type and xterm available; please tell us + whether or not your bug reproduces on both. + If you have xterm available, it is also good to collect xterm + reports for different window sizes. This is especially true if you + normally use an unusual xterm window size -- a surprising number + of the bugs we've seen are either triggered or masked by these. + 3. Generate and examine a trace file for the broken behavior. + Recompile your program with the debugging versions of the + libraries. Insert a trace() call with the argument set to + TRACE_UPDATE. (See "Writing Programs with NCURSES" for details on + trace levels.) Reproduce your bug, then look at the trace file to + see what the library was actually doing. + Another frequent cause of apparent bugs is application coding + errors that cause the wrong things to be put on the virtual + screen. Looking at the virtual-screen dumps in the trace file will + tell you immediately if this is happening, and save you from the + possible embarrassment of being told that the bug is in your code + and is your problem rather than ours. + If the virtual-screen dumps look correct but the bug persists, + it's possible to crank up the trace level to give more and more + information about the library's update actions and the control + sequences it issues to perform them. The test directory of the + distribution contains a tool for digesting these logs to make them + less tedious to wade through. + Often you'll find terminfo problems at this stage by noticing that + the escape sequences put out for various capabilities are wrong. + If not, you're likely to learn enough to be able to characterize + any bug in the screen-update logic quite exactly. + 4. Report details and symptoms, not just interpretations. + If you do the preceding two steps, it is very likely that you'll + discover the nature of the problem yourself and be able to send us + a fix. This will create happy feelings all around and earn you + good karma for the first time you run into a bug you really can't + characterize and fix yourself. + If you're still stuck, at least you'll know what to tell us. + Remember, we need details. If you guess about what is safe to + leave out, you are too likely to be wrong. + If your bug produces a bad update, include a trace file. Try to + make the trace at the least voluminous level that pins down the + bug. Logs that have been through tracemunch are OK, it doesn't + throw away any information (actually they're better than + un-munched ones because they're easier to read). + If your bug produces a core-dump, please include a symbolic stack + trace generated by gdb(1) or your local equivalent. + Tell us about every terminal on which you've reproduced the bug -- + and every terminal on which you can't. Ideally, sent us terminfo + sources for all of these (yours might differ from ours). + Include your ncurses version and your OS/machine type, of course! + You can find your ncurses version in the curses.h file. + + If your problem smells like a logic error or in cursor movement or + scrolling or a bad capability, there are a couple of tiny test frames + for the library algorithms in the progs directory that may help you + isolate it. These are not part of the normal build, but do have their + own make productions. + + The most important of these is mvcur, a test frame for the + cursor-movement optimization code. With this program, you can see + directly what control sequences will be emitted for any given cursor + movement or scroll/insert/delete operations. If you think you've got a + bad capability identified, you can disable it and test again. The + program is command-driven and has on-line help. + + If you think the vertical-scroll optimization is broken, or just want + to understand how it works better, build hashmap and read the header + comments of hardscroll.c and hashmap.c; then try it out. You can also + test the hardware-scrolling optimization separately with hardscroll. + + There's one other interactive tester, tctest, that exercises + translation between termcap and terminfo formats. If you have a + serious need to run this, you probably belong on our development team! + + A Tour of the Ncurses Library + +Library Overview + + Most of the library is superstructure -- fairly trivial convenience + interfaces to a small set of basic functions and data structures used + to manipulate the virtual screen (in particular, none of this code + does any I/O except through calls to more fundamental modules + described below). The files + + lib_addch.c lib_bkgd.c lib_box.c lib_chgat.c lib_clear.c + lib_clearok.c lib_clrbot.c lib_clreol.c lib_colorset.c lib_data.c + lib_delch.c lib_delwin.c lib_echo.c lib_erase.c lib_gen.c + lib_getstr.c lib_hline.c lib_immedok.c lib_inchstr.c lib_insch.c + lib_insdel.c lib_insstr.c lib_instr.c lib_isendwin.c lib_keyname.c + lib_leaveok.c lib_move.c lib_mvwin.c lib_overlay.c lib_pad.c + lib_printw.c lib_redrawln.c lib_scanw.c lib_screen.c lib_scroll.c + lib_scrollok.c lib_scrreg.c lib_set_term.c lib_slk.c + lib_slkatr_set.c lib_slkatrof.c lib_slkatron.c lib_slkatrset.c + lib_slkattr.c lib_slkclear.c lib_slkcolor.c lib_slkinit.c + lib_slklab.c lib_slkrefr.c lib_slkset.c lib_slktouch.c lib_touch.c + lib_unctrl.c lib_vline.c lib_wattroff.c lib_wattron.c lib_window.c + + are all in this category. They are very unlikely to need change, + barring bugs or some fundamental reorganization in the underlying data + structures. + + These files are used only for debugging support: + + lib_trace.c lib_traceatr.c lib_tracebits.c lib_tracechr.c + lib_tracedmp.c lib_tracemse.c trace_buf.c + + It is rather unlikely you will ever need to change these, unless you + want to introduce a new debug trace level for some reasoon. + + There is another group of files that do direct I/O via tputs(), + computations on the terminal capabilities, or queries to the OS + environment, but nevertheless have only fairly low complexity. These + include: + + lib_acs.c lib_beep.c lib_color.c lib_endwin.c lib_initscr.c + lib_longname.c lib_newterm.c lib_options.c lib_termcap.c lib_ti.c + lib_tparm.c lib_tputs.c lib_vidattr.c read_entry.c. + + They are likely to need revision only if ncurses is being ported to an + environment without an underlying terminfo capability representation. + + These files have serious hooks into the tty driver and signal + facilities: + + lib_kernel.c lib_baudrate.c lib_raw.c lib_tstp.c lib_twait.c + + If you run into porting snafus moving the package to another UNIX, the + problem is likely to be in one of these files. The file lib_print.c + uses sleep(2) and also falls in this category. + + Almost all of the real work is done in the files + + hardscroll.c hashmap.c lib_addch.c lib_doupdate.c lib_getch.c + lib_mouse.c lib_mvcur.c lib_refresh.c lib_setup.c lib_vidattr.c + + Most of the algorithmic complexity in the library lives in these + files. If there is a real bug in ncurses itself, it's probably here. + We'll tour some of these files in detail below (see The Engine Room). + + Finally, there is a group of files that is actually most of the + terminfo compiler. The reason this code lives in the ncurses library + is to support fallback to /etc/termcap. These files include + + alloc_entry.c captoinfo.c comp_captab.c comp_error.c comp_hash.c + comp_parse.c comp_scan.c parse_entry.c read_termcap.c write_entry.c + + We'll discuss these in the compiler tour. + +The Engine Room + + Keyboard Input + + All ncurses input funnels through the function wgetch(), defined in + lib_getch.c. This function is tricky; it has to poll for keyboard and + mouse events and do a running match of incoming input against the set + of defined special keys. + + The central data structure in this module is a FIFO queue, used to + match multiple-character input sequences against special-key + capabilities; also to implement pushback via ungetch(). + + The wgetch() code distinguishes between function key sequences and the + same sequences typed manually by doing a timed wait after each input + character that could lead a function key sequence. If the entire + sequence takes less than 1 second, it is assumed to have been + generated by a function key press. + + Hackers bruised by previous encounters with variant select(2) calls + may find the code in lib_twait.c interesting. It deals with the + problem that some BSD selects don't return a reliable time-left value. + The function timed_wait() effectively simulates a System V select. + + Mouse Events + + If the mouse interface is active, wgetch() polls for mouse events each + call, before it goes to the keyboard for input. It is up to + lib_mouse.c how the polling is accomplished; it may vary for different + devices. + + Under xterm, however, mouse event notifications come in via the + keyboard input stream. They are recognized by having the kmous + capability as a prefix. This is kind of klugey, but trying to wire in + recognition of a mouse key prefix without going through the + function-key machinery would be just too painful, and this turns out + to imply having the prefix somewhere in the function-key capabilities + at terminal-type initialization. + + This kluge only works because kmous isn't actually used by any + historic terminal type or curses implementation we know of. Best guess + is it's a relic of some forgotten experiment in-house at Bell Labs + that didn't leave any traces in the publicly-distributed System V + terminfo files. If System V or XPG4 ever gets serious about using it + again, this kluge may have to change. + + Here are some more details about mouse event handling: + + The lib_mouse()code is logically split into a lower level that accepts + event reports in a device-dependent format and an upper level that + parses mouse gestures and filters events. The mediating data structure + is a circular queue of event structures. + + Functionally, the lower level's job is to pick up primitive events and + put them on the circular queue. This can happen in one of two ways: + either (a) _nc_mouse_event() detects a series of incoming mouse + reports and queues them, or (b) code in lib_getch.c detects the kmous + prefix in the keyboard input stream and calls _nc_mouse_inline to + queue up a series of adjacent mouse reports. + + In either case, _nc_mouse_parse() should be called after the series is + accepted to parse the digested mouse reports (low-level events) into a + gesture (a high-level or composite event). + + Output and Screen Updating + + With the single exception of character echoes during a wgetnstr() call + (which simulates cooked-mode line editing in an ncurses window), the + library normally does all its output at refresh time. + + The main job is to go from the current state of the screen (as + represented in the curscr window structure) to the desired new state + (as represented in the newscr window structure), while doing as little + I/O as possible. + + The brains of this operation are the modules hashmap.c, hardscroll.c + and lib_doupdate.c; the latter two use lib_mvcur.c. Essentially, what + happens looks like this: + + The hashmap.c module tries to detect vertical motion changes between + the real and virtual screens. This information is represented by the + oldindex members in the newscr structure. These are modified by + vertical-motion and clear operations, and both are re-initialized + after each update. To this change-journalling information, the hashmap + code adds deductions made using a modified Heckel algorithm on hash + values generated from the line contents. + + The hardscroll.c module computes an optimum set of scroll, insertion, + and deletion operations to make the indices match. It calls + _nc_mvcur_scrolln() in lib_mvcur.c to do those motions. + + Then lib_doupdate.c goes to work. Its job is to do line-by-line + transformations of curscr lines to newscr lines. Its main tool is the + routine mvcur() in lib_mvcur.c. This routine does cursor-movement + optimization, attempting to get from given screen location A to given + location B in the fewest output characters posible. + + If you want to work on screen optimizations, you should use the fact + that (in the trace-enabled version of the library) enabling the + TRACE_TIMES trace level causes a report to be emitted after each + screen update giving the elapsed time and a count of characters + emitted during the update. You can use this to tell when an update + optimization improves efficiency. + + In the trace-enabled version of the library, it is also possible to + disable and re-enable various optimizations at runtime by tweaking the + variable _nc_optimize_enable. See the file include/curses.h.in for + mask values, near the end. + + The Forms and Menu Libraries + + The forms and menu libraries should work reliably in any environment + you can port ncurses to. The only portability issue anywhere in them + is what flavor of regular expressions the built-in form field type + TYPE_REGEXP will recognize. + + The configuration code prefers the POSIX regex facility, modeled on + System V's, but will settle for BSD regexps if the former isn't + available. + + Historical note: the panels code was written primarily to assist in + porting u386mon 2.0 (comp.sources.misc v14i001-4) to systems lacking + panels support; u386mon 2.10 and beyond use it. This version has been + slightly cleaned up for ncurses. + + A Tour of the Terminfo Compiler + + The ncurses implementation of tic is rather complex internally; it has + to do a trying combination of missions. This starts with the fact + that, in addition to its normal duty of compiling terminfo sources + into loadable terminfo binaries, it has to be able to handle termcap + syntax and compile that too into terminfo entries. + + The implementation therefore starts with a table-driven, dual-mode + lexical analyzer (in comp_scan.c). The lexer chooses its mode (termcap + or terminfo) based on the first `,' or `:' it finds in each entry. The + lexer does all the work of recognizing capability names and values; + the grammar above it is trivial, just "parse entries till you run out + of file". + +Translation of Non-use Capabilities + + Translation of most things besides use capabilities is pretty + straightforward. The lexical analyzer's tokenizer hands each + capability name to a hash function, which drives a table lookup. The + table entry yields an index which is used to look up the token type in + another table, and controls interpretation of the value. + + One possibly interesting aspect of the implementation is the way the + compiler tables are initialized. All the tables are generated by + various awk/sed/sh scripts from a master table include/Caps; these + scripts actually write C initializers which are linked to the + compiler. Furthermore, the hash table is generated in the same way, so + it doesn't have to be generated at compiler startup time (another + benefit of this organization is that the hash table can be in + shareable text space). + + Thus, adding a new capability is usually pretty trivial, just a matter + of adding one line to the include/Caps file. We'll have more to say + about this in the section on Source-Form Translation. + +Use Capability Resolution + + The background problem that makes tic tricky isn't the capability + translation itself, it's the resolution of use capabilities. Older + versions would not handle forward use references for this reason (that + is, a using terminal always had to follow its use target in the source + file). By doing this, they got away with a simple implementation + tactic; compile everything as it blows by, then resolve uses from + compiled entries. + + This won't do for ncurses. The problem is that that the whole + compilation process has to be embeddable in the ncurses library so + that it can be called by the startup code to translate termcap entries + on the fly. The embedded version can't go promiscuously writing + everything it translates out to disk -- for one thing, it will + typically be running with non-root permissions. + + So our tic is designed to parse an entire terminfo file into a + doubly-linked circular list of entry structures in-core, and then do + use resolution in-memory before writing everything out. This design + has other advantages: it makes forward and back use-references equally + easy (so we get the latter for free), and it makes checking for name + collisions before they're written out easy to do. + + And this is exactly how the embedded version works. But the + stand-alone user-accessible version of tic partly reverts to the + historical strategy; it writes to disk (not keeping in core) any entry + with no use references. + + This is strictly a core-economy kluge, implemented because the + terminfo master file is large enough that some core-poor systems swap + like crazy when you compile it all in memory...there have been reports + of this process taking three hours, rather than the twenty seconds or + less typical on the author's development box. + + So. The executable tic passes the entry-parser a hook that immediately + writes out the referenced entry if it has no use capabilities. The + compiler main loop refrains from adding the entry to the in-core list + when this hook fires. If some other entry later needs to reference an + entry that got written immediately, that's OK; the resolution code + will fetch it off disk when it can't find it in core. + + Name collisions will still be detected, just not as cleanly. The + write_entry() code complains before overwriting an entry that + postdates the time of tic's first call to write_entry(), Thus it will + complain about overwriting entries newly made during the tic run, but + not about overwriting ones that predate it. + +Source-Form Translation + + Another use of tic is to do source translation between various termcap + and terminfo formats. There are more variants out there than you might + think; the ones we know about are described in the captoinfo(1) manual + page. + + The translation output code (dump_entry() in ncurses/dump_entry.c) is + shared with the infocmp(1) utility. It takes the same internal + representation used to generate the binary form and dumps it to + standard output in a specified format. + + The include/Caps file has a header comment describing ways you can + specify source translations for nonstandard capabilities just by + altering the master table. It's possible to set up capability aliasing + or tell the compiler to plain ignore a given capability without + writing any C code at all. + + For circumstances where you need to do algorithmic translation, there + are functions in parse_entry.c called after the parse of each entry + that are specifically intended to encapsulate such translations. This, + for example, is where the AIX box1 capability get translated to an + acsc string. + + Other Utilities + + The infocmp utility is just a wrapper around the same entry-dumping + code used by tic for source translation. Perhaps the one interesting + aspect of the code is the use of a predicate function passed in to + dump_entry() to control which capabilities are dumped. This is + necessary in order to handle both the ordinary De-compilation case and + entry difference reporting. + + The tput and clear utilities just do an entry load followed by a + tputs() of a selected capability. + + Style Tips for Developers + + See the TO-DO file in the top-level directory of the source + distribution for additions that would be particularly useful. + + The prefix _nc_ should be used on library public functions that are + not part of the curses API in order to prevent pollution of the + application namespace. If you have to add to or modify the function + prototypes in curses.h.in, read ncurses/MKlib_gen.sh first so you can + avoid breaking XSI conformance. Please join the ncurses mailing list. + See the INSTALL file in the top level of the distribution for details + on the list. + + Look for the string FIXME in source files to tag minor bugs and + potential problems that could use fixing. + + Don't try to auto-detect OS features in the main body of the C code. + That's the job of the configuration system. + + To hold down complexity, do make your code data-driven. Especially, if + you can drive logic from a table filtered out of include/Caps, do it. + If you find you need to augment the data in that file in order to + generate the proper table, that's still preferable to ad-hoc code -- + that's why the fifth field (flags) is there. + + Have fun! + + Porting Hints + + The following notes are intended to be a first step towards DOS and + Macintosh ports of the ncurses libraries. + + The following library modules are `pure curses'; they operate only on + the curses internal structures, do all output through other curses + calls (not including tputs() and putp()) and do not call any other + UNIX routines such as signal(2) or the stdio library. Thus, they + should not need to be modified for single-terminal ports. + + lib_addch.c lib_addstr.c lib_bkgd.c lib_box.c lib_clear.c + lib_clrbot.c lib_clreol.c lib_delch.c lib_delwin.c lib_erase.c + lib_inchstr.c lib_insch.c lib_insdel.c lib_insstr.c lib_keyname.c + lib_move.c lib_mvwin.c lib_newwin.c lib_overlay.c lib_pad.c + lib_printw.c lib_refresh.c lib_scanw.c lib_scroll.c lib_scrreg.c + lib_set_term.c lib_touch.c lib_tparm.c lib_tputs.c lib_unctrl.c + lib_window.c panel.c + + This module is pure curses, but calls outstr(): + + lib_getstr.c + + These modules are pure curses, except that they use tputs() and + putp(): + + lib_beep.c lib_color.c lib_endwin.c lib_options.c lib_slk.c + lib_vidattr.c + + This modules assist in POSIX emulation on non-POSIX systems: + + sigaction.c + signal calls + + The following source files will not be needed for a + single-terminal-type port. + + alloc_entry.c captoinfo.c clear.c comp_captab.c comp_error.c + comp_hash.c comp_main.c comp_parse.c comp_scan.c dump_entry.c + infocmp.c parse_entry.c read_entry.c tput.c write_entry.c + + The following modules will use open()/read()/write()/close()/lseek() + on files, but no other OS calls. + + lib_screen.c + used to read/write screen dumps + + lib_trace.c + used to write trace data to the logfile + + Modules that would have to be modified for a port start here: + + The following modules are `pure curses' but contain assumptions + inappropriate for a memory-mapped port. + + lib_longname.c + assumes there may be multiple terminals + + lib_acs.c + assumes acs_map as a double indirection + + lib_mvcur.c + assumes cursor moves have variable cost + + lib_termcap.c + assumes there may be multiple terminals + + lib_ti.c + assumes there may be multiple terminals + + The following modules use UNIX-specific calls: + + lib_doupdate.c + input checking + + lib_getch.c + read() + + lib_initscr.c + getenv() + + lib_newterm.c + lib_baudrate.c + lib_kernel.c + various tty-manipulation and system calls + + lib_raw.c + various tty-manipulation calls + + lib_setup.c + various tty-manipulation calls + + lib_restart.c + various tty-manipulation calls + + lib_tstp.c + signal-manipulation calls + + lib_twait.c + gettimeofday(), select(). + _________________________________________________________________ + + + Eric S. Raymond + + (Note: This is not the bug address!) diff --git a/ncurses-5.2/doc/html/Ada95.html b/ncurses-5.2/doc/html/Ada95.html new file mode 100644 index 0000000..aef60ca --- /dev/null +++ b/ncurses-5.2/doc/html/Ada95.html @@ -0,0 +1,172 @@ + + + + + +Ada95 Binding for ncurses + + +

    Ada95 Binding for ncurses

    +The ncurses Ada95 binding is © 1996-2000 by +Jürgen Pfeifer. +

    + +Permission is hereby granted to reproduce and distribute this +binding by any means and for any fee, whether alone or as part +of a larger distribution, in source or in binary form, PROVIDED +this notice is included with any such distribution, and is not +removed from any of its header files. Mention of ncurses and the +author of this binding in any applications linked with it is +highly appreciated.
    + +This binding comes AS IS with no warranty, implied or expressed. +

    +


    +

    General Remarks

    +
      +
    • This document describes Version 01.00 of the binding.
    • +
    • The functionality is modelled to be compatible with the ncurses +package, a clone of the SVr4 curses model.
      +I did the development on an Intel box running the latest stable release of +Linux, ncurses and the most recent released +GNU Ada Translator +gnat versions. For any older versions of ncurses and gnat +it is not guaranteed to work.
    • +
    • You must have the m4 macroprocessor to build this package. +If you don't have this program, you can get the FSF version +here.
    • +
    • Ada programs are supposed to be readable. One of my +favourite methods to make code readable is to use expressive +names for the identifiers. You can find a list of a mapping +of the cryptic curses names to the Ada names in this table.
    • +
    • This is not a typical one-2-one interface mapping. It is +close to one-2-one on the functional level. Each (n)curses function +has it's counterpart with a more or less similar formal parameter list +in the binding. It is not one-2-one with respect to the datatypes. +I tried to make records out of the flat chtype and similar structures, +so you don't have to do bit operations to mark an attributed character +as bold. Just make the boolean member bold of the record +true. The binding also hides the structures like WINDOW, PANEL, MENU, FORM +etc. ! It's a pure functional API.
    • +
    • I try to do as much error checking as possible and feasible +in the binding. I will raise an Ada exception when something +went wrong in the low-level curses. This has the effect that - at least +first time in my life - (n)curses programs have now a very rigid error +checking, but - thanks to Ada - you don't have to code the orgiastic +error checking style of C.
    • +
    • Support for wide characters is currently not in the binding, as it +is not really in ncurses at this point in time.
    • +
    +

    + +

    Limitations

    +
      +
    • I provide no SCREEN datatype and functions to set a new screen. +If you need this (mostly for debugging I guess), write a small +C routine doing all this and import it into your Ada program.
    • +
    • I provide no functions to switch on/off curses tracing options. +Same suggestion as above.
    • +
    • Although Ada95 is an OO Language, this binding doesn't provide +an OO abstraction of the (n)curses functionality. As mentioned above +it's a thin binding for the (n)curses functions. But without any +doubt it would be nice to build on top of this an OO abstraction +of (n)curses functionality.
      +The only exception is the method how fieldtypes are represented in +this Binding. We provide an abstract tagged type Field_Type from +which the various fieldtypes are derived.
    • +
    • I currently do not support the link_fieldtype functionality of the +forms subsystem.
    • +
    • The *_IO packages are currently output only.
    • +
    + +

    Hierarchy of packages

    + +If you want to navigate through the html pages of the package specs, click here. +

    Implementation Details

    +

    Behind the abstraction

    +All the new types like Window, Panel, +Menu, Form etc. are just +opaque representations of the pointers to the corresponding +low level (n)curses structures like +WINDOW *, PANEL *, +MENU * or FORM *. +So you can safely pass them to C routines that expect a pointer +to one of those structures. +

    Extended ripoffline() usage

    +The official documentation of (n)curses says, that the line parameter +determines only whether or not exactly one line is +stolen from the top or bottom of the screen. So essentially only the +sign of the parameter is evaluated. ncurses has internally implemented +it in a way, that uses the line parameter also to control the amount of +lines to steal. This mechanism is used in the Rip_Off_Lines +routine of the binding. + +

    How user defined field types work

    +TBD +

    Enumeration fields handling

    +The (n)curses documentation says, that the String arrays to be passed to +an TYPE_ENUM fieldtype must not be automatic variables. This is not true +in this binding, because it is internally arranged to safely copy these +values. +
    +

    Using other Ada compilers

    +This should basically not be a problem. +

    Port to other curses implementations

    +Basically it should not be too hard to make all this run on a regular SVr4 +implementation of curses. The problems are probably these:
    +
      +
    • ncurses has some additional features which are presented in this binding. You +have two choices to deal with this: +
        +
      • Emulate the feature in this binding
      • +
      • Raise an exception for non implemented features
      • +
      +Most likely you will follow a mixed approach. Some features are easy to simulate, +others will be hard if not impossible.
    • +
    +I'm quite sure I forgot something.

    + + diff --git a/ncurses-5.2/doc/html/ada/files.htm b/ncurses-5.2/doc/html/ada/files.htm new file mode 100644 index 0000000..682207c --- /dev/null +++ b/ncurses-5.2/doc/html/ada/files.htm @@ -0,0 +1,5 @@ + + +

    Files

    +
    [T] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/files/T.htm b/ncurses-5.2/doc/html/ada/files/T.htm new file mode 100644 index 0000000..46b0a00 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/files/T.htm @@ -0,0 +1,69 @@ +T + +

    Files - T

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs.htm b/ncurses-5.2/doc/html/ada/funcs.htm new file mode 100644 index 0000000..96e0b14 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs.htm @@ -0,0 +1,27 @@ + + +

    Functions/Procedures

    +[ ] +[A] +[B] +[C] +[D] +[E] +[F] +[G] +[H] +[I] +[K] +[L] +[M] +[N] +[O] +[P] +[Q] +[R] +[S] +[T] +[U] +[V] +[W] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/A.htm b/ncurses-5.2/doc/html/ada/funcs/A.htm new file mode 100644 index 0000000..f32aaba --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/A.htm @@ -0,0 +1,18 @@ +A + +

    Functions - A

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/B.htm b/ncurses-5.2/doc/html/ada/funcs/B.htm new file mode 100644 index 0000000..46b0d30 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/B.htm @@ -0,0 +1,10 @@ +B + +

    Functions - B

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/C.htm b/ncurses-5.2/doc/html/ada/funcs/C.htm new file mode 100644 index 0000000..47beaff --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/C.htm @@ -0,0 +1,33 @@ +C + +

    Functions - C

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/D.htm b/ncurses-5.2/doc/html/ada/funcs/D.htm new file mode 100644 index 0000000..9472a37 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/D.htm @@ -0,0 +1,22 @@ +D + +

    Functions - D

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/E.htm b/ncurses-5.2/doc/html/ada/funcs/E.htm new file mode 100644 index 0000000..b9f13e3 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/E.htm @@ -0,0 +1,11 @@ +E + +

    Functions - E

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/F.htm b/ncurses-5.2/doc/html/ada/funcs/F.htm new file mode 100644 index 0000000..1df765f --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/F.htm @@ -0,0 +1,46 @@ +F + +

    Functions - F

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/G.htm b/ncurses-5.2/doc/html/ada/funcs/G.htm new file mode 100644 index 0000000..d90750d --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/G.htm @@ -0,0 +1,21 @@ +G + +

    Functions - G

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/H.htm b/ncurses-5.2/doc/html/ada/funcs/H.htm new file mode 100644 index 0000000..e852d92 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/H.htm @@ -0,0 +1,12 @@ +H + +

    Functions - H

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/I.htm b/ncurses-5.2/doc/html/ada/funcs/I.htm new file mode 100644 index 0000000..a3dada4 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/I.htm @@ -0,0 +1,31 @@ +I + +

    Functions - I

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/K.htm b/ncurses-5.2/doc/html/ada/funcs/K.htm new file mode 100644 index 0000000..d09ddcd --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/K.htm @@ -0,0 +1,10 @@ +K + +

    Functions - K

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/L.htm b/ncurses-5.2/doc/html/ada/funcs/L.htm new file mode 100644 index 0000000..456daf8 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/L.htm @@ -0,0 +1,14 @@ +L + +

    Functions - L

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/M.htm b/ncurses-5.2/doc/html/ada/funcs/M.htm new file mode 100644 index 0000000..c2b7878 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/M.htm @@ -0,0 +1,44 @@ +M + +

    Functions - M

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/N.htm b/ncurses-5.2/doc/html/ada/funcs/N.htm new file mode 100644 index 0000000..09ba03f --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/N.htm @@ -0,0 +1,28 @@ +N + +

    Functions - N

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/O.htm b/ncurses-5.2/doc/html/ada/funcs/O.htm new file mode 100644 index 0000000..d5ec406 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/O.htm @@ -0,0 +1,9 @@ +O + +

    Functions - O

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/P.htm b/ncurses-5.2/doc/html/ada/funcs/P.htm new file mode 100644 index 0000000..79eae2a --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/P.htm @@ -0,0 +1,39 @@ +P + +

    Functions - P

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/Q.htm b/ncurses-5.2/doc/html/ada/funcs/Q.htm new file mode 100644 index 0000000..51ad35b --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/Q.htm @@ -0,0 +1,7 @@ +Q + +

    Functions - Q

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/R.htm b/ncurses-5.2/doc/html/ada/funcs/R.htm new file mode 100644 index 0000000..213a13c --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/R.htm @@ -0,0 +1,20 @@ +R + +

    Functions - R

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/S.htm b/ncurses-5.2/doc/html/ada/funcs/S.htm new file mode 100644 index 0000000..f0e0204 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/S.htm @@ -0,0 +1,93 @@ +S + +

    Functions - S

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/T.htm b/ncurses-5.2/doc/html/ada/funcs/T.htm new file mode 100644 index 0000000..817d22b --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/T.htm @@ -0,0 +1,19 @@ +T + +

    Functions - T

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/U.htm b/ncurses-5.2/doc/html/ada/funcs/U.htm new file mode 100644 index 0000000..135f3fb --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/U.htm @@ -0,0 +1,11 @@ +U + +

    Functions - U

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/V.htm b/ncurses-5.2/doc/html/ada/funcs/V.htm new file mode 100644 index 0000000..21bebc2 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/V.htm @@ -0,0 +1,7 @@ +V + +

    Functions - V

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/funcs/W.htm b/ncurses-5.2/doc/html/ada/funcs/W.htm new file mode 100644 index 0000000..5016fb7 --- /dev/null +++ b/ncurses-5.2/doc/html/ada/funcs/W.htm @@ -0,0 +1,51 @@ +W + +

    Functions - W

    +[index] + \ No newline at end of file diff --git a/ncurses-5.2/doc/html/ada/index.htm b/ncurses-5.2/doc/html/ada/index.htm new file mode 100644 index 0000000..79c9f4a --- /dev/null +++ b/ncurses-5.2/doc/html/ada/index.htm @@ -0,0 +1,41 @@ + +Source Browser + + +

    Files

    +[T] + +
    +

    Functions/Procedures

    +[ ] +[A] +[B] +[C] +[D] +[E] +[F] +[G] +[H] +[I] +[K] +[L] +[M] +[N] +[O] +[P] +[Q] +[R] +[S] +[T] +[U] +[V] +[W] + +
    + + + + + + + diff --git a/ncurses-5.2/doc/html/ada/main.htm b/ncurses-5.2/doc/html/ada/main.htm new file mode 100644 index 0000000..2a403dc --- /dev/null +++ b/ncurses-5.2/doc/html/ada/main.htm @@ -0,0 +1,66 @@ + + +

    [No frame version is here]

    Files

    +[T] + +

    Functions/Procedures

    +[ ] +[A] +[B] +[C] +[D] +[E] +[F] +[G] +[H] +[I] +[K] +[L] +[M] +[N] +[O] +[P] +[Q] +[R] +[S] +[T] +[U] +[V] +[W] + +
    +You should start your browsing with one of these files: +\n"); +} + +print "# end of pass 1\n" if $T2H_VERBOSE; + +SetDocumentLanguage('en') unless ($T2H_LANG); +#+++############################################################################ +# # +# Stuff related to Index generation # +# # +#---############################################################################ + +sub EnterIndexEntry +{ + my $prefix = shift; + my $key = shift; + my $docu_doc = shift; + my $section = shift; + my $lines = shift; + local $_; + + warn "$ERROR Undefined index command: $_", next + unless (exists ($index_properties->{$prefix})); + $key =~ s/\s+$//; + $_ = $key; + &protect_texi; + $key = $_; + $_ = &protect_html($_); + my $html_key = substitute_style($_); + my $id; + $key = remove_style($key); + $key = remove_things($key); + $_ = $key; + &unprotect_texi; + $key = $_; + while (exists $index->{$prefix}->{$key}) {$key .= ' '}; + if ($lines->[$#lines] =~ /^$/) + { + $id = $1; + } + else + { + $id = 'IDX' . ++$idx_num; + push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); + } + $index->{$prefix}->{$key}->{html_key} = $html_key; + $index->{$prefix}->{$key}->{section} = $section; + $index->{$prefix}->{$key}->{href} = "$docu_doc#$id"; + print "# found ${prefix}index for '$key' with id $id\n" + if $T2H_DEBUG & $DEBUG_INDEX; +} + +sub IndexName2Prefix +{ + my $name = shift; + my $prefix; + + for $prefix (keys %$index_properties) + { + return $prefix if ($index_properties->{$prefix}->{name} eq $name); + } + return undef; +} + +sub GetIndexEntries +{ + my $normal = shift; + my $code = shift; + my ($entries, $prefix, $key) = ({}); + + for $prefix (keys %$normal) + { + for $key (keys %{$index->{$prefix}}) + { + $entries->{$key} = {%{$index->{$prefix}->{$key}}}; + } + } + + if (defined($code)) + { + for $prefix (keys %$code) + { + unless (exists $normal->{$keys}) + { + for $key (keys %{$index->{$prefix}}) + { + $entries->{$key} = {%{$index->{$prefix}->{$key}}}; + $entries->{$key}->{html_key} = "$entries->{$key}->{html_key}"; + } + } + } + } + return $entries; +} + +sub byAlpha +{ + if ($a =~ /^[A-Za-z]/) + { + if ($b =~ /^[A-Za-z]/) + { + return lc($a) cmp lc($b); + } + else + { + return 1; + } + } + elsif ($b =~ /^[A-Za-z]/) + { + return -1; + } + else + { + return lc($a) cmp lc($b); + } +} + +sub GetIndexPages +{ + my $entries = shift; + my (@Letters, $key); + my ($EntriesByLetter, $Pages, $page) = ({}, [], {}); + my @keys = sort byAlpha keys %$entries; + + for $key (@keys) + { + push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key}; + } + @Letters = sort byAlpha keys %$EntriesByLetter; + + $T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT); + + unless ($T2H_SPLIT_INDEX) + { + $page->{First} = $Letters[0]; + $page->{Last} = $Letters[$#Letters]; + $page->{Letters} = \@Letters; + $page->{EntriesByLetter} = $EntriesByLetter; + push @$Pages, $page; + return $Pages; + } + + if ($T2H_SPLIT_INDEX =~ /^\d+$/) + { + my $i = 0; + my ($prev_letter, $letter); + $page->{First} = $Letters[0]; + for $letter (@Letters) + { + if ($i > $T2H_SPLIT_INDEX) + { + $page->{Last} = $prev_letter; + push @$Pages, {%$page}; + $page->{Letters} = []; + $page->{EntriesByLetter} = {}; + $page->{First} = $letter; + $i=0; + } + push @{$page->{Letters}}, $letter; + $page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}]; + $i += scalar(@{$EntriesByLetter->{$letter}}); + $prev_letter = $letter; + } + $page->{Last} = $Letters[$#Letters]; + push @$Pages, {%$page}; + } + return $Pages; +} + +sub GetIndexSummary +{ + my $first_page = shift; + my $Pages = shift; + my $name = shift; + my ($page, $letter, $summary, $i, $l1, $l2, $l); + + $i = 0; + $summary = '
    Jump to:   '; + + for $page ($first_page, @$Pages) + { + for $letter (@{$page->{Letters}}) + { + $l = t2h_anchor('', "$page->{href}#${name}_$letter", "$letter", + 0, 'style="text-decoration:none"') . "\n   \n"; + + if ($letter =~ /^[A-Za-z]/) + { + $l2 .= $l; + } + else + { + $l1 .= $l; + } + } + } + $summary .= $l1 . "
    \n" if ($l1); + $summary .= $l2 . '

    '; + return $summary; +} + +sub PrintIndexPage +{ + my $lines = shift; + my $summary = shift; + my $page = shift; + my $name = shift; + + push @$lines, $summary; + + push @$lines , <

    + + + +EOT + + for $letter (@{$page->{Letters}}) + { + push @$lines, "\n"; + for $entry (@{$page->{EntriesByLetter}->{$letter}}) + { + push @$lines, + "\n"; + } + push @$lines, "\n"; + } + push @$lines, "
    Index Entry Section

    $letter
    " . + t2h_anchor('', $entry->{href}, $entry->{html_key}) . + "" . + t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) . + "

    "; + push @$lines, $summary; +} + +sub PrintIndex +{ + my $lines = shift; + my $name = shift; + my $section = shift; + $section = 'Top' unless $section; + my $prefix = IndexName2Prefix($name); + + warn ("$ERROR printindex: bad index name: $name"), return + unless $prefix; + + if ($index_properties->{$prefix}->{code}) + { + $index_properties->{$prefix}->{from_code}->{$prefix} = 1; + } + else + { + $index_properties->{$prefix}->{from}->{$prefix}= 1; + } + + my $Entries = GetIndexEntries($index_properties->{$prefix}->{from}, + $index_properties->{$prefix}->{from_code}); + return unless %$Entries; + + if ($T2H_IDX_SUMMARY) + { + my $key; + open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx") + || die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n"; + print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE; + + for $key (sort keys %$Entries) + { + print FHIDX "$key\t$Entries->{$key}->{href}\n"; + } + } + + my $Pages = GetIndexPages($Entries); + my $page; + my $first_page = shift @$Pages; + my $sec_name = $section; + # remove section number + $sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./; + + ($first_page->{href} = sec_href($section)) =~ s/\#.*$//; + # Update tree structure of document + if (@$Pages) + { + my $sec; + my @after; + + while (@sections && $sections[$#sections] ne $section) + { + unshift @after, pop @sections; + } + + for $page (@$Pages) + { + my $node = ($page->{First} ne $page->{Last} ? + "$sec_name: $page->{First} -- $page->{Last}" : + "$sec_name: $page->{First}"); + push @sections, $node; + $node2sec{$node} = $node; + $sec2node{$node} = $node; + $node2up{$node} = $section; + $page->{href} = next_doc(); + $page->{name} = $node; + $node2href{$node} = $page->{href}; + if ($prev_node) + { + $node2next{$prev_node} = $node; + $node2prev{$node} = $prev_node; + } + $prev_node = $node; + } + push @sections, @after; + } + + my $summary = GetIndexSummary($first_page, $Pages, $name); + PrintIndexPage($lines, $summary, $first_page, $name); + for $page (@$Pages) + { + push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); + push @$lines, "

    $page->{name}

    \n"; + PrintIndexPage($lines, $summary, $page, $name); + } +} + + +#+++############################################################################ +# # +# Pass 2/3: handle style, menu, index, cross-reference # +# # +#---############################################################################ + +@lines2 = (); # whole document (2nd pass) +@lines3 = (); # whole document (3rd pass) +$in_menu = 0; # am I inside a menu + +while (@lines) { + $_ = shift(@lines); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@lines2, $_); + next; + } + # + # menu + # + if (/^\@menu\b/) + { + $in_menu = 1; + $in_menu_listing = 1; + push(@lines2, &debug("
    \n", __LINE__)); + next; + } + if (/^\@end\s+menu\b/) + { + if ($in_menu_listing) + { + push(@lines2, &debug("
    \n", __LINE__)); + } + else + { + push(@lines2, &debug("\n", __LINE__)); + } + $in_menu = 0; + $in_menu_listing = 0; + next; + } + if ($in_menu) + { + my ($node, $name, $descr); + if (/^\*\s+($NODERE)::/o) + { + $node = $1; + $descr = $'; + } + elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) + { + $name = $1; + $node = $2; + $descr = $'; + } + elsif (/^\*/) + { + warn "$ERROR Bad menu line: $_"; + } + else + { + if ($in_menu_listing) + { + $in_menu_listing = 0; + push(@lines2, &debug("\n", __LINE__)); + } + # should be like verbatim -- preseve spaces, etc + s/ /\ /g; + $_ .= "
    \n"; + push(@lines2, $_); + } + if ($node) + { + if (! $in_menu_listing) + { + $in_menu_listing = 1; + push(@lines2, &debug("\n", __LINE__)); + } + # look for continuation + while ($lines[0] =~ /^\s+\w+/) + { + $descr .= shift(@lines); + } + &menu_entry($node, $name, $descr); + } + next; + } + # + # printindex + # + PrintIndex(\@lines2, $2, $1), next + if (/^\@printindex\s+(\w+)/); + # + # simple style substitutions + # + $_ = &substitute_style($_); + # + # xref + # + while (/\@(x|px|info|)ref{([^{}]+)(}?)/) { + # note: Texinfo may accept other characters + ($type, $nodes, $full) = ($1, $2, $3); + ($before, $after) = ($`, $'); + if (! $full && $after) { + warn "$ERROR Bad xref (no ending } on line): $_"; + $_ = "$before$;0${type}ref\{$nodes$after"; + next; # while xref + } + if ($type eq 'x') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; + } elsif ($type eq 'px') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; + } elsif ($type eq 'info') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info"; + } else { + $type = ''; + } + unless ($full) { + $next = shift(@lines); + $next = &substitute_style($next); + chop($nodes); # remove final newline + if ($next =~ /\}/) { # split on 2 lines + $nodes .= " $`"; + $after = $'; + } else { + $nodes .= " $next"; + $next = shift(@lines); + $next = &substitute_style($next); + chop($nodes); + if ($next =~ /\}/) { # split on 3 lines + $nodes .= " $`"; + $after = $'; + } else { + warn "$ERROR Bad xref (no ending }): $_"; + $_ = "$before$;0xref\{$nodes$after"; + unshift(@lines, $next); + next; # while xref + } + } + } + $nodes =~ s/\s+/ /g; # remove useless spaces + @args = split(/\s*,\s*/, $nodes); + $node = $args[0]; # the node is always the first arg + $node = &normalise_node($node); + $sec = $args[2] || $args[1] || $node2sec{$node}; + $href = $node2href{$node}; + if (@args == 5) { # reference to another manual + $sec = $args[2] || $node; + $man = $args[4] || $args[3]; + $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after"; + } elsif ($type =~ /Info/) { # inforef + warn "$ERROR Wrong number of arguments: $_" unless @args == 3; + ($nn, $_, $in) = @args; + $_ = "${before}${type} file `$in', node `$nn'$after"; + } elsif ($sec && $href && ! $T2H_SHORT_REF) { + $_ = "${before}${type}"; + $_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type}; + $_ .= &t2h_anchor('', $href, $sec) . $after; + } + elsif ($href) + { + $_ = "${before}${type} " . + &t2h_anchor('', $href, $args[2] || $args[1] || $node) . + $after; + } + else { + warn "$ERROR Undefined node ($node): $_"; + $_ = "$before$;0xref{$nodes}$after"; + } + } + + # replace images + s[\@image\s*{(.+?)}] + { + my @args = split (/\s*,\s*/, $1); + my $base = $args[0]; + my $image = + LocateIncludeFile("$base.png") || + LocateIncludeFile("$base.jpg") || + LocateIncludeFile("$base.gif"); + warn "$ERROR no image file for $base: $_" unless ($image && -e $image); + "\"$base\""; + ($T2H_CENTER_IMAGE ? + "
    \"$base\"
    " : + "\"$base\""); + }eg; + + # + # try to guess bibliography references or glossary terms + # + unless (/^/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + if ($T2H_USE_GLOSSARY) { + $done = ''; + while (/\b\w+\b/) { + ($pre, $what, $post) = ($`, $&, $'); + $entry = $what; + $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; + $href = $gloss2href{$entry}; + if (defined($href) && $post !~ /^[^<]*<\/A>/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + } + # otherwise + push(@lines2, $_); +} +print "# end of pass 2\n" if $T2H_VERBOSE; + +# +# split style substitutions +# +while (@lines2) { + $_ = shift(@lines2); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@lines3, $_); + next; + } + # + # split style substitutions + # + $old = ''; + while ($old ne $_) { + $old = $_; + if (/\@(\w+)\{/) { + ($before, $style, $after) = ($`, $1, $'); + if (defined($style_map{$style})) { + $_ = $after; + $text = ''; + $after = ''; + $failed = 1; + while (@lines2) { + if (/\}/) { + $text .= $`; + $after = $'; + $failed = 0; + last; + } else { + $text .= $_; + $_ = shift(@lines2); + } + } + if ($failed) { + die "* Bad syntax (\@$style) after: $before\n"; + } else { + $text = &apply_style($style, $text); + $_ = "$before$text$after"; + } + } + } + } + # otherwise + push(@lines3, $_); +} +print "# end of pass 3\n" if $T2H_VERBOSE; + +#+++############################################################################ +# # +# Pass 4: foot notes, final cleanup # +# # +#---############################################################################ + +@foot_lines = (); # footnotes +@doc_lines = (); # final document +$end_of_para = 0; # true if last line is

    + +while (@lines3) { + $_ = shift(@lines3); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@doc_lines, $_); + $end_of_para = 0; + next; + } + # + # footnotes + # + while (/\@footnote([^\{\s]+)\{/) { + ($before, $d, $after) = ($`, $1, $'); + $_ = $after; + $text = ''; + $after = ''; + $failed = 1; + while (@lines3) { + if (/\}/) { + $text .= $`; + $after = $'; + $failed = 0; + last; + } else { + $text .= $_; + $_ = shift(@lines3); + } + } + if ($failed) { + die "* Bad syntax (\@footnote) after: $before\n"; + } else { + $foot_num++; + $docid = "DOCF$foot_num"; + $footid = "FOOT$foot_num"; + $foot = "($foot_num)"; + push(@foot_lines, "

    " . &t2h_anchor($footid, "$d#$docid", $foot) . "

    \n"); + $text = "

    $text" unless $text =~ /^\s*

    /; + push(@foot_lines, "$text\n"); + $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after; + } + } + # + # remove unnecessary

    + # + if (/^\s*

    \s*$/) { + next if $end_of_para++; + } else { + $end_of_para = 0; + } + # otherwise + push(@doc_lines, $_); +} + +print "# end of pass 4\n" if $T2H_VERBOSE; + +#+++############################################################################ +# # +# Pass 5: print things # +# # +#---############################################################################ + +$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H); +$T2H_L2H = &l2h_ToHtml if ($T2H_L2H); +$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H); + +# fix node2up, node2prev, node2next, if desired +if ($has_top_command) +{ + for $section (keys %sec2number) + { + $node = $sec2node{$section}; + $node2up{$node} = Sec2UpNode($section) unless $node2up{$node}; + $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node}; + $node2next{$node} = Sec2NextNode($section) unless $node2next{$node}; + } +} + +# prepare %T2H_THISDOC +$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document"; +$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle}; +$T2H_THISDOC{author} = $value{'_author'}; +$T2H_THISDOC{subtitle} = $value{'_subtitle'}; +$T2H_THISDOC{shorttitle} = $value{'_shorttitle'}; +for $key (keys %T2H_THISDOC) +{ + $_ = &substitute_style($T2H_THISDOC{$key}); + &unprotect_texi; + s/\s*$//; + $T2H_THISDOC{$key} = $_; +} + +# if no sections, then simply print document as is +unless (@sections) +{ + print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE; + open(FILE, "> $docu_top_file") + || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; + + &$T2H_print_page_head(\*FILE); + $T2H_THIS_SECTION = \@doc_lines; + t2h_print_lines(\*FILE); + &$T2H_print_foot_navigation(\*FILE); + &$T2H_print_page_foot(\*FILE); + close(FILE); + goto Finish; +} + +# initialize $T2H_HREF, $T2H_NAME +%T2H_HREF = + ( + 'First' , sec_href($sections[0]), + 'Last', sec_href($sections[$#sections]), + 'About', $docu_about. '#SEC_About', + ); + +# prepare TOC, OVERVIEW, TOP +$T2H_TOC = \@toc_lines; +$T2H_OVERVIEW = \@stoc_lines; +if ($has_top) +{ + while (1) + { + $_ = shift @doc_lines; + last if /$TOPEND/; + push @$T2H_TOP, $_; + } + $T2H_HREF{'Top'} = $docu_top . '#SEC_Top'; +} +else +{ + $T2H_HREF{'Top'} = $T2H_HREF{First}; +} + +$node2href{Top} = $T2H_HREF{Top}; +$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines; +$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines; + +# settle on index +if ($T2H_INDEX_CHAPTER) +{ + $T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)}; + warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n" + unless $T2H_HREF{Index}; +} +if (! $T2H_HREF{Index} && $first_index_chapter) +{ + $T2H_INDEX_CHAPTER = $first_index_chapter; + $T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER}; +} + +print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n" + if ($T2H_VERBOSE && $T2H_HREF{Index}); + +%T2H_NAME = + ( + 'First', clean_name($sec2node{$sections[0]}), + 'Last', clean_name($sec2node{$sections[$#sections]}), + 'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'}, + 'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'}, + 'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'}, + 'Index' , clean_name($T2H_INDEX_CHAPTER), + 'Top', clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}), + ); + +############################################################################# +# print frame and frame toc file +# +if ( $T2H_FRAMES ) +{ + open(FILE, "> $docu_frame_file") + || die "$ERROR: Can't open $docu_frame_file for writing: $!\n"; + print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE; + &$T2H_print_frame(\*FILE); + close(FILE); + + open(FILE, "> $docu_toc_frame_file") + || die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n"; + print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE; + &$T2H_print_toc_frame(\*FILE); + close(FILE); +} + + +############################################################################# +# print Top +# +open(FILE, "> $docu_top_file") + || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; +&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT); + +if ($has_top) +{ + print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE; + $T2H_THIS_SECTION = $T2H_TOP; + $T2H_HREF{This} = $T2H_HREF{Top}; + $T2H_NAME{This} = $T2H_NAME{Top}; + &$T2H_print_Top(\*FILE); +} + +close(FILE) if $T2H_SPLIT; + +############################################################################# +# Print sections +# +$T2H_NODE{Forward} = $sec2node{$sections[0]}; +$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]}); +$T2H_HREF{Forward} = sec_href($sections[0]); +$T2H_NODE{This} = 'Top'; +$T2H_NAME{This} = $T2H_NAME{Top}; +$T2H_HREF{This} = $T2H_HREF{Top}; +if ($T2H_SPLIT) +{ + print "# writing " . scalar(@sections) . + " sections in $docu_rdir$docu_name"."_[1..$doc_num]" + if $T2H_VERBOSE; + $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); + undef $FH; + $doc_num = 0; +} +else +{ + print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." + if $T2H_VERBOSE; + $FH = \*FILE; + $previous = ''; +} + +$counter = 0; +# loop through sections +while ($section = shift(@sections)) +{ + if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND)) + { + if ($FH) + { + #close previous page + &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; + &$T2H_print_page_foot($FH); + close($FH); + undef $FH; + } + } + $T2H_NAME{Back} = $T2H_NAME{This}; + $T2H_HREF{Back} = $T2H_HREF{This}; + $T2H_NODE{Back} = $T2H_NODE{This}; + $T2H_NAME{This} = $T2H_NAME{Forward}; + $T2H_HREF{This} = $T2H_HREF{Forward}; + $T2H_NODE{This} = $T2H_NODE{Forward}; + if ($sections[0]) + { + $T2H_NODE{Forward} = $sec2node{$sections[0]}; + $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward}); + $T2H_HREF{Forward} = sec_href($sections[0]); + } + else + { + undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward}; + } + + $node = $node2up{$T2H_NODE{This}}; + $T2H_HREF{Up} = $node2href{$node}; + if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up}) + { + $T2H_NAME{Up} = $T2H_NAME{Top}; + $T2H_HREF{Up} = $T2H_HREF{Top}; + $T2H_NODE{Up} = 'Up'; + } + else + { + $T2H_NAME{Up} = &clean_name($node); + $T2H_NODE{Up} = $node; + } + + $node = $T2H_NODE{This}; + $node = $node2prev{$node}; + $T2H_NAME{Prev} = &clean_name($node); + $T2H_HREF{Prev} = $node2href{$node}; + $T2H_NODE{Prev} = $node; + + $node = $T2H_NODE{This}; + if ($node2up{$node} && $node2up{$node} ne 'Top'&& + ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node})) + { + $node = $node2up{$node}; + while ($node && $node ne $node2up{$node} && ! $node2prev{$node}) + { + $node = $node2up{$node}; + } + $node = $node2prev{$node} + unless $node2up{$node} eq 'Top' || ! $node2up{$node}; + } + else + { + $node = $node2prev{$node}; + } + $T2H_NAME{FastBack} = &clean_name($node); + $T2H_HREF{FastBack} = $node2href{$node}; + $T2H_NODE{FastBack} = $node; + + $node = $T2H_NODE{This}; + $node = $node2next{$node}; + $T2H_NAME{Next} = &clean_name($node); + $T2H_HREF{Next} = $node2href{$node}; + $T2H_NODE{Next} = $node; + + $node = $T2H_NODE{This}; + if ($node2up{$node} && $node2up{$node} ne 'Top'&& + ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node})) + { + $node = $node2up{$node}; + while ($node && $node ne $node2up{$node} && ! $node2next{$node}) + { + $node = $node2up{$node}; + } + } + $node = $node2next{$node}; + $T2H_NAME{FastForward} = &clean_name($node); + $T2H_HREF{FastForward} = $node2href{$node}; + $T2H_NODE{FastForward} = $node; + + if (! defined($FH)) + { + my $file = $T2H_HREF{This}; + $file =~ s/\#.*$//; + open(FILE, "> $docu_rdir$file") || + die "$ERROR: Can't open $docu_rdir$file for writing: $!\n"; + $FH = \*FILE; + &$T2H_print_page_head($FH); + t2h_print_label($FH); + &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter'; + } + else + { + t2h_print_label($FH); + } + + $T2H_THIS_SECTION = []; + while (@doc_lines) { + $_ = shift(@doc_lines); + last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND); + push(@$T2H_THIS_SECTION, $_); + } + $previous = $_; + &$T2H_print_section($FH); + + if ($T2H_VERBOSE) + { + $counter++; + print "." if $counter =~ /00$/; + } +} +if ($T2H_SPLIT) +{ + &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; + &$T2H_print_page_foot($FH); + close($FH); +} +print "\n" if $T2H_VERBOSE; + +############################################################################# +# Print ToC, Overview, Footnotes +# +undef $T2H_HREF{Prev}; +undef $T2H_HREF{Next}; +undef $T2H_HREF{Back}; +undef $T2H_HREF{Forward}; +undef $T2H_HREF{Up}; + +if (@foot_lines) +{ + print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n" + if $T2H_SPLIT; + $T2H_HREF{This} = $docu_foot; + $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'}; + $T2H_THIS_SECTION = \@foot_lines; + &$T2H_print_Footnotes(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if (@toc_lines) +{ + print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n" + if $T2H_SPLIT; + $T2H_HREF{This} = $T2H_HREF{Contents}; + $T2H_NAME{This} = $T2H_NAME{Contents}; + $T2H_THIS_SECTION = \@toc_lines; + &$T2H_print_Toc(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if (@stoc_lines) +{ + print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n" + if $T2H_SPLIT; + + $T2H_HREF{This} = $T2H_HREF{Overview}; + $T2H_NAME{This} = $T2H_NAME{Overview}; + $T2H_THIS_SECTION = \@stoc_lines; + unshift @$T2H_THIS_SECTION, "

    \n"; + push @$T2H_THIS_SECTION, "\n
    \n"; + &$T2H_print_Overview(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if ($about_body = &$T2H_about_body()) +{ + print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n" + if $T2H_SPLIT; + + $T2H_HREF{This} = $T2H_HREF{About}; + $T2H_NAME{This} = $T2H_NAME{About}; + $T2H_THIS_SECTION = [$about_body]; + &$T2H_print_About(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +unless ($T2H_SPLIT) +{ + &$T2H_print_page_foot(\*FILE); + close (FILE); +} + +Finish: +&l2h_FinishFromHtml if ($T2H_L2H); +&l2h_Finish if($T2H_L2H); +print "# that's all folks\n" if $T2H_VERBOSE; + +exit(0); + +#+++############################################################################ +# # +# Low level functions # +# # +#---############################################################################ + +sub LocateIncludeFile +{ + my $file = shift; + my $dir; + + return $file if (-e $file && -r $file); + foreach $dir (@T2H_INCLUDE_DIRS) + { + return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); + } + return undef; +} + +sub clean_name +{ + local ($_); + $_ = &remove_style($_[0]); + &unprotect_texi; + return $_; +} + +sub update_sec_num { + local($name, $level) = @_; + my $ret; + + $level--; # here we start at 0 + if ($name =~ /^appendix/ || defined(@appendix_sec_num)) { + # appendix style + if (defined(@appendix_sec_num)) { + &incr_sec_num($level, @appendix_sec_num); + } else { + @appendix_sec_num = ('A', 0, 0, 0); + } + $ret = join('.', @appendix_sec_num[0..$level]); + } else { + # normal style + if (defined(@normal_sec_num)) + { + &incr_sec_num($level, @normal_sec_num); + } + else + { + @normal_sec_num = (1, 0, 0, 0); + } + $ret = join('.', @normal_sec_num[0..$level]); + } + + $ret .= "." if $level == 0; + return $ret; +} + +sub incr_sec_num { + local($level, $l); + $level = shift(@_); + $_[$level]++; + foreach $l ($level+1 .. 3) { + $_[$l] = 0; + } +} + +sub Sec2UpNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + + return '' unless $num; + return 'Top' unless $num =~ /\.\d+/; + $num =~ s/\.[^\.]*$//; + $num = $num . '.' unless $num =~ /\./; + return $sec2node{$number2sec{$num}}; +} + +sub Sec2PrevNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + my ($i, $post); + + if ($num =~ /(\w+)(\.$|$)/) + { + $num = $`; + $i = $1; + $post = $2; + if ($i eq 'A') + { + $i = $normal_sec_num[0]; + } + elsif ($i ne '1') + { + # unfortunately, -- operator is not magical + $i = chr(ord($i) + 1); + } + else + { + return ''; + } + return $sec2node{$number2sec{$num . $i . $post}} + } + return ''; +} + +sub Sec2NextNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + my $i; + + if ($num =~ /(\w+)(\.$|$)/) + { + $num = $`; + $i = $1; + $post = $2; + if ($post eq '.' && $i eq $normal_sec_num[0]) + { + $i = 'A'; + } + else + { + $i++; + } + return $sec2node{$number2sec{$num . $i . $post}} + } + return ''; +} + +sub check { + local($_, %seen, %context, $before, $match, $after); + + while (<>) { + if (/\@(\*|\.|\:|\@|\{|\})/) { + $seen{$&}++; + $context{$&} .= "> $_" if $T2H_VERBOSE; + $_ = "$`XX$'"; + redo; + } + if (/\@(\w+)/) { + ($before, $match, $after) = ($`, $&, $'); + if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address + $seen{'e-mail address'}++; + $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; + } else { + $seen{$match}++; + $context{$match} .= "> $_" if $T2H_VERBOSE; + } + $match =~ s/^\@/X/; + $_ = "$before$match$after"; + redo; + } + } + + foreach (sort(keys(%seen))) { + if ($T2H_VERBOSE) { + print "$_\n"; + print $context{$_}; + } else { + print "$_ ($seen{$_})\n"; + } + } +} + +sub open { + local($name) = @_; + + ++$fh_name; + if (open($fh_name, $name)) { + unshift(@fhs, $fh_name); + } else { + warn "$ERROR Can't read file $name: $!\n"; + } +} + +sub init_input { + @fhs = (); # hold the file handles to read + @input_spool = (); # spooled lines to read + $fh_name = 'FH000'; + &open($docu); +} + +sub next_line { + local($fh, $line); + + if (@input_spool) { + $line = shift(@input_spool); + return($line); + } + while (@fhs) { + $fh = $fhs[0]; + $line = <$fh>; + return($line) if $line; + close($fh); + shift(@fhs); + } + return(undef); +} + +# used in pass 1, use &next_line +sub skip_until { + local($tag) = @_; + local($_); + + while ($_ = &next_line) { + return if /^\@end\s+$tag\s*$/; + } + die "* Failed to find '$tag' after: " . $lines[$#lines]; +} + +# used in pass 1 for l2h use &next_line +sub string_until { + local($tag) = @_; + local($_, $string); + + while ($_ = &next_line) { + return $string if /^\@end\s+$tag\s*$/; +# $_ =~ s/hbox/mbox/g; + $string = $string.$_; + } + die "* Failed to find '$tag' after: " . $lines[$#lines]; +} + +# +# HTML stacking to have a better HTML output +# + +sub html_reset { + @html_stack = ('html'); + $html_element = 'body'; +} + +sub html_push { + local($what) = @_; + push(@html_stack, $html_element); + $html_element = $what; +} + +sub html_push_if { + local($what) = @_; + push(@html_stack, $html_element) + if ($html_element && $html_element ne 'P'); + $html_element = $what; +} + +sub html_pop { + $html_element = pop(@html_stack); +} + +sub html_pop_if { + local($elt); + + if (@_) { + foreach $elt (@_) { + if ($elt eq $html_element) { + $html_element = pop(@html_stack) if @html_stack; + last; + } + } + } else { + $html_element = pop(@html_stack) if @html_stack; + } +} + +sub html_debug { + local($what, $line) = @_; + if ($T2H_DEBUG & $DEBUG_HTML) + { + $what = "\n" unless $what; + return("$what") + } + return($what); +} + +# to debug the output... +sub debug { + local($what, $line) = @_; + return("$what") + if $T2H_DEBUG & $DEBUG_HTML; + return($what); +} + +sub SimpleTexi2Html +{ + local $_ = $_[0]; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +sub normalise_node { + local $_ = $_[0]; + s/\s+/ /g; + s/ $//; + s/^ //; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +sub menu_entry +{ + my ($node, $name, $descr) = @_; + my ($href, $entry); + + &normalise_node($node); + $href = $node2href{$node}; + if ($href) + { + $descr =~ s/^\s+//; + $descr =~ s/\s*$//; + $descr = SimpleTexi2Html($descr); + if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node}) + { + $entry = $node2sec{$node}; + $name = ''; + } + else + { + &normalise_node($name); + $entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY) + ? "$name : $node" : $node); + } + + if ($T2H_AVOID_MENU_REDUNDANCY && $descr) + { + my $clean_entry = $entry; + $clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /); + $clean_entry =~ s/[^\w]//g; + my $clean_descr = $descr; + $clean_descr =~ s/[^\w]//g; + $descr = '' if ($clean_entry eq $clean_descr) + } + push(@lines2,&debug('
    \n", __LINE__)); + } + elsif ($node =~ /^\(.*\)\w+/) + { + push(@lines2,&debug('\n", __LINE__)) + } + else + { + warn "$ERROR Undefined node of menu_entry ($node): $_"; + } +} + +sub do_ctrl { "^$_[0]" } + +sub do_email { + local($addr, $text) = split(/,\s*/, $_[0]); + + $text = $addr unless $text; + &t2h_anchor('', "mailto:$addr", $text); +} + +sub do_sc +{ + # l2h does this much better + return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H); + return "\U$_[0]\E"; +} + +sub do_math +{ + return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); + return "".$text.""; +} + +sub do_uref { + local($url, $text, $only_text) = split(/,\s*/, $_[0]); + + $text = $only_text if $only_text; + $text = $url unless $text; + &t2h_anchor('', $url, $text); +} + +sub do_url { &t2h_anchor('', $_[0], $_[0]) } + +sub do_acronym +{ + return '' . $_[0] . ''; +} + +sub do_accent +{ + return "&$_[0]acute;" if $_[1] eq 'H'; + return "$_[0]." if $_[1] eq 'dotaccent'; + return "$_[0]*" if $_[1] eq 'ringaccent'; + return "$_[0]".'[' if $_[1] eq 'tieaccent'; + return "$_[0]".'(' if $_[1] eq 'u'; + return "$_[0]_" if $_[1] eq 'ubaraccent'; + return ".$_[0]" if $_[1] eq 'udotaccent'; + return "$_[0]<" if $_[1] eq 'v'; + return "&$_[0]cedil;" if $_[1] eq ','; + return "$_[0]" if $_[1] eq 'dotless'; + return undef; +} + +sub apply_style { + local($texi_style, $text) = @_; + local($style); + + $style = $style_map{$texi_style}; + if (defined($style)) { # known style + if ($style =~ /^\"/) { # add quotes + $style = $'; + $text = "\`$text\'"; + } + if ($style =~ /^\&/) { # custom + $style = $'; + $text = &$style($text, $texi_style); + } elsif ($style) { # good style + $text = "<$style>$text"; + } else { # no style + } + } else { # unknown style + $text = undef; + } + return($text); +} + +# remove Texinfo styles +sub remove_style { + local($_) = @_; + 1 while(s/\@\w+{([^\{\}]+)}/$1/g); + return($_); +} + +sub remove_things +{ + local ($_) = @_; + s|\@(\w+)\{\}|$1|g; + return $_; +} + +sub substitute_style { + local($_) = @_; + local($changed, $done, $style, $text); + + &simple_substitutions; + $changed = 1; + while ($changed) { + $changed = 0; + $done = ''; + while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) { + $text = &apply_style($1, $2); + if ($text) { + $_ = "$`$text$'"; + $changed = 1; + } else { + $done .= "$`\@$1"; + $_ = "{$2}$'"; + } + } + $_ = $done . $_; + } + return($_); +} + +sub t2h_anchor { + local($name, $href, $text, $newline, $extra_attribs) = @_; + local($result); + + $result = " + $what =~ s/\&/\&\#38;/g; + $what =~ s/\/\&\#62;/g; + # restore anything in quotes + # this fixes my problem where I had: + # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < in my ALT text ?? + # maybe byte stuffing or some other technique should be used. + $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g; + $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g; + $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g; + # but recognize some HTML things + $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # + $what =~ s/\&\#60;A ([^\&]+)\&\#62;//g; # + $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;//g; # + return($what); +} + +sub unprotect_texi { + s/$;0/\@/go; + s/$;1/\{/go; + s/$;2/\}/go; + s/$;3/\`/go; + s/$;4/\'/go; +} + +sub Unprotect_texi +{ + local $_ = shift; + &unprotect_texi; + return($_); +} + +sub unprotect_html { + local($what) = @_; + $what =~ s/\&\#38;/\&/g; + $what =~ s/\&\#60;/\/g; + return($what); +} + +sub t2h_print_label +{ + my $fh = shift; + my $href = shift || $T2H_HREF{This}; + $href =~ s/.*#(.*)$/$1/; + print $fh qq{\n}; +} + +############################################################################## + + # These next few lines are legal in both Perl and nroff. + +.00 ; # finish .ig + +'di \" finish diversion--previous line must be blank +.nr nl 0-1 \" fake up transition to first page again +.nr % 0 \" start at page 1 +'; __END__ ############# From here on it's a standard manual page ############ +.so /usr/local/man/man1/texi2html.1 diff --git a/readline-4.3.orig/doc/texinfo.tex b/readline-4.3.orig/doc/texinfo.tex new file mode 100644 index 0000000..c49af9f --- /dev/null +++ b/readline-4.3.orig/doc/texinfo.tex @@ -0,0 +1,5992 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{1999-09-25.10} +% +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.gnu.org/gnu/texinfo.tex +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) +% ftp://texinfo.org/tex/texinfo.tex +% ftp://us.ctan.org/macros/texinfo/texinfo.tex +% (and all CTAN mirrors, finger ctan@us.ctan.org for a list). +% /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% The texinfo.tex in any given Texinfo distribution could well be out +% of date, so if that's what you're using, please check. +% Texinfo has a small home page at http://texinfo.org/. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. +% The extra runs of TeX get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages. You can get +% the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% Save some parts of plain tex whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexi=\i +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexstar=\* +\let\ptext=\t + +% We never want plain's outer \+ definition in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +\message{Basics,} +\chardef\other=12 + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi + +% Ignore a token. +% +\def\gobble#1{} + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset +\newdimen \normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\ifx\eTeXversion\undefined +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\else +\def\loggingall{\tracingcommands3 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \tracingscantokens1 \tracingassigns1 \tracingifs1 + \tracinggroups1 \tracingnesting2 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\fi + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \turnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt +\def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce actual \{ & \} command in an index. + \catcode`\{ = 12 \catcode`\} = 12 + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\@ = 0 \catcode`\\ = 12 + @gdef@lbracecmd[\{]% + @gdef@rbracecmd[\}]% +@endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + + +% @page forces the start of a new page +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + +%\hbox{{\rm#1}}\hfil\break}} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% We cannot implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\def\paragraphindent{\parsearg\doparagraphindent} +\def\doparagraphindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\def\exampleindent{\parsearg\doexampleindent} +\def\doexampleindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math means output in math mode. +% We don't use $'s directly in the definition of \math because control +% sequences like \math are expanded when the toc file is written. Then, +% we read the toc file back, the $'s will be normal characters (as they +% should be, according to the definition of Texinfo). So we must use a +% control sequence to switch into and out of math mode. +% +% This isn't quite enough for @math to work properly in indices, but it +% seems unlikely it will ever be needed there. +% +\let\implicitmath = $ +\def\math#1{\implicitmath #1\implicitmath} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \iflinks + \readauxfile + \fi % \openindices needs to do some work in any case. + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +\ifx\pdfoutput\undefined + \pdffalse + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\linkcolor = \relax + \let\pdfmakeoutlines = \relax +\else + \pdftrue + \pdfoutput = 1 + \input pdfcolor + \def\dopdfimage#1#2#3{% + \def\imagewidth{#2}% + \def\imageheight{#3}% + \ifnum\pdftexversion < 14 + \pdfimage + \else + \pdfximage + \fi + \ifx\empty\imagewidth\else width \imagewidth \fi + \ifx\empty\imageheight\else height \imageheight \fi + {#1.pdf}% + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + \def\pdfmkdest#1{\pdfdest name{#1@} xyz} + \def\pdfmkpgn#1{#1@} + \let\linkcolor = \Cyan + \def\endlink{\Black\pdfendlink} + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + \def\pdfmakeoutlines{{% + \openin 1 \jobname.toc + \ifeof 1\else\bgroup + \closein 1 + \indexnofonts + \def\tt{} + % thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % + \def\chapentry ##1##2##3{} + \def\unnumbchapentry ##1##2{} + \def\secentry ##1##2##3##4{\advancenumber{chap##2}} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \def\chapentry ##1##2##3{% + \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} + \def\unnumbchapentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\secentry ##1##2##3##4{% + \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} + \def\unnumbsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsecentry ##1##2##3##4##5{% + \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} + \def\unnumbsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsubsecentry ##1##2##3##4##5##6{% + \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} + \def\unnumbsubsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \input \jobname.toc + \egroup\fi + }} + \def\makelinks #1,{% + \def\params{#1}\def\E{END}% + \ifx\params\E + \let\nextmakelinks=\relax + \else + \let\nextmakelinks=\makelinks + \ifnum\lnkcount>0,\fi + \picknum{#1}% + \startlink attr{/Border [0 0 0]} + goto name{\pdfmkpgn{\the\pgn}}% + \linkcolor #1% + \advance\lnkcount by 1% + \endlink + \fi + \nextmakelinks + } + \def\picknum#1{\expandafter\pn#1} + \def\pn#1{% + \def\p{#1}% + \ifx\p\lbrace + \let\nextpn=\ppn + \else + \let\nextpn=\ppnn + \def\first{#1} + \fi + \nextpn + } + \def\ppn#1{\pgn=#1\gobble} + \def\ppnn{\pgn=\first} + \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \fi + \nextsp} + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + \def\pdfurl#1{% + \begingroup + \normalturnoffactive\def\@{@}% + \leavevmode\Red + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + % #1 + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS| + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\mkpgn{#1}} + \linkcolor #1\endlink} + \def\mkpgn#1{#1@} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\fi % \ifx\pdfoutput + + +\message{fonts,} +% Font-change commands. + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Use Computer Modern fonts at \magstephalf (11pt). +\newcount\mainmagstep +\mainmagstep=\magstephalf + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\ifx\bigger\relax +\let\mainmagstep=\magstep1 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} +\else +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\setfont\smallrm\rmshape{9}{1000} +\setfont\smalltt\ttshape{9}{1000} +\setfont\smallbf\bfshape{10}{900} +\setfont\smallit\itshape{9}{1000} +\setfont\smallsl\slshape{9}{1000} +\setfont\smallsf\sfshape{9}{1000} +\setfont\smallsc\scshape{10}{900} +\setfont\smallttsl\ttslshape{10}{900} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} + +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} + +%\let\ssecbf=\ssecrm + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts, we +% don't bother to reset \scriptfont and \scriptscriptfont (which would +% also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf +} + + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \resetmathfonts \setleading{11pt}} + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} +\def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic +\let\cite=\smartslanted + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp#1{`\tclose{#1}'\null} +\setfont\keyrm\rmshape{8}{1000} +\font\keysy=cmsy9 +\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active + \catcode`\_=\active + % + \global\def\code{\begingroup + \catcode`\-=\active \let-\codedash + \catcode`\_=\active \let_\codeunder + \codex + } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} +\def\codex #1{\tclose{#1}\endgroup} + +%\let\exp=\tclose %Was temporary + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is kbdinputdistinct. (Too much of a hassle to call the macro, +% the catcodes are wrong for parsearg to work.) +\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi + % + \ifpdf \pdfmakepagedesttrue \fi + % + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% Produces Day Month Year style of output. +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +% @table, @ftable, @vtable. +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey #1#2{% +\aboveenvbreak % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\afterenvbreak\endgroup}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +% Set sfcode to normal for the chars that usually have another value. +% These are `.?!:;,' +\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; + % typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% This used to have \hskip1sp. But then the space in a template line is +% not enough. That is bad. So let's go back to just & until we +% encounter the problem it was intended to solve again. +% --karl, nathan@acm.org, 20apr99. +\def\tab{&} + +% @multitable ... @end multitable definitions: +% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup + \vskip\parskip + \let\item\crcr + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +\else +%% FIXME: what is \box0 supposed to be? +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{conditionals,} +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% + \let\chapter=\relax + \let\unnumbered=\relax + \let\top=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax + \let\section=\relax + \let\subsec=\relax + \let\subsubsec=\relax + \let\subsection=\relax + \let\subsubsection=\relax + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + \let\contents=\relax + \let\smallbook=\relax + \let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypeivar = \relax + \let\deftypeop = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifnottex{\doignore{ifnottex}} +\def\html{\doignore{html}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + % This @ is a catcode 12 token (that is the normal catcode of @ in + % this texinfo.tex file). We change the catcode of @ below to match. + \long\def\doignoretext##1@end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % We must not have @c interpreted as a control sequence. + \catcode`\@ = 12 + % + % Make the letter c a comment character so that the rest of the line + % will be ignored. This way, the document can have (for example) + % @c @end ifinfo + % and the @end ifinfo will be properly ignored. + % (We've just changed @ to catcode 12.) + \catcode`\c = 14 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{WARNING: for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont + \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont + \let\tensf=\nullfont + % Similarly for index fonts (mostly for their use in smallexample). + \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont + \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont + \let\smallsf=\nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}}% + % Do not execute macro definitions. + % `c' is a comment character, so the word `macro' will get cut off. + \def\macro{\doignore{ma}}% +} + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +{ + \catcode`\_ = \active + % + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup + \catcode`\-=12 \catcode`\_=12 + \indexbreaks \let_\normalunderscore + \valuexxx} +} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable, since the result +% winds up in the index file. This means that if the variable's value +% contains other Texinfo commands, it's almost certain it will fail +% (although perhaps we could fix that with sufficient work to do a +% one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text +% following, through the first @end iftex (etc.). Make `@end iftex' +% (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} + +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} + +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% The \closeout helps reduce unnecessary open files; the limit on the +% Acorn RISC OS is a mere 16 files. +\def\synindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\doindex{#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\docodeindex{#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +\def\ { }% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. +% (Must be a way to avoid doing expansion at all, and thus not have to +% laboriously list every single command here.) +\def\@{@}% will be @@ when we switch to @ as escape char. +% Need these in case \tex is in effect and \{ is a \delimiter again. +% But can't use \lbracecmd and \rbracecmd because texindex assumes +% braces and backslashes are used only as delimiters. +\let\{ = \mylbrace +\let\} = \myrbrace +\def\_{{\realbackslash _}}% +\def\w{\realbackslash w }% +\def\bf{\realbackslash bf }% +%\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\sf{\realbackslash sf}% +\def\tt{\realbackslash tt}% +\def\gtr{\realbackslash gtr}% +\def\less{\realbackslash less}% +\def\hat{\realbackslash hat}% +\def\TeX{\realbackslash TeX}% +\def\dots{\realbackslash dots }% +\def\result{\realbackslash result}% +\def\equiv{\realbackslash equiv}% +\def\expansion{\realbackslash expansion}% +\def\print{\realbackslash print}% +\def\error{\realbackslash error}% +\def\point{\realbackslash point}% +\def\copyright{\realbackslash copyright}% +\def\tclose##1{\realbackslash tclose {##1}}% +\def\code##1{\realbackslash code {##1}}% +\def\uref##1{\realbackslash uref {##1}}% +\def\url##1{\realbackslash url {##1}}% +\def\env##1{\realbackslash env {##1}}% +\def\command##1{\realbackslash command {##1}}% +\def\option##1{\realbackslash option {##1}}% +\def\dotless##1{\realbackslash dotless {##1}}% +\def\samp##1{\realbackslash samp {##1}}% +\def\,##1{\realbackslash ,{##1}}% +\def\t##1{\realbackslash t {##1}}% +\def\r##1{\realbackslash r {##1}}% +\def\i##1{\realbackslash i {##1}}% +\def\b##1{\realbackslash b {##1}}% +\def\sc##1{\realbackslash sc {##1}}% +\def\cite##1{\realbackslash cite {##1}}% +\def\key##1{\realbackslash key {##1}}% +\def\file##1{\realbackslash file {##1}}% +\def\var##1{\realbackslash var {##1}}% +\def\kbd##1{\realbackslash kbd {##1}}% +\def\dfn##1{\realbackslash dfn {##1}}% +\def\emph##1{\realbackslash emph {##1}}% +\def\acronym##1{\realbackslash acronym {##1}}% +% +% Handle some cases of @value -- where the variable name does not +% contain - or _, and the value does not contain any +% (non-fully-expandable) commands. +\let\value = \expandablevalue +% +\unsepspaces +% Turn off macro expansion +\turnoffmacros +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexdummytex{TeX} +\def\indexdummydots{...} + +\def\indexnofonts{% +% Just ignore accents. +\let\,=\indexdummyfont +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +\let\dotless=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% +\let\w=\indexdummyfont +\let\t=\indexdummyfont +\let\r=\indexdummyfont +\let\i=\indexdummyfont +\let\b=\indexdummyfont +\let\emph=\indexdummyfont +\let\strong=\indexdummyfont +\let\cite=\indexdummyfont +\let\sc=\indexdummyfont +%Don't no-op \tt, since it isn't a user-level command +% and is used in the definitions of the active chars like <, >, |... +%\let\tt=\indexdummyfont +\let\tclose=\indexdummyfont +\let\code=\indexdummyfont +\let\url=\indexdummyfont +\let\uref=\indexdummyfont +\let\env=\indexdummyfont +\let\acronym=\indexdummyfont +\let\command=\indexdummyfont +\let\option=\indexdummyfont +\let\file=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +\let\TeX=\indexdummytex +\let\dots=\indexdummydots +\def\@{@}% +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other + @gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% For \ifx comparisons. +\def\emptymacro{\empty} + +% Most index entries go through here, but \dosubind is the general case. +% +\def\doind#1#2{\dosubind{#1}{#2}\empty} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. +% +\def\dosubind#1#2#3{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% + \fi + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio = 0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + \def\thirdarg{#3}% + % + % If third arg is present, precede it with space in sort key. + \ifx\thirdarg\emptymacro + \let\subentry = \empty + \else + \def\subentry{ #3}% + \fi + % + % First process the index entry with all font commands turned + % off to get the string to sort by. + {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% + % + % Now the real index entry with the fonts. + \toks0 = {#2}% + % + % If third (subentry) arg is present, add it to the index + % string. And include a space. + \ifx\thirdarg\emptymacro \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + % Set up the complete index entry, with both the sort key + % and the original text, including any font commands. We write + % three arguments to \entry to the .?? file, texindex reduces to + % two when writing the .??s sorted result. + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write will make \lastskip zero. The result is that sequences + % like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + \iflinks + \ifvmode + \skip0 = \lastskip + \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi + \fi + % + \temp % do the write + % + % + \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi + \fi + }% + }% + \penalty\count255 + }% +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \indexbreaks + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \penalty -300 + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % + % Do our best not to break after the initial. + \nobreak +}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ #2% The page number ends the paragraph. + \fi + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +\def\pagesofar{% + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split, in box0 and box2. + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +\def\enddoublecolumns{% + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +\def\balancecolumns{% + % Called at the end of the double column material. + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% \def\appendixletter{\char\the\appendixno} +% We do the following for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise. +\def\thischapter{} +\def\thissection{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raise/lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi +\fi +} + +% @chapter, @appendix, @unnumbered. +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +% We don't substitute the actual chapter name into \thischapter +% because we don't want its macros evaluated now. +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\the\chapno}}}% +\temp +\donoderef +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec +} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \appendixno by 1 +\message{\putwordAppendix\space \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\putwordAppendix{} \appendixletter}}}% +\temp +\appendixnoderef +\global\let\section = \appendixsec +\global\let\subsection = \appendixsubsec +\global\let\subsubsection = \appendixsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the to achieve this: TeX expands \the only once, +% simply yielding the contents of . (We also do this for +% the toc entries.) +\toks0 = {#1}\message{(\the\toks0)}% +% +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% +\temp +\unnumbnoderef +\global\let\section = \unnumberedsec +\global\let\subsection = \unnumberedsubsec +\global\let\subsubsection = \unnumberedsubsubsec +} + +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\the\chapno}{\the\secno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\appendixletter}{\the\secno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{% +\plainsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsections. +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{% +\plainsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsubsections. +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{% +\plainsubsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% + \pchapsepmacro + {% + \chapfonts \rm + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} + +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} + +% Subsection titles. +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} + +% Subsubsection titles. +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} + + +% Print any size section title. +% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% + {% + % Switch to the right set of fonts. + \csname #1fonts\endcsname \rm + % + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% + % + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% + }% + \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. We supply {\folio} at the end of the +% argument, which will end up as the last argument to the \...entry macro. +% +% We open the .toc file here instead of at @setfilename or any other +% given time so that @contents can be put in the document anywhere. +% +\newif\iftocfileopened +\def\writetocentry#1{% + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + \iflinks \write\tocfile{#1{\folio}}\fi +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Finish up the main text and prepare to read what we've written +% to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \pageno = \lastnegativepageno \fi +} + + +% Normal (long) toc. +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \pdfmakeoutlines + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} +\let\shortcontents = \summarycontents + +\ifpdf + \pdfcatalog{/PageMode /UseOutlines}% +\fi + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + +% See comments in \dochapentry re vbox and related settings +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% +} + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +% +\newdimen\shortappendixwidth +% +\def\shortchaplabel#1{% + % Compute width of word "Appendix", may change with language. + \setbox0 = \hbox{\shortcontrm \putwordAppendix}% + \shortappendixwidth = \wd0 + % + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno\bgroup#2\egroup}} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, so characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} +% @foo ... @end foo. + +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% Furthermore, these definitions must come after we define our fonts. +\newbox\dblarrowbox \newbox\longdblarrowbox +\newbox\pushcharbox \newbox\bullbox +\newbox\equivbox \newbox\errorbox + +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +% Adapted from the manmac format (p.420 of TeXbook) +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% Adapted from the TeXbook's \boxit. +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + +% The @error{} command. +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 % plus + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\long\def\cartouche{% +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. +% +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} + +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} + +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + +% @small... is usually equivalent to the non-small (@smallbook +% redefines). We must call \example (or whatever) last in the +% definition, since it reads the return following the @example (or +% whatever) command. +% +% This actually allows (for example) @end display inside an +% @smalldisplay. Too bad, but makeinfo will catch the error anyway. +% +\def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} +\def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} +\def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + +% Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. +% Originally contributed by Pavel@xerox. +\def\smalllispx{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \smallfonts + \lisp +} + +% @display: same as @lisp except keep current font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} + +% @smalldisplay (when @smallbook): @display plus smaller fonts. +% +\def\smalldisplayx{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \smallfonts \rm + \display +} + +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} + +% @smallformat (when @smallbook): @format plus smaller fonts. +% +\def\smallformatx{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \smallfonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} + +% @flushright. +% +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble +} + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + + +\message{defuns,} +% @defun etc. + +% Allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\let\ampnr = \& +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% Active &'s sneak into the index arguments, so make sure it's defined. +{ + \catcode`& = 13 + \global\let& = \ampnr +} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +% Get the values of \leftskip and \rightskip as they were +% outside the @def... +\dimen2=\leftskip +\advance\dimen2 by -\defbodyindent +\noindent +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +{% Adjust \hsize to exclude the ambient margins, +% so that \rightline will obey them. +\advance \hsize by -\dimen2 +\rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% +% Make all lines underfull and no complaints: +\tolerance=10000 \hbadness=10000 +\advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % 61 is `=' +\obeylines\activeparens\spacesplit#3} + +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by the space, is the class name. +% +\def\defmethparsebody#1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +% Used for @deftypemethod and @deftypeivar. +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by a space, is the class name. +% #5 is the method's return type. +% +\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} + +% Used for @deftypeop. The change from \deftypemethparsebody is an +% extra argument at the beginning which is the `category', instead of it +% being the hardwired string `Method' or `Instance Variable'. We have +% to account for this both in the \...x definition and in parsing the +% input at hand. Thus also need a control sequence (passed as #5) for +% the \E... definition to assign the category name to. +% +\def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 ##3 {% + \def#4{##1}% + \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. + +\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % +\obeylines\spacesplit#3} + +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs#1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Set the font temporarily and use \font in case \setfont made \tensl a macro. +{\tensl\hyphenchar\font=0}% +#1% +{\tensl\hyphenchar\font=45}% +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDeffunc}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% +\deftypefunargs {#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefmac}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefspec}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defop CATEGORY CLASS OPERATION ARG... +% +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} +% +\def\defopheader#1#2#3{% +\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% +\defunargs {#3}\endgroup % +} + +% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... +% +\def\deftypeop #1 {\def\deftypeopcategory{#1}% + \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader + \deftypeopcategory} +% +% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. +\def\deftypeopheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3} + {\deftypeopcategory\ \putwordon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypemethod CLASS TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypeivar CLASS TYPE VARNAME +% +\def\deftypeivar{% + \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} +% +% #1 is the class name, #2 the data type, #3 the variable name. +\def\deftypeivarheader#1#2#3{% + \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index + \begingroup + \defname{#3}{\putwordInstanceVariableof\ \code{#1}}% + \defvarargs{#3}% + \endgroup +} + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME +% +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} +% +\def\defivarheader#1#2#3{% + \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index + \begingroup + \defname{#2}{\putwordInstanceVariableof\ #1}% + \defvarargs{#3}% + \endgroup +} + +% @defvar +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefvar}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefopt}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% These definitions are used if you use @defunx (etc.) +% anywhere other than immediately after a @defun or @defunx. +% +\def\defcvx#1 {\errmessage{@defcvx in invalid context}} +\def\deffnx#1 {\errmessage{@deffnx in invalid context}} +\def\defivarx#1 {\errmessage{@defivarx in invalid context}} +\def\defmacx#1 {\errmessage{@defmacx in invalid context}} +\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\defopx#1 {\errmessage{@defopx in invalid context}} +\def\defspecx#1 {\errmessage{@defspecx in invalid context}} +\def\deftpx#1 {\errmessage{@deftpx in invalid context}} +\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} +\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} +\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} +\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} +\def\defunx#1 {\errmessage{@defunx in invalid context}} +\def\defvarx#1 {\errmessage{@defvarx in invalid context}} +\def\defvrx#1 {\errmessage{@defvrx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + % Undo catcode changes of \startcontents and \doprintindex + \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ + % Append \endinput to make sure that TeX does not see the ending newline. + \toks0={#1\endinput}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup +} +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +% Undo catcode changes of \startcontents and \doprintindex +\catcode`\@=0 \catcode`\\=12 \escapechar=`\@ +\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} +\fi + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? +\def\macrolist{} % List of all defined macros in the form + % \do\macro1\do\macro2... + +% Utility routines. +% Thisdoes \let #1 = #2, except with \csnames. +\def\cslet#1#2{% +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=12\catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\macrobodyctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\{=12 + \catcode`\}=12 + \catcode`\@=12 + \catcode`\^^M=12 + \usembodybackslash} + +\def\macroargctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\@=12 + \catcode`\\=12} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{The name \the\macname\space is reserved}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + % Add the macroname to \macrolist + \toks0 = \expandafter{\macrolist\do}% + \xdef\macrolist{\the\toks0 + \expandafter\noexpand\csname\the\macname\endcsname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\def\unmacro{\parsearg\unmacroxxx} +\def\unmacroxxx#1{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist + \begingroup + \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% + \def\do##1{% + \def\tempb{##1}% + \ifx\tempa\tempb + % remove this + \else + \toks0 = \expandafter{\newmacrolist\do}% + \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% + \fi}% + \def\newmacrolist{}% + % Execute macro list to define \newmacrolist + \macrolist + \global\let\macrolist\newmacrolist + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \next} + +% We mant to disable all macros during \shipout so that they are not +% expanded by \write. +\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% + \edef\next{\macrolist}\expandafter\endgroup\next} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Just make them active and then expand them all to nothing. +\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{\ignoreactivespaces +\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% + \expandafter\noexpand\csname#2\endcsname}% +\expandafter\endgroup\next} + + +\message{cross references,} +% @xref etc. + +\newwrite\auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's job is to define \lastnode. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\relax + +% The sectioning commands (@chapter, etc.) call these. +\def\donoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Ysectionnumberandtype}% + \global\let\lastnode=\relax + \fi +} +\def\unnumbnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% + \global\let\lastnode=\relax + \fi +} +\def\appendixnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Yappendixletterandtype}% + \global\let\lastnode=\relax + \fi +} + + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME, namely +% NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have +% to set \indexdummies so commands such as @code in a section title +% aren't expanded. It would be nicer not to expand the titles in the +% first place, but there's so many layers that that is hard to do. +% +\def\setref#1#2{{% + \indexdummies + \pdfmkdest{#1}% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2}% +}} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifpdf + \leavevmode + \getfilename{#4}% + \ifnum\filenamelength>0 + \startlink attr{/Border [0 0 0]}% + goto file{\the\filename.pdf} name{#1@}% + \else + \startlink attr{/Border [0 0 0]}% + goto name{#1@}% + \fi + \linkcolor + \fi + % + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\normalturnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % [mynode], + [\printednodename],\space + % page 3 + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi + \endlink +\endgroup} + +% \dosetq is the interface for calls from other macros + +% Use \normalturnoffactive so that punctuation chars such as underscore +% and backslash work in node names. (\turnoffactive doesn't do \.) +\def\dosetq#1#2{% + {\let\folio=0% + \normalturnoffactive + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \iflinks + \next + \fi + }% +} + +% \internalsetq {foo}{page} expands into +% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ytitle{\thissection} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\def\Yappendixletterandtype{% +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. + +\def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +% +\def\xrdef#1{\begingroup + % Reenable \ as an escape while reading the second argument. + \catcode`\\ = 0 + \afterassignment\endgroup + \expandafter\gdef\csname X#1\endcsname +} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + \catcode`\@=\other + \catcode`\^=\other + % It was suggested to define this as 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % The aux file uses ' as the escape (for now). + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\%=\other + \catcode`\'=0 + \catcode`\\=\other + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\long\gdef\footnotezzz{\insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t + \else\let\next\f@t\fi \next} +\def\f@@t{\bgroup\aftergroup\@foot\let\next} +\def\f@t#1{#1\@foot} +\def\@foot{\strut\par\egroup} + +}%end \catcode `\@=11 + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + \closein 1 + % Do not bother showing banner with post-v2.7 epsf.tex (available in + % doc/epsf.tex until it shows up on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is just the usual extra ignored arg for parsing this stuff. +\def\imagexxx#1,#2,#3,#4\finish{% + \ifpdf + \centerline{\dopdfimage{#1}{#2}{#3}}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \begingroup + \catcode`\^^M = 5 % in case we're inside an example + % If the image is by itself, center it. + \ifvmode + \nobreak\bigskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \centerline{\epsfbox{#1.eps}}% + \bigbreak + \else + % In the middle of a paragraph, no extra space. + \epsfbox{#1.eps}% + \fi + \endgroup + \fi +} + + +\message{localization,} +% and i18n. + +% @documentlanguage is usually given very early, just after +% @setfilename. If done too late, it may not override everything +% properly. Single argument is the language abbreviation. +% It would be nice if we could set up a hyphenation file here. +% +\def\documentlanguage{\parsearg\dodocumentlanguage} +\def\dodocumentlanguage#1{% + \tex % read txi-??.tex file in plain TeX. + % Read the file if it exists. + \openin 1 txi-#1.tex + \ifeof1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \let\temp = \relax + \else + \def\temp{\input txi-#1.tex }% + \fi + \temp + \endgroup +} +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? In the current directory +should work if nowhere else does.} + + +% @documentencoding should change something in TeX eventually, most +% likely, but for now just recognize it. +\let\documentencoding = \comment + + +% Page size parameters. +% +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; +% 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can +% set \parskip and call \setleading for \baselineskip. +% +\def\internalpagesizes#1#2#3#4#5#6{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + % If page is nothing but text, make it come out even. + \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% +}} + +% Use @smallbook to reset parameters for 7x9.5 (or so) format. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \setleading{12pt}% + % + \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \deftypemargin = 0pt + \defbodyindent = .5cm + % + \let\smalldisplay = \smalldisplayx + \let\smallexample = \smalllispx + \let\smallformat = \smallformatx + \let\smalllisp = \smalllispx +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \setleading{12pt}% + \parskip = 3pt plus 2pt minus 1pt + % + \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% + % + \tolerance = 700 + \hfuzz = 1pt +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex{{\globaldefs = 1 + \setleading{13.6pt}% + % + \afourpaper + \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% + % + \globaldefs = 0 +}} + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{% + \afourpaper + \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% + % + \globaldefs = 0 +} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$} + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar} +%\catcode 27=\active +%\def^^[{$\diamondsuit$} + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +\global\chardef\rawbackslashxx=`\\ +%{\catcode`\\=\other +%@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% \catcode 17=0 % Define control-q +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These look ok in all fonts, so just make them not special. +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other + +@c Set initial fonts. +@textfonts +@rm + + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: diff --git a/readline-4.3.orig/emacs_keymap.c b/readline-4.3.orig/emacs_keymap.c new file mode 100644 index 0000000..ca9d134 --- /dev/null +++ b/readline-4.3.orig/emacs_keymap.c @@ -0,0 +1,873 @@ +/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +/* An array of function pointers, one for each possible key. + If the type byte is ISKMAP, then the pointer is the address of + a keymap. */ + +KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { + + /* Control keys. */ + { ISFUNC, rl_set_mark }, /* Control-@ */ + { ISFUNC, rl_beg_of_line }, /* Control-a */ + { ISFUNC, rl_backward_char }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_delete }, /* Control-d */ + { ISFUNC, rl_end_of_line }, /* Control-e */ + { ISFUNC, rl_forward_char }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, rl_char_search }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_undo_command }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { 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) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { 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 */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_meta_keymap = { + + /* Meta keys. Just like above, but the high bit is set. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */ + { ISFUNC, rl_abort }, /* Meta-Control-g */ + { ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */ + { ISFUNC, rl_tab_insert }, /* Meta-Control-i */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-l */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */ + { ISFUNC, rl_revert_line }, /* Meta-Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */ + { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */ + + { ISFUNC, rl_complete }, /* Meta-Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */ + { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_set_mark }, /* Meta-SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */ + { ISFUNC, rl_insert_comment }, /* Meta-# */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */ + { ISFUNC, rl_tilde_expand }, /* Meta-& */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */ + { ISFUNC, rl_insert_completions }, /* Meta-* */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */ + { ISFUNC, rl_digit_argument }, /* Meta-- */ + { ISFUNC, rl_yank_last_arg}, /* Meta-. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */ + + /* Regular digits. */ + { ISFUNC, rl_digit_argument }, /* Meta-0 */ + { ISFUNC, rl_digit_argument }, /* Meta-1 */ + { ISFUNC, rl_digit_argument }, /* Meta-2 */ + { ISFUNC, rl_digit_argument }, /* Meta-3 */ + { ISFUNC, rl_digit_argument }, /* Meta-4 */ + { ISFUNC, rl_digit_argument }, /* Meta-5 */ + { ISFUNC, rl_digit_argument }, /* Meta-6 */ + { ISFUNC, rl_digit_argument }, /* Meta-7 */ + { ISFUNC, rl_digit_argument }, /* Meta-8 */ + { ISFUNC, rl_digit_argument }, /* Meta-9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */ + { ISFUNC, rl_beginning_of_history }, /* Meta-< */ + { ISFUNC, rl_possible_completions }, /* Meta-= */ + { ISFUNC, rl_end_of_history }, /* Meta-> */ + { ISFUNC, rl_possible_completions }, /* Meta-? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-A */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-B */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-C */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-D */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-E */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-F */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-G */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-H */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-I */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-J */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-K */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-L */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-M */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-N */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-O */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-P */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Q */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-R */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-S */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-T */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-U */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-V */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-W */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-X */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Y */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */ + { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */ + { ISFUNC, rl_yank_last_arg }, /* Meta-_ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */ + { ISFUNC, rl_backward_word }, /* Meta-b */ + { ISFUNC, rl_capitalize_word }, /* Meta-c */ + { ISFUNC, rl_kill_word }, /* Meta-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */ + { ISFUNC, rl_forward_word }, /* Meta-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */ + { ISFUNC, rl_downcase_word }, /* Meta-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */ + { ISFUNC, rl_noninc_forward_search }, /* Meta-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */ + { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */ + { ISFUNC, rl_revert_line }, /* Meta-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */ + { ISFUNC, rl_transpose_words }, /* Meta-t */ + { ISFUNC, rl_upcase_word }, /* Meta-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */ + { ISFUNC, rl_yank_pop }, /* Meta-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */ + { ISFUNC, rl_tilde_expand }, /* Meta-~ */ + { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = { + + /* Control keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, rl_re_read_init_file }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, rl_undo_command }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, rl_exchange_point_and_mark }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, rl_start_kbd_macro }, /* ( */ + { ISFUNC, rl_end_kbd_macro }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, rl_call_last_kbd_macro }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_line }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; diff --git a/readline-4.3.orig/examples/Inputrc b/readline-4.3.orig/examples/Inputrc new file mode 100644 index 0000000..d7fdb42 --- /dev/null +++ b/readline-4.3.orig/examples/Inputrc @@ -0,0 +1,81 @@ +# My ~/.inputrc file is in -*- text -*- for easy editing with Emacs. +# +# Notice the various bindings which are conditionalized depending +# on which program is running, or what terminal is active. +# + +# Copyright (C) 1989-2002 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 USA. + +# In all programs, all terminals, make sure this is bound. +"\C-x\C-r": re-read-init-file + +# Hp terminals (and some others) have ugly default behaviour for C-h. +"\C-h": backward-delete-char +"\e\C-h": backward-kill-word +"\C-xd": dump-functions + +# In xterm windows, make the arrow keys do the right thing. +$if TERM=xterm +"\e[A": previous-history +"\e[B": next-history +"\e[C": forward-char +"\e[D": backward-char + +# alternate arrow key prefix +"\eOA": previous-history +"\eOB": next-history +"\eOC": forward-char +"\eOD": backward-char + +# Under Xterm in Bash, we bind local Function keys to do something useful. +$if Bash +"\e[11~": "Function Key 1" +"\e[12~": "Function Key 2" +"\e[13~": "Function Key 3" +"\e[14~": "Function Key 4" +"\e[15~": "Function Key 5" + +# I know the following escape sequence numbers are 1 greater than +# the function key. Don't ask me why, I didn't design the xterm terminal. +"\e[17~": "Function Key 6" +"\e[18~": "Function Key 7" +"\e[19~": "Function Key 8" +"\e[20~": "Function Key 9" +"\e[21~": "Function Key 10" +$endif +$endif + +# For Bash, all terminals, add some Bash specific hacks. +$if Bash +"\C-xv": show-bash-version +"\C-x\C-e": shell-expand-line + +# Here is one for editing my path. +"\C-xp": "$PATH\C-x\C-e\C-e\"\C-aPATH=\":\C-b" + +# Make C-x r read my mail in emacs. +# "\C-xr": "emacs -f rmail\C-j" +$endif + +# For FTP, different hacks: +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif + +" ": self-insert diff --git a/readline-4.3.orig/examples/Makefile.in b/readline-4.3.orig/examples/Makefile.in new file mode 100644 index 0000000..72c9904 --- /dev/null +++ b/readline-4.3.orig/examples/Makefile.in @@ -0,0 +1,104 @@ +# +# This is the Makefile for the readline examples subdirectory. +# +# Copyright (C) 1994 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 USA. +RL_LIBRARY_VERSION = @LIBVERSION@ + +SHELL = @MAKE_SHELL@ +RM = rm -f + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +top_srcdir = @top_srcdir@ +BUILD_DIR = . + +# Support an alternate destination root directory for package building +DESTDIR = + +DEFS = @DEFS@ +CC = @CC@ +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DREADLINE_LIBRARY -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I$(srcdir) -I$(top_srcdir) -I.. + +CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS) +LDFLAGS = -g -L.. @LDFLAGS@ + +READLINE_LIB = ../libreadline.a +HISTORY_LIB = ../libhistory.a + +TERMCAP_LIB = @TERMCAP_LIB@ + +.c.o: + ${RM} $@ + $(CC) $(CCFLAGS) -c $< + +EXECUTABLES = fileman rltest rl rlcat rlversion histexamp +OBJECTS = fileman.o rltest.o rl.o rlversion.o histexamp.o + +all: $(EXECUTABLES) +everything: all rlfe + +rl: rl.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rl.o -lreadline $(TERMCAP_LIB) + +rlcat: rlcat.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline $(TERMCAP_LIB) + +fileman: fileman.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ fileman.o -lreadline $(TERMCAP_LIB) + +rltest: rltest.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rltest.o -lreadline $(TERMCAP_LIB) + +rlversion: rlversion.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rlversion.o -lreadline $(TERMCAP_LIB) + +histexamp: histexamp.o $(HISTORY_LIB) + $(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 + +fileman.o: fileman.c +rltest.o: rltest.c +rl.o: rl.c +rlversion.o: rlversion.c +histexamp.o: histexamp.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 diff --git a/readline-4.3.orig/examples/excallback.c b/readline-4.3.orig/examples/excallback.c new file mode 100644 index 0000000..3d4bb18 --- /dev/null +++ b/readline-4.3.orig/examples/excallback.c @@ -0,0 +1,188 @@ +/* +From: Jeff Solomon +Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT) +To: chet@po.cwru.edu +Subject: new readline example +Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU> + +Chet, + +I've been using readline 4.0. Specifically, I've been using the perl +version Term::ReadLine::Gnu. It works great. + +Anyway, I've been playing around the alternate interface and I wanted +to contribute a little C program, callback.c, to you that you could +use as an example of the alternate interface in the /examples +directory of the readline distribution. + +My example shows how, using the alternate interface, you can +interactively change the prompt (which is very nice imo). Also, I +point out that you must roll your own terminal setting when using the +alternate interface because readline depreps (using your parlance) the +terminal while in the user callback. I try to demostrate what I mean +with an example. I've included the program below. + +To compile, I just put the program in the examples directory and made +the appropriate changes to the EXECUTABLES and OBJECTS line and added +an additional target 'callback'. + +I compiled on my Sun Solaris2.6 box using Sun's cc. + +Let me know what you think. + +Jeff +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include /* xxx - should make this more general */ + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +/* This little examples demonstrates the alternate interface to using readline. + * In the alternate interface, the user maintains control over program flow and + * only calls readline when STDIN is readable. Using the alternate interface, + * you can do anything else while still using readline (like talking to a + * network or another program) without blocking. + * + * Specifically, this program highlights two importants features of the + * alternate interface. The first is the ability to interactively change the + * prompt, which can't be done using the regular interface since rl_prompt is + * read-only. + * + * The second feature really highlights a subtle point when using the alternate + * interface. That is, readline will not alter the terminal when inside your + * callback handler. So let's so, your callback executes a user command that + * takes a non-trivial amount of time to complete (seconds). While your + * executing the command, the user continues to type keystrokes and expects them + * to be re-echoed on the new prompt when it returns. Unfortunately, the default + * terminal configuration doesn't do this. After the prompt returns, the user + * must hit one additional keystroke and then will see all of his previous + * keystrokes. To illustrate this, compile and run this program. Type "sleep" at + * the prompt and then type "bar" before the prompt returns (you have 3 + * seconds). Notice how "bar" is re-echoed on the prompt after the prompt + * returns? This is what you expect to happen. Now comment out the 4 lines below + * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do + * the same thing. When the prompt returns, you should not see "bar". Now type + * "f", see how "barf" magically appears? This behavior is un-expected and not + * desired. + */ + +void process_line(char *line); +int change_prompt(void); +char *get_prompt(void); + +int prompt = 1; +char prompt_buf[40], line_buf[256]; +tcflag_t old_lflag; +cc_t old_vtime; +struct termios term; + +int +main() +{ + fd_set fds; + + /* Adjust the terminal slightly before the handler is installed. Disable + * canonical mode processing and set the input character time flag to be + * non-blocking. + */ + if( tcgetattr(STDIN_FILENO, &term) < 0 ) { + perror("tcgetattr"); + exit(1); + } + old_lflag = term.c_lflag; + old_vtime = term.c_cc[VTIME]; + term.c_lflag &= ~ICANON; + term.c_cc[VTIME] = 1; + /* COMMENT LINE BELOW - see above */ + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + + rl_add_defun("change-prompt", change_prompt, CTRL('t')); + rl_callback_handler_install(get_prompt(), process_line); + + while(1) { + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + + if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(1); + } + + if( FD_ISSET(fileno(stdin), &fds) ) { + rl_callback_read_char(); + } + } +} + +void +process_line(char *line) +{ + if( line == NULL ) { + fprintf(stderr, "\n", line); + + /* reset the old terminal setting before exiting */ + term.c_lflag = old_lflag; + term.c_cc[VTIME] = old_vtime; + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + exit(0); + } + + if( strcmp(line, "sleep") == 0 ) { + sleep(3); + } else { + fprintf(stderr, "|%s|\n", line); + } + + free (line); +} + +int +change_prompt(void) +{ + /* toggle the prompt variable */ + prompt = !prompt; + + /* save away the current contents of the line */ + strcpy(line_buf, rl_line_buffer); + + /* install a new handler which will change the prompt and erase the current line */ + rl_callback_handler_install(get_prompt(), process_line); + + /* insert the old text on the new line */ + rl_insert_text(line_buf); + + /* redraw the current line - this is an undocumented function. It invokes the + * redraw-current-line command. + */ + rl_refresh_line(0, 0); +} + +char * +get_prompt(void) +{ + /* The prompts can even be different lengths! */ + sprintf(prompt_buf, "%s", + prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); + return prompt_buf; +} diff --git a/readline-4.3.orig/examples/fileman.c b/readline-4.3.orig/examples/fileman.c new file mode 100644 index 0000000..340eee7 --- /dev/null +++ b/readline-4.3.orig/examples/fileman.c @@ -0,0 +1,485 @@ +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_SYS_FILE_H +# include +#endif +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern char *xmalloc (); + +/* The names of functions that actually do the manipulation. */ +int com_list PARAMS((char *)); +int com_view PARAMS((char *)); +int com_rename PARAMS((char *)); +int com_stat PARAMS((char *)); +int com_pwd PARAMS((char *)); +int com_delete PARAMS((char *)); +int com_help PARAMS((char *)); +int com_cd PARAMS((char *)); +int com_quit PARAMS((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 global means the user is done using this program. */ +int done; + +char * +dupstr (s) + char *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 PARAMS((const char *, int)); +char **fileman_completion PARAMS((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. Return the 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; + +#if defined (__MSDOS__) + /* more.com doesn't grok slashes in pathnames */ + sprintf (syscom, "less %s", arg); +#else + sprintf (syscom, "more %s", arg); +#endif + 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. Write it yourself.\n", + caller); +} + +/* 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); +} diff --git a/readline-4.3.orig/examples/histexamp.c b/readline-4.3.orig/examples/histexamp.c new file mode 100644 index 0000000..45651df --- /dev/null +++ b/readline-4.3.orig/examples/histexamp.c @@ -0,0 +1,112 @@ +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include + +#ifdef READLINE_LIBRARY +# include "history.h" +#else +# include +#endif + +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; + + using_history (); + + 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"); + } + } + } +} diff --git a/readline-4.3.orig/examples/manexamp.c b/readline-4.3.orig/examples/manexamp.c new file mode 100644 index 0000000..9c6cf2c --- /dev/null +++ b/readline-4.3.orig/examples/manexamp.c @@ -0,0 +1,112 @@ +/* manexamp.c -- The examples which appear in the documentation are here. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include +#include + +/* **************************************************************** */ +/* */ +/* How to Emulate gets () */ +/* */ +/* **************************************************************** */ + +/* 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); +} + +/* **************************************************************** */ +/* */ +/* Writing a Function to be Called by Readline. */ +/* */ +/* **************************************************************** */ + +/* Invert the case of the COUNT following characters. */ +invert_case_line (count, key) + int count, key; +{ + register int start, end; + + start = rl_point; + + 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 = -1; + + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + if (start == end) + return; + + /* Tell readline that we are modifying the line, so save the undo + information. */ + rl_modifying (start, end); + + for (; start != end; start += direction) + { + if (_rl_uppercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); + else if (_rl_lowercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); + } + + /* Move point to on top of the last character changed. */ + rl_point = end - direction; +} diff --git a/readline-4.3.orig/examples/readlinebuf.h b/readline-4.3.orig/examples/readlinebuf.h new file mode 100644 index 0000000..91ef4d6 --- /dev/null +++ b/readline-4.3.orig/examples/readlinebuf.h @@ -0,0 +1,139 @@ +/******************************************************************************* + * $Revision$ + * $Date$ + * $Author$ + * + * Contents: A streambuf which uses the GNU readline library for line I/O + * (c) 2001 by Dimitris Vyzovitis [vyzo@media.mit.edu] + * + * 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 + * + ******************************************************************************/ + +#ifndef _READLINEBUF_H_ +#define _READLINEBUF_H_ + +#include +#include +#include +#include +#include + +#include +#include + +#if (defined __GNUC__) && (__GNUC__ < 3) +#include +#else +#include +using std::streamsize; +using std::streambuf; +#endif + +class readlinebuf : public streambuf { +public: +#if (defined __GNUC__) && (__GNUC__ < 3) + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; +#endif + static const int_type eof = EOF; // this is -1 + static const int_type not_eof = 0; + +private: + const char* prompt_; + bool history_; + char* line_; + int low_; + int high_; + +protected: + + virtual int_type showmanyc() const { return high_ - low_; } + + virtual streamsize xsgetn( char_type* buf, streamsize n ) { + int rd = n > (high_ - low_)? (high_ - low_) : n; + memcpy( buf, line_, rd ); + low_ += rd; + + if ( rd < n ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + rd += xsgetn( buf + rd, n - rd ); + } + } + + return rd; + } + + virtual int_type underflow() { + if ( high_ == low_ ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + } + } + + if ( low_ < high_ ) return line_[low_]; + else return eof; + } + + virtual int_type uflow() { + int_type c = underflow(); + if ( c != eof ) ++low_; + return c; + } + + virtual int_type pbackfail( int_type c = eof ) { + if ( low_ > 0 ) --low_; + else if ( c != eof ) { + if ( high_ > 0 ) { + char* nl = (char*)realloc( line_, high_ + 1 ); + if ( nl ) { + line_ = (char*)memcpy( nl + 1, line_, high_ ); + high_ += 1; + line_[0] = char( c ); + } else return eof; + } else { + assert( !line_ ); + line_ = (char*)malloc( sizeof( char ) ); + *line_ = char( c ); + high_ = 1; + } + } else return eof; + + return not_eof; + } + +public: + readlinebuf( const char* prompt = NULL, bool history = true ) + : prompt_( prompt ), history_( history ), + line_( NULL ), low_( 0 ), high_( 0 ) { + setbuf( 0, 0 ); + } + + +}; + +#endif diff --git a/readline-4.3.orig/examples/rl.c b/readline-4.3.orig/examples/rl.c new file mode 100644 index 0000000..d260489 --- /dev/null +++ b/readline-4.3.orig/examples/rl.c @@ -0,0 +1,151 @@ +/* + * rl - command-line interface to read a line from the standard input + * (or another fd) using readline. + * + * usage: rl [-p prompt] [-u unit] [-d default] [-n nchars] + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixstat.h" + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +#if !defined (strchr) && !defined (__STDC__) +extern char *strrchr(); +#endif + +static char *progname; +static char *deftext; + +static int +set_deftext () +{ + if (deftext) + { + rl_insert_text (deftext); + deftext = (char *)NULL; + rl_startup_hook = (rl_hook_func_t *)NULL; + } + return 0; +} + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n", + progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp, *prompt; + struct stat sb; + int opt, fd, nch; + FILE *ifp; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + /* defaults */ + prompt = "readline$ "; + fd = nch = 0; + deftext = (char *)0; + + while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF) + { + switch (opt) + { + case 'p': + prompt = optarg; + break; + case 'u': + fd = atoi(optarg); + if (fd < 0) + { + fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg); + exit (2); + } + break; + case 'd': + deftext = optarg; + break; + case 'n': + nch = atoi(optarg); + if (nch < 0) + { + fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg); + exit (2); + } + break; + default: + usage (); + exit (2); + } + } + + if (fd != 0) + { + if (fstat (fd, &sb) < 0) + { + fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd); + exit (1); + } + ifp = fdopen (fd, "r"); + rl_instream = ifp; + } + + if (deftext && *deftext) + rl_startup_hook = set_deftext; + + if (nch > 0) + rl_num_chars_to_read = nch; + + temp = readline (prompt); + + /* Test for EOF. */ + if (temp == 0) + exit (1); + + printf ("%s\n", temp); + exit (0); +} diff --git a/readline-4.3.orig/examples/rlcat.c b/readline-4.3.orig/examples/rlcat.c new file mode 100644 index 0000000..176b9f4 --- /dev/null +++ b/readline-4.3.orig/examples/rlcat.c @@ -0,0 +1,174 @@ +/* + * rlcat - cat(1) using readline + * + * usage: rlcat + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include "posixstat.h" + +#include +#include +#include +#include + +#ifndef errno +extern int errno; +#endif + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +static int stdcat(); + +static char *progname; +static int vflag; + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp; + int opt, Vflag, Nflag; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + vflag = Vflag = Nflag = 0; + while ((opt = getopt(argc, argv, "vEVN")) != EOF) + { + switch (opt) + { + case 'v': + vflag = 1; + break; + case 'V': + Vflag = 1; + break; + case 'E': + Vflag = 0; + break; + case 'N': + Nflag = 1; + break; + default: + usage (); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (isatty(0) == 0 || argc || Nflag) + return stdcat(argc, argv); + + rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs"); + while (temp = readline ("")) + { + if (*temp) + add_history (temp); + printf ("%s\n", temp); + } + + return (ferror (stdout)); +} + +static int +fcopy(fp) + FILE *fp; +{ + int c; + char *x; + + while ((c = getc(fp)) != EOF) + { + if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0) + { + x = rl_untranslate_keyseq (c); + if (fputs (x, stdout) != 0) + return 1; + } + else if (putchar (c) == EOF) + return 1; + } + return (ferror (stdout)); +} + +int +stdcat (argc, argv) + int argc; + char **argv; +{ + int i, fd, r; + char *s; + FILE *fp; + + if (argc == 0) + return (fcopy(stdin)); + + for (i = 0, r = 1; i < argc; i++) + { + if (*argv[i] == '-' && argv[i][1] == 0) + fp = stdin; + else + { + fp = fopen (argv[i], "r"); + if (fp == 0) + { + fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno)); + continue; + } + } + r = fcopy (fp); + if (fp != stdin) + fclose(fp); + } + return r; +} diff --git a/readline-4.3.orig/examples/rlfe.c b/readline-4.3.orig/examples/rlfe.c new file mode 100644 index 0000000..d634d7c --- /dev/null +++ b/readline-4.3.orig/examples/rlfe.c @@ -0,0 +1,1042 @@ +/* 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#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-4.3.orig/examples/rltest.c b/readline-4.3.orig/examples/rltest.c new file mode 100644 index 0000000..99f083b --- /dev/null +++ b/readline-4.3.orig/examples/rltest.c @@ -0,0 +1,87 @@ +/* **************************************************************** */ +/* */ +/* Testing Readline */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern HIST_ENTRY **history_list (); + +main () +{ + char *temp, *prompt; + int done; + + temp = (char *)NULL; + prompt = "readline$ "; + done = 0; + + while (!done) + { + temp = readline (prompt); + + /* Test for EOF. */ + if (!temp) + exit (1); + + /* If there is anything on the line, print it and remember it. */ + if (*temp) + { + fprintf (stderr, "%s\r\n", temp); + add_history (temp); + } + + /* Check for `command' that we handle. */ + if (strcmp (temp, "quit") == 0) + done = 1; + + if (strcmp (temp, "list") == 0) + { + HIST_ENTRY **list; + register int i; + + list = history_list (); + if (list) + { + for (i = 0; list[i]; i++) + fprintf (stderr, "%d: %s\r\n", i, list[i]->line); + } + } + free (temp); + } + exit (0); +} diff --git a/readline-4.3.orig/examples/rlversion.c b/readline-4.3.orig/examples/rlversion.c new file mode 100644 index 0000000..53949d1 --- /dev/null +++ b/readline-4.3.orig/examples/rlversion.c @@ -0,0 +1,43 @@ +/* + * rlversion -- print out readline's version number + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixstat.h" + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +main() +{ + printf ("%s\n", rl_library_version ? rl_library_version : "unknown"); + exit (0); +} diff --git a/readline-4.3.orig/funmap.c b/readline-4.3.orig/funmap.c new file mode 100644 index 0000000..fe9a1da --- /dev/null +++ b/readline-4.3.orig/funmap.c @@ -0,0 +1,253 @@ +/* funmap.c -- attach names to functions. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if !defined (BUFSIZ) +#include +#endif /* BUFSIZ */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "rlconf.h" +#include "readline.h" + +#include "xmalloc.h" + +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +extern int _rl_qsort_string_compare PARAMS((char **, char **)); + +FUNMAP **funmap; +static int funmap_size; +static int funmap_entry; + +/* After initializing the function map, this is the index of the first + program specific function. */ +int funmap_program_specific_entry_start; + +static FUNMAP default_funmap[] = { + { "abort", rl_abort }, + { "accept-line", rl_newline }, + { "arrow-key-prefix", rl_arrow_keys }, + { "backward-byte", rl_backward_byte }, + { "backward-char", rl_backward_char }, + { "backward-delete-char", rl_rubout }, + { "backward-kill-line", rl_backward_kill_line }, + { "backward-kill-word", rl_backward_kill_word }, + { "backward-word", rl_backward_word }, + { "beginning-of-history", rl_beginning_of_history }, + { "beginning-of-line", rl_beg_of_line }, + { "call-last-kbd-macro", rl_call_last_kbd_macro }, + { "capitalize-word", rl_capitalize_word }, + { "character-search", rl_char_search }, + { "character-search-backward", rl_backward_char_search }, + { "clear-screen", rl_clear_screen }, + { "complete", rl_complete }, + { "copy-backward-word", rl_copy_backward_word }, + { "copy-forward-word", rl_copy_forward_word }, + { "copy-region-as-kill", rl_copy_region_to_kill }, + { "delete-char", rl_delete }, + { "delete-char-or-list", rl_delete_or_show_completions }, + { "delete-horizontal-space", rl_delete_horizontal_space }, + { "digit-argument", rl_digit_argument }, + { "do-lowercase-version", rl_do_lowercase_version }, + { "downcase-word", rl_downcase_word }, + { "dump-functions", rl_dump_functions }, + { "dump-macros", rl_dump_macros }, + { "dump-variables", rl_dump_variables }, + { "emacs-editing-mode", rl_emacs_editing_mode }, + { "end-kbd-macro", rl_end_kbd_macro }, + { "end-of-history", rl_end_of_history }, + { "end-of-line", rl_end_of_line }, + { "exchange-point-and-mark", rl_exchange_point_and_mark }, + { "forward-backward-delete-char", rl_rubout_or_delete }, + { "forward-byte", rl_forward_byte }, + { "forward-char", rl_forward_char }, + { "forward-search-history", rl_forward_search_history }, + { "forward-word", rl_forward_word }, + { "history-search-backward", rl_history_search_backward }, + { "history-search-forward", rl_history_search_forward }, + { "insert-comment", rl_insert_comment }, + { "insert-completions", rl_insert_completions }, + { "kill-whole-line", rl_kill_full_line }, + { "kill-line", rl_kill_line }, + { "kill-region", rl_kill_region }, + { "kill-word", rl_kill_word }, + { "menu-complete", rl_menu_complete }, + { "next-history", rl_get_next_history }, + { "non-incremental-forward-search-history", rl_noninc_forward_search }, + { "non-incremental-reverse-search-history", rl_noninc_reverse_search }, + { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, + { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, + { "overwrite-mode", rl_overwrite_mode }, +#ifdef __CYGWIN__ + { "paste-from-clipboard", rl_paste_from_clipboard }, +#endif + { "possible-completions", rl_possible_completions }, + { "previous-history", rl_get_previous_history }, + { "quoted-insert", rl_quoted_insert }, + { "re-read-init-file", rl_re_read_init_file }, + { "redraw-current-line", rl_refresh_line}, + { "reverse-search-history", rl_reverse_search_history }, + { "revert-line", rl_revert_line }, + { "self-insert", rl_insert }, + { "set-mark", rl_set_mark }, + { "start-kbd-macro", rl_start_kbd_macro }, + { "tab-insert", rl_tab_insert }, + { "tilde-expand", rl_tilde_expand }, + { "transpose-chars", rl_transpose_chars }, + { "transpose-words", rl_transpose_words }, + { "tty-status", rl_tty_status }, + { "undo", rl_undo_command }, + { "universal-argument", rl_universal_argument }, + { "unix-line-discard", rl_unix_line_discard }, + { "unix-word-rubout", rl_unix_word_rubout }, + { "upcase-word", rl_upcase_word }, + { "yank", rl_yank }, + { "yank-last-arg", rl_yank_last_arg }, + { "yank-nth-arg", rl_yank_nth_arg }, + { "yank-pop", rl_yank_pop }, + +#if defined (VI_MODE) + { "vi-append-eol", rl_vi_append_eol }, + { "vi-append-mode", rl_vi_append_mode }, + { "vi-arg-digit", rl_vi_arg_digit }, + { "vi-back-to-indent", rl_vi_back_to_indent }, + { "vi-bWord", rl_vi_bWord }, + { "vi-bword", rl_vi_bword }, + { "vi-change-case", rl_vi_change_case }, + { "vi-change-char", rl_vi_change_char }, + { "vi-change-to", rl_vi_change_to }, + { "vi-char-search", rl_vi_char_search }, + { "vi-column", rl_vi_column }, + { "vi-complete", rl_vi_complete }, + { "vi-delete", rl_vi_delete }, + { "vi-delete-to", rl_vi_delete_to }, + { "vi-eWord", rl_vi_eWord }, + { "vi-editing-mode", rl_vi_editing_mode }, + { "vi-end-word", rl_vi_end_word }, + { "vi-eof-maybe", rl_vi_eof_maybe }, + { "vi-eword", rl_vi_eword }, + { "vi-fWord", rl_vi_fWord }, + { "vi-fetch-history", rl_vi_fetch_history }, + { "vi-first-print", rl_vi_first_print }, + { "vi-fword", rl_vi_fword }, + { "vi-goto-mark", rl_vi_goto_mark }, + { "vi-insert-beg", rl_vi_insert_beg }, + { "vi-insertion-mode", rl_vi_insertion_mode }, + { "vi-match", rl_vi_match }, + { "vi-movement-mode", rl_vi_movement_mode }, + { "vi-next-word", rl_vi_next_word }, + { "vi-overstrike", rl_vi_overstrike }, + { "vi-overstrike-delete", rl_vi_overstrike_delete }, + { "vi-prev-word", rl_vi_prev_word }, + { "vi-put", rl_vi_put }, + { "vi-redo", rl_vi_redo }, + { "vi-replace", rl_vi_replace }, + { "vi-search", rl_vi_search }, + { "vi-search-again", rl_vi_search_again }, + { "vi-set-mark", rl_vi_set_mark }, + { "vi-subst", rl_vi_subst }, + { "vi-tilde-expand", rl_vi_tilde_expand }, + { "vi-yank-arg", rl_vi_yank_arg }, + { "vi-yank-to", rl_vi_yank_to }, +#endif /* VI_MODE */ + + {(char *)NULL, (rl_command_func_t *)NULL } +}; + +int +rl_add_funmap_entry (name, function) + const char *name; + rl_command_func_t *function; +{ + if (funmap_entry + 2 >= funmap_size) + { + funmap_size += 64; + funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *)); + } + + funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP)); + funmap[funmap_entry]->name = name; + funmap[funmap_entry]->function = function; + + funmap[++funmap_entry] = (FUNMAP *)NULL; + return funmap_entry; +} + +static int funmap_initialized; + +/* Make the funmap contain all of the default entries. */ +void +rl_initialize_funmap () +{ + register int i; + + if (funmap_initialized) + return; + + for (i = 0; default_funmap[i].name; i++) + rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function); + + funmap_initialized = 1; + funmap_program_specific_entry_start = i; +} + +/* Produce a NULL terminated array of known function names. The array + is sorted. The array itself is allocated, but not the strings inside. + You should free () the array when you done, but not the pointrs. */ +const char ** +rl_funmap_names () +{ + const char **result; + int result_size, result_index; + + /* Make sure that the function map has been initialized. */ + rl_initialize_funmap (); + + for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++) + { + if (result_index + 2 > result_size) + { + result_size += 20; + result = (const char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index] = funmap[result_index]->name; + result[result_index + 1] = (char *)NULL; + } + + qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + return (result); +} diff --git a/readline-4.3.orig/histexpand.c b/readline-4.3.orig/histexpand.c new file mode 100644 index 0000000..6c81196 --- /dev/null +++ b/readline-4.3.orig/histexpand.c @@ -0,0 +1,1491 @@ +/* histexpand.c -- history expansion. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifndef _MINIX +# include +# endif +# include +#endif + +#include "rlmbutil.h" + +#include "history.h" +#include "histlib.h" + +#include "rlshell.h" +#include "xmalloc.h" + +#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" +#define HISTORY_QUOTE_CHARACTERS "\"'`" + +typedef int _hist_search_func_t PARAMS((const char *, int)); + +extern int rl_byte_oriented; /* declared in mbutil.c */ + +static char error_pointer; + +static char *subst_lhs; +static char *subst_rhs; +static int subst_lhs_len; +static int subst_rhs_len; + +static char *get_history_word_specifier PARAMS((char *, char *, int *)); +static char *history_find_word PARAMS((char *, int)); + +static char *quote_breaks PARAMS((char *)); + +/* Variables exported by this file. */ +/* The character that represents the start of a history expansion + request. This is usually `!'. */ +char history_expansion_char = '!'; + +/* The character that invokes word substitution if found at the start of + a line. This is usually `^'. */ +char history_subst_char = '^'; + +/* During tokenization, if this character is seen as the first character + of a word, then it, and all subsequent characters upto a newline are + ignored. For a Bourne shell, this should be '#'. Bash special cases + the interactive comment character to not be a comment delimiter. */ +char history_comment_char = '\0'; + +/* The list of characters which inhibit the expansion of text if found + immediately following history_expansion_char. */ +char *history_no_expand_chars = " \t\n\r="; + +/* If set to a non-zero value, single quotes inhibit history expansion. + The default is 0. */ +int history_quotes_inhibit_expansion = 0; + +/* Used to split words by history_tokenize_internal. */ +char *history_word_delimiters = HISTORY_WORD_DELIMITERS; + +/* If set, this points to a function that is called to verify that a + particular history expansion should be performed. */ +rl_linebuf_func_t *history_inhibit_expansion_function; + +/* **************************************************************** */ +/* */ +/* History Expansion */ +/* */ +/* **************************************************************** */ + +/* Hairy history expansion on text, not tokens. This is of general + use, and thus belongs in this library. */ + +/* The last string searched for by a !?string? search. */ +static char *search_string; + +/* The last string matched by a !?string? search. */ +static char *search_match; + +/* Return the event specified at TEXT + OFFSET modifying OFFSET to + point to after the event specifier. Just a pointer to the history + line is returned; NULL is returned in the event of a bad specifier. + You pass STRING with *INDEX equal to the history_expansion_char that + begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. + So you might call this function like: + line = get_history_event ("!echo:p", &index, 0); */ +char * +get_history_event (string, caller_index, delimiting_quote) + const char *string; + int *caller_index; + int delimiting_quote; +{ + register int i; + register char c; + HIST_ENTRY *entry; + int which, sign, local_index, substring_okay; + _hist_search_func_t *search_func; + char *temp; + + /* The event can be specified in a number of ways. + + !! the previous command + !n command line N + !-n current command-line minus N + !str the most recent command starting with STR + !?str[?] + the most recent command containing STR + + All values N are determined via HISTORY_BASE. */ + + i = *caller_index; + + if (string[i] != history_expansion_char) + return ((char *)NULL); + + /* Move on to the specification. */ + i++; + + sign = 1; + substring_okay = 0; + +#define RETURN_ENTRY(e, w) \ + return ((e = history_get (w)) ? e->line : (char *)NULL) + + /* Handle !! case. */ + if (string[i] == history_expansion_char) + { + i++; + which = history_base + (history_length - 1); + *caller_index = i; + RETURN_ENTRY (entry, which); + } + + /* Hack case of numeric line specification. */ + if (string[i] == '-') + { + sign = -1; + i++; + } + + if (_rl_digit_p (string[i])) + { + /* Get the extent of the digits and compute the value. */ + for (which = 0; _rl_digit_p (string[i]); i++) + which = (which * 10) + _rl_digit_value (string[i]); + + *caller_index = i; + + if (sign < 0) + which = (history_length + history_base) - which; + + RETURN_ENTRY (entry, which); + } + + /* This must be something to search for. If the spec begins with + a '?', then the string may be anywhere on the line. Otherwise, + the string must be found at the start of a line. */ + if (string[i] == '?') + { + substring_okay++; + i++; + } + + /* 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; + + 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)) || + string[i] == delimiting_quote)) || + string[i] == '\n' || + (substring_okay && string[i] == '?')) + break; + + which = i - local_index; + temp = (char *)xmalloc (1 + which); + if (which) + strncpy (temp, string + local_index, which); + temp[which] = '\0'; + + if (substring_okay && string[i] == '?') + i++; + + *caller_index = i; + +#define FAIL_SEARCH() \ + do { \ + history_offset = history_length; free (temp) ; return (char *)NULL; \ + } while (0) + + /* If there is no search string, try to use the previous search string, + if one exists. If not, fail immediately. */ + if (*temp == '\0' && substring_okay) + { + if (search_string) + { + free (temp); + temp = savestring (search_string); + } + else + FAIL_SEARCH (); + } + + search_func = substring_okay ? history_search : history_search_prefix; + while (1) + { + local_index = (*search_func) (temp, -1); + + if (local_index < 0) + FAIL_SEARCH (); + + if (local_index == 0 || substring_okay) + { + entry = current_history (); + history_offset = history_length; + + /* If this was a substring search, then remember the + string that we matched for word substitution. */ + if (substring_okay) + { + FREE (search_string); + search_string = temp; + + FREE (search_match); + search_match = history_find_word (entry->line, local_index); + } + else + free (temp); + + return (entry->line); + } + + if (history_offset) + history_offset--; + else + FAIL_SEARCH (); + } +#undef FAIL_SEARCH +#undef RETURN_ENTRY +} + +/* Function for extracting single-quoted strings. Used for inhibiting + history expansion within single quotes. */ + +/* Extract the contents of STRING as if it is enclosed in single quotes. + SINDEX, when passed in, is the offset of the character immediately + following the opening single quote; on exit, SINDEX is left pointing + to the closing single quote. */ +static void +hist_string_extract_single_quoted (string, sindex) + char *string; + int *sindex; +{ + register int i; + + for (i = *sindex; string[i] && string[i] != '\''; i++) + ; + + *sindex = i; +} + +static char * +quote_breaks (s) + char *s; +{ + register char *p, *r; + char *ret; + int len = 3; + + for (p = s; p && *p; p++, len++) + { + if (*p == '\'') + len += 3; + else if (whitespace (*p) || *p == '\n') + len += 2; + } + + r = ret = (char *)xmalloc (len); + *r++ = '\''; + for (p = s; p && *p; ) + { + if (*p == '\'') + { + *r++ = '\''; + *r++ = '\\'; + *r++ = '\''; + *r++ = '\''; + p++; + } + else if (whitespace (*p) || *p == '\n') + { + *r++ = '\''; + *r++ = *p++; + *r++ = '\''; + } + else + *r++ = *p++; + } + *r++ = '\''; + *r = '\0'; + return ret; +} + +static char * +hist_error(s, start, current, errtype) + char *s; + int start, current, errtype; +{ + char *temp; + const char *emsg; + int ll, elen; + + ll = current - start; + + switch (errtype) + { + case EVENT_NOT_FOUND: + emsg = "event not found"; + elen = 15; + break; + case BAD_WORD_SPEC: + emsg = "bad word specifier"; + elen = 18; + break; + case SUBST_FAILED: + emsg = "substitution failed"; + elen = 19; + break; + case BAD_MODIFIER: + emsg = "unrecognized history modifier"; + elen = 29; + break; + case NO_PREV_SUBST: + emsg = "no previous substitution"; + elen = 24; + break; + default: + emsg = "unknown expansion error"; + elen = 23; + break; + } + + temp = (char *)xmalloc (ll + elen + 3); + strncpy (temp, s + start, ll); + temp[ll] = ':'; + temp[ll + 1] = ' '; + strcpy (temp + ll + 2, emsg); + return (temp); +} + +/* Get a history substitution string from STR starting at *IPTR + and return it. The length is returned in LENPTR. + + A backslash can quote the delimiter. If the string is the + empty string, the previous pattern is used. If there is + no previous pattern for the lhs, the last history search + string is used. + + If IS_RHS is 1, we ignore empty strings and set the pattern + to "" anyway. subst_lhs is not changed if the lhs is empty; + subst_rhs is allowed to be set to the empty string. */ + +static char * +get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) + char *str; + int *iptr, delimiter, is_rhs, *lenptr; +{ + register int si, i, j, k; + char *s; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; +#endif + + s = (char *)NULL; + i = *iptr; + +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); + _rl_adjust_point (str, i, &ps); +#endif + + for (si = i; str[si] && str[si] != delimiter; si++) +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + if ((v = _rl_get_char_len (str + si, &ps)) > 1) + si += v - 1; + else if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + } + else +#endif /* HANDLE_MULTIBYTE */ + if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + + if (si > i || is_rhs) + { + s = (char *)xmalloc (si - i + 1); + for (j = 0, k = i; k < si; j++, k++) + { + /* Remove a backslash quoting the search string delimiter. */ + if (str[k] == '\\' && str[k + 1] == delimiter) + k++; + s[j] = str[k]; + } + s[j] = '\0'; + if (lenptr) + *lenptr = j; + } + + i = si; + if (str[i]) + i++; + *iptr = i; + + return s; +} + +static void +postproc_subst_rhs () +{ + char *new; + int i, j, new_size; + + new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len); + for (i = j = 0; i < subst_rhs_len; i++) + { + if (subst_rhs[i] == '&') + { + if (j + subst_lhs_len >= new_size) + new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); + strcpy (new + j, subst_lhs); + j += subst_lhs_len; + } + else + { + /* a single backslash protects the `&' from lhs interpolation */ + if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') + i++; + if (j >= new_size) + new = (char *)xrealloc (new, new_size *= 2); + new[j++] = subst_rhs[i]; + } + } + new[j] = '\0'; + free (subst_rhs); + subst_rhs = new; + subst_rhs_len = j; +} + +/* Expand the bulk of a history specifier starting at STRING[START]. + Returns 0 if everything is OK, -1 if an error occurred, and 1 + if the `p' modifier was supplied and the caller should just print + the returned string. Returns the new index into string in + *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ +static int +history_expand_internal (string, start, end_index_ptr, ret_string, current_line) + char *string; + int start, *end_index_ptr; + char **ret_string; + char *current_line; /* for !# */ +{ + int i, n, starting_index; + int substitute_globally, want_quotes, print_only; + char *event, *temp, *result, *tstr, *t, c, *word_spec; + int result_len; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + result = (char *)xmalloc (result_len = 128); + + i = start; + + /* If it is followed by something that starts a word specifier, + then !! is implied as the event specifier. */ + + if (member (string[i + 1], ":$*%^")) + { + char fake_s[3]; + int fake_i = 0; + i++; + fake_s[0] = fake_s[1] = history_expansion_char; + fake_s[2] = '\0'; + event = get_history_event (fake_s, &fake_i, 0); + } + else if (string[i + 1] == '#') + { + i += 2; + event = current_line; + } + else + { + int quoted_search_delimiter = 0; + + /* If the character before this `!' is a double or single + quote, then this expansion takes place inside of the + quoted string. If we have to search for some text ("!foo"), + allow the delimiter to end the search string. */ +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int c, l; + l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY); + c = string[l]; + /* XXX - original patch had i - 1 ??? If i == 0 it would fail. */ + if (i && (c == '\'' || c == '"')) + quoted_search_delimiter = c; + } + else +#endif /* HANDLE_MULTIBYTE */ + if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) + quoted_search_delimiter = string[i - 1]; + + event = get_history_event (string, &i, quoted_search_delimiter); + } + + if (event == 0) + { + *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); + free (result); + return (-1); + } + + /* If a word specifier is found, then do what that requires. */ + starting_index = i; + word_spec = get_history_word_specifier (string, event, &i); + + /* There is no such thing as a `malformed word specifier'. However, + it is possible for a specifier that has no match. In that case, + we complain. */ + if (word_spec == (char *)&error_pointer) + { + *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC); + free (result); + return (-1); + } + + /* If no word specifier, than the thing of interest was the event. */ + temp = word_spec ? savestring (word_spec) : savestring (event); + FREE (word_spec); + + /* Perhaps there are other modifiers involved. Do what they say. */ + want_quotes = substitute_globally = print_only = 0; + starting_index = i; + + while (string[i] == ':') + { + c = string[i + 1]; + + if (c == 'g') + { + substitute_globally = 1; + i++; + c = string[i + 1]; + } + + switch (c) + { + default: + *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER); + free (result); + free (temp); + return -1; + + case 'q': + want_quotes = 'q'; + break; + + case 'x': + want_quotes = 'x'; + break; + + /* :p means make this the last executed line. So we + return an error state after adding this line to the + history. */ + case 'p': + print_only++; + break; + + /* :t discards all but the last part of the pathname. */ + case 't': + tstr = strrchr (temp, '/'); + if (tstr) + { + tstr++; + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :h discards the last part of a pathname. */ + case 'h': + tstr = strrchr (temp, '/'); + if (tstr) + *tstr = '\0'; + break; + + /* :r discards the suffix. */ + case 'r': + tstr = strrchr (temp, '.'); + if (tstr) + *tstr = '\0'; + break; + + /* :e discards everything but the suffix. */ + case 'e': + tstr = strrchr (temp, '.'); + if (tstr) + { + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :s/this/that substitutes `that' for the first + occurrence of `this'. :gs/this/that substitutes `that' + for each occurrence of `this'. :& repeats the last + substitution. :g& repeats the last substitution + globally. */ + + case '&': + case 's': + { + char *new_event; + int delimiter, failed, si, l_temp; + + if (c == 's') + { + if (i + 2 < (int)strlen (string)) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + _rl_adjust_point (string, i + 2, &ps); + if (_rl_get_char_len (string + i + 2, &ps) > 1) + delimiter = 0; + else + delimiter = string[i + 2]; + } + else +#endif /* HANDLE_MULTIBYTE */ + delimiter = string[i + 2]; + } + else + break; /* no search delimiter */ + + i += 3; + + t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len); + /* An empty substitution lhs with no previous substitution + uses the last search string as the lhs. */ + if (t) + { + FREE (subst_lhs); + subst_lhs = t; + } + else if (!subst_lhs) + { + if (search_string && *search_string) + { + subst_lhs = savestring (search_string); + subst_lhs_len = strlen (subst_lhs); + } + else + { + subst_lhs = (char *) NULL; + subst_lhs_len = 0; + } + } + + FREE (subst_rhs); + subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len); + + /* If `&' appears in the rhs, it's supposed to be replaced + with the lhs. */ + if (member ('&', subst_rhs)) + postproc_subst_rhs (); + } + else + i += 2; + + /* If there is no lhs, the substitution can't succeed. */ + if (subst_lhs_len == 0) + { + *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST); + free (result); + free (temp); + return -1; + } + + l_temp = strlen (temp); + /* Ignore impossible cases. */ + if (subst_lhs_len > l_temp) + { + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + + /* Find the first occurrence of THIS in TEMP. */ + si = 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; + } + + if (substitute_globally > 1) + { + substitute_globally = 0; + continue; /* don't want to increment i */ + } + + if (failed == 0) + continue; /* don't want to increment i */ + + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + } + i += 2; + } + /* Done with modfiers. */ + /* Believe it or not, we have to back the pointer up by one. */ + --i; + + if (want_quotes) + { + char *x; + + if (want_quotes == 'q') + x = sh_single_quote (temp); + else if (want_quotes == 'x') + x = quote_breaks (temp); + else + x = savestring (temp); + + free (temp); + temp = x; + } + + n = strlen (temp); + if (n >= result_len) + result = (char *)xrealloc (result, n + 2); + strcpy (result, temp); + free (temp); + + *end_index_ptr = i; + *ret_string = result; + return (print_only); +} + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + -1) If there was an error in expansion. + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + 2) If the `p' modifier was given and the caller should print the result + + If an error ocurred in expansion, then OUTPUT contains a descriptive + error message. */ + +#define ADD_STRING(s) \ + do \ + { \ + int sl = strlen (s); \ + j += sl; \ + if (j >= result_len) \ + { \ + while (j >= result_len) \ + result_len += 128; \ + result = (char *)xrealloc (result, result_len); \ + } \ + strcpy (result + j - sl, s); \ + } \ + while (0) + +#define ADD_CHAR(c) \ + do \ + { \ + if (j >= result_len - 1) \ + result = (char *)xrealloc (result, result_len += 64); \ + result[j++] = c; \ + result[j] = '\0'; \ + } \ + while (0) + +int +history_expand (hstring, output) + char *hstring; + char **output; +{ + register int j; + int i, r, l, passc, cc, modified, eindex, only_printing; + char *string; + + /* The output string, and its length. */ + int result_len; + char *result; + +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; + mbstate_t ps; +#endif + + /* Used when adding the string. */ + char *temp; + + if (output == 0) + return 0; + + /* Setting the history expansion character to 0 inhibits all + history expansion. */ + if (history_expansion_char == 0) + { + *output = savestring (hstring); + return (0); + } + + /* Prepare the buffer for printing error messages. */ + result = (char *)xmalloc (result_len = 256); + result[0] = '\0'; + + only_printing = modified = 0; + l = strlen (hstring); + + /* Grovel the string. Only backslash and single quotes can quote the + history escape character. We also handle arg specifiers. */ + + /* Before we grovel forever, see if the history_expansion_char appears + anywhere within the text. */ + + /* The quick substitution character is a history expansion all right. That + is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, + that is the substitution that we do. */ + if (hstring[0] == history_subst_char) + { + string = (char *)xmalloc (l + 5); + + string[0] = string[1] = history_expansion_char; + string[2] = ':'; + string[3] = 's'; + strcpy (string + 4, hstring); + l += 4; + } + else + { +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + string = hstring; + /* If not quick substitution, still maybe have to do expansion. */ + + /* `!' followed by one of the characters in history_no_expand_chars + is NOT an expansion. */ + for (i = 0; string[i]; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + v = _rl_get_char_len (string + i, &ps); + if (v > 1) + { + i += v - 1; + continue; + } + } +#endif /* HANDLE_MULTIBYTE */ + + cc = string[i + 1]; + /* The history_comment_char, if set, appearing at the beginning + of a word signifies that the rest of the line should not have + history expansion performed on it. + Skip the rest of the line and break out of the loop. */ + if (history_comment_char && string[i] == history_comment_char && + (i == 0 || member (string[i - 1], history_word_delimiters))) + { + while (string[i]) + i++; + break; + } + else if (string[i] == history_expansion_char) + { + if (!cc || member (cc, history_no_expand_chars)) + continue; + /* If the calling application has set + history_inhibit_expansion_function to a function that checks + for special cases that should not be history expanded, + call the function and skip the expansion if it returns a + non-zero value. */ + else if (history_inhibit_expansion_function && + (*history_inhibit_expansion_function) (string, i)) + continue; + 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] == '\'') + { + /* If this is bash, single quotes inhibit history expansion. */ + i++; + hist_string_extract_single_quoted (string, &i); + } + else if (history_quotes_inhibit_expansion && string[i] == '\\') + { + /* If this is bash, allow backslashes to quote single + quotes and the history expansion character. */ + if (cc == '\'' || cc == history_expansion_char) + i++; + } + } + + if (string[i] != history_expansion_char) + { + free (result); + *output = savestring (string); + return (0); + } + } + + /* Extract and perform the substitution. */ + for (passc = i = j = 0; i < l; i++) + { + int tchar = string[i]; + + if (passc) + { + passc = 0; + ADD_CHAR (tchar); + continue; + } + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int k, c; + + c = tchar; + memset (mb, 0, sizeof (mb)); + for (k = 0; k < MB_LEN_MAX; k++) + { + mb[k] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_get_char_len (mb, &ps) == -2) + c = string[++i]; + else + break; + } + if (strlen (mb) > 1) + { + ADD_STRING (mb); + break; + } + } +#endif /* HANDLE_MULTIBYTE */ + + if (tchar == history_expansion_char) + tchar = -3; + else if (tchar == history_comment_char) + tchar = -2; + + switch (tchar) + { + default: + ADD_CHAR (string[i]); + break; + + case '\\': + passc++; + ADD_CHAR (tchar); + break; + + case '\'': + { + /* If history_quotes_inhibit_expansion is set, single quotes + inhibit history expansion. */ + if (history_quotes_inhibit_expansion) + { + int quote, slen; + + quote = i++; + hist_string_extract_single_quoted (string, &i); + + slen = i - quote + 2; + temp = (char *)xmalloc (slen); + strncpy (temp, string + quote, slen); + temp[slen - 1] = '\0'; + ADD_STRING (temp); + free (temp); + } + else + ADD_CHAR (string[i]); + break; + } + + case -2: /* history_comment_char */ + if (i == 0 || member (string[i - 1], history_word_delimiters)) + { + temp = (char *)xmalloc (l - i + 1); + strcpy (temp, string + i); + ADD_STRING (temp); + free (temp); + i = l; + } + else + ADD_CHAR (string[i]); + break; + + case -3: /* history_expansion_char */ + cc = string[i + 1]; + + /* If the history_expansion_char is followed by one of the + characters in history_no_expand_chars, then it is not a + candidate for expansion of any kind. */ + if (member (cc, history_no_expand_chars)) + { + ADD_CHAR (string[i]); + break; + } + +#if defined (NO_BANG_HASH_MODIFIERS) + /* There is something that is listed as a `word specifier' in csh + documentation which means `the expanded text to this point'. + That is not a word specifier, it is an event specifier. If we + don't want to allow modifiers with `!#', just stick the current + output line in again. */ + if (cc == '#') + { + if (result) + { + temp = (char *)xmalloc (1 + strlen (result)); + strcpy (temp, result); + ADD_STRING (temp); + free (temp); + } + i++; + break; + } +#endif + + r = history_expand_internal (string, i, &eindex, &temp, result); + if (r < 0) + { + *output = temp; + free (result); + if (string != hstring) + free (string); + return -1; + } + else + { + if (temp) + { + modified++; + if (*temp) + ADD_STRING (temp); + free (temp); + } + only_printing = r == 1; + i = eindex; + } + break; + } + } + + *output = result; + if (string != hstring) + free (string); + + if (only_printing) + { + add_history (result); + return (2); + } + + return (modified != 0); +} + +/* Return a consed string which is the word specified in SPEC, and found + in FROM. NULL is returned if there is no spec. The address of + ERROR_POINTER is returned if the word specified cannot be found. + CALLER_INDEX is the offset in SPEC to start looking; it is updated + to point to just after the last character parsed. */ +static char * +get_history_word_specifier (spec, from, caller_index) + char *spec, *from; + int *caller_index; +{ + register int i = *caller_index; + int first, last; + int expecting_word_spec = 0; + char *result; + + /* The range of words to return doesn't exist yet. */ + first = last = 0; + result = (char *)NULL; + + /* If we found a colon, then this *must* be a word specification. If + it isn't, then it is an error. */ + if (spec[i] == ':') + { + i++; + expecting_word_spec++; + } + + /* Handle special cases first. */ + + /* `%' is the word last searched for. */ + if (spec[i] == '%') + { + *caller_index = i + 1; + return (search_match ? savestring (search_match) : savestring ("")); + } + + /* `*' matches all of the arguments, but not the command. */ + if (spec[i] == '*') + { + *caller_index = i + 1; + result = history_arg_extract (1, '$', from); + return (result ? result : savestring ("")); + } + + /* `$' is last arg. */ + if (spec[i] == '$') + { + *caller_index = i + 1; + return (history_arg_extract ('$', '$', from)); + } + + /* Try to get FIRST and LAST figured out. */ + + if (spec[i] == '-') + first = 0; + else if (spec[i] == '^') + first = 1; + else if (_rl_digit_p (spec[i]) && expecting_word_spec) + { + for (first = 0; _rl_digit_p (spec[i]); i++) + first = (first * 10) + _rl_digit_value (spec[i]); + } + else + return ((char *)NULL); /* no valid `first' for word specifier */ + + if (spec[i] == '^' || spec[i] == '*') + { + last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */ + i++; + } + else if (spec[i] != '-') + last = first; + else + { + i++; + + if (_rl_digit_p (spec[i])) + { + for (last = 0; _rl_digit_p (spec[i]); i++) + last = (last * 10) + _rl_digit_value (spec[i]); + } + else if (spec[i] == '$') + { + i++; + last = '$'; + } +#if 0 + else if (!spec[i] || spec[i] == ':') + /* check against `:' because there could be a modifier separator */ +#else + else + /* csh seems to allow anything to terminate the word spec here, + leaving it as an abbreviation. */ +#endif + last = -1; /* x- abbreviates x-$ omitting word `$' */ + } + + *caller_index = i; + + if (last >= first || last == '$' || last < 0) + result = history_arg_extract (first, last, from); + + return (result ? result : (char *)&error_pointer); +} + +/* Extract the args specified, starting at FIRST, and ending at LAST. + The args are taken from STRING. If either FIRST or LAST is < 0, + then make that arg count from the right (subtract from the number of + tokens, so that FIRST = -1 means the next to last token on the line). + If LAST is `$' the last arg from STRING is used. */ +char * +history_arg_extract (first, last, string) + int first, last; + const char *string; +{ + register int i, len; + char *result; + int size, offset; + char **list; + + /* XXX - think about making history_tokenize return a struct array, + each struct in array being a string and a length to avoid the + calls to strlen below. */ + if ((list = history_tokenize (string)) == NULL) + return ((char *)NULL); + + for (len = 0; list[len]; len++) + ; + + if (last < 0) + last = len + last - 1; + + if (first < 0) + first = len + first - 1; + + if (last == '$') + last = len - 1; + + if (first == '$') + first = len - 1; + + last++; + + if (first >= len || last > len || first < 0 || last < 0 || first > last) + result = ((char *)NULL); + else + { + for (size = 0, i = first; i < last; i++) + size += strlen (list[i]) + 1; + result = (char *)xmalloc (size + 1); + result[0] = '\0'; + + for (i = first, offset = 0; i < last; i++) + { + strcpy (result + offset, list[i]); + offset += strlen (list[i]); + if (i + 1 < last) + { + result[offset++] = ' '; + result[offset] = 0; + } + } + } + + for (i = 0; i < len; i++) + free (list[i]); + free (list); + + return (result); +} + +#define slashify_in_quotes "\\`\"$" + +/* 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 + WIND. The position in the returned array of strings is returned in + *INDP. */ +static char ** +history_tokenize_internal (string, wind, indp) + const char *string; + int 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. */ + if (indp && wind != -1) + *indp = -1; + + /* Get a token, and stuff it into RESULT. The tokens are split + 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++) + ; + if (string[i] == 0 || string[i] == history_comment_char) + return (result); + + start = i; + + if (member (string[i], "()\n")) + { + i++; + goto got_token; + } + + if (member (string[i], "<>;&|$")) + { + int peek = string[i + 1]; + + 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 (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]; + } + + 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; + } + + return (result); +} + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +char ** +history_tokenize (string) + const char *string; +{ + return (history_tokenize_internal (string, -1, (int *)NULL)); +} + +/* Find and return the word which contains the character at index IND + in the history line LINE. Used to save the word matched by the + last history !?string? search. */ +static char * +history_find_word (line, ind) + char *line; + int ind; +{ + char **words, *s; + int i, wind; + + words = history_tokenize_internal (line, ind, &wind); + if (wind == -1 || words == 0) + return ((char *)NULL); + s = words[wind]; + for (i = 0; i < wind; i++) + free (words[i]); + for (i = wind + 1; words[i]; i++) + free (words[i]); + free (words); + return s; +} diff --git a/readline-4.3.orig/histfile.c b/readline-4.3.orig/histfile.c new file mode 100644 index 0000000..60a9125 --- /dev/null +++ b/readline-4.3.orig/histfile.c @@ -0,0 +1,479 @@ +/* histfile.c - functions to manipulate the history file. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include +#ifndef _MINIX +# include +#endif +#include "posixstat.h" +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (__EMX__) || defined (__CYGWIN__) +# undef HAVE_MMAP +#endif + +#ifdef HAVE_MMAP +# include + +# ifdef MAP_FILE +# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE) +# define MAP_WFLAGS (MAP_FILE|MAP_SHARED) +# else +# define MAP_RFLAGS MAP_PRIVATE +# define MAP_WFLAGS MAP_SHARED +# endif + +# ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +# endif + +#endif /* HAVE_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 + is no \n -> \r\n conversion performed. On other systems, we don't want to + mess around with O_BINARY at all, so we ensure that it's defined to 0. */ +#if defined (__EMX__) || defined (__CYGWIN__) +# ifndef O_BINARY +# define O_BINARY 0 +# endif +#else /* !__EMX__ && !__CYGWIN__ */ +# undef O_BINARY +# define O_BINARY 0 +#endif /* !__EMX__ && !__CYGWIN__ */ + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "history.h" +#include "histlib.h" + +#include "rlshell.h" +#include "xmalloc.h" + +/* 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 (). */ +static char * +history_filename (filename) + const char *filename; +{ + char *return_val; + const char *home; + int home_len; + + return_val = filename ? savestring (filename) : (char *)NULL; + + if (return_val) + return (return_val); + + home = sh_get_env_value ("HOME"); + + if (home == 0) + { + home = "."; + home_len = 1; + } + else + home_len = strlen (home); + + return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ + strcpy (return_val, home); + return_val[home_len] = '/'; +#if defined (__MSDOS__) + strcpy (return_val + home_len + 1, "_history"); +#else + strcpy (return_val + home_len + 1, ".history"); +#endif + + return (return_val); +} + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +int +read_history (filename) + const char *filename; +{ + return (read_history_range (filename, 0, -1)); +} + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +int +read_history_range (filename, from, to) + const char *filename; + int from, to; +{ + register char *line_start, *line_end; + char *input, *buffer, *bufend; + int file, current_line, chars_read; + struct stat finfo; + size_t file_size; + + buffer = (char *)NULL; + input = history_filename (filename); + file = open (input, O_RDONLY|O_BINARY, 0666); + + if ((file < 0) || (fstat (file, &finfo) == -1)) + goto error_and_exit; + + file_size = (size_t)finfo.st_size; + + /* 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 + goto error_and_exit; + } + +#ifdef HAVE_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; + chars_read = file_size; +#else + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + goto error_and_exit; + + chars_read = read (file, buffer, file_size); +#endif + if (chars_read < 0) + { + error_and_exit: + chars_read = errno; + if (file >= 0) + close (file); + + FREE (input); +#ifndef HAVE_MMAP + FREE (buffer); +#endif + + return (chars_read); + } + + close (file); + + /* Set TO to larger than end of file if negative. */ + if (to < 0) + to = chars_read; + + /* Start at beginning of file, work to end. */ + bufend = buffer + chars_read; + current_line = 0; + + /* Skip lines until we are at FROM. */ + 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; + } + + /* If there are lines left to gobble, then gobble them now. */ + for (line_end = line_start; line_end < bufend; line_end++) + if (*line_end == '\n') + { + *line_end = '\0'; + + if (*line_start) + add_history (line_start); + + current_line++; + + if (current_line >= to) + break; + + line_start = line_end + 1; + } + + FREE (input); +#ifndef HAVE_MMAP + FREE (buffer); +#else + munmap (buffer, file_size); +#endif + + return (0); +} + +/* Truncate the history file FNAME, leaving only LINES trailing lines. + If FNAME is NULL, then use ~/.history. Returns 0 on success, errno + on failure. */ +int +history_truncate_file (fname, lines) + const char *fname; + int lines; +{ + char *buffer, *filename, *bp; + int file, chars_read, rv; + struct stat finfo; + size_t file_size; + + buffer = (char *)NULL; + filename = history_filename (fname); + file = open (filename, O_RDONLY|O_BINARY, 0666); + rv = 0; + + /* Don't try to truncate non-regular files. */ + if (file == -1 || fstat (file, &finfo) == -1) + { + rv = errno; + if (file != -1) + close (file); + goto truncate_exit; + } + + if (S_ISREG (finfo.st_mode) == 0) + { + close (file); +#ifdef EFTYPE + rv = EFTYPE; +#else + rv = EINVAL; +#endif + goto truncate_exit; + } + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + close (file); +#if defined (EFBIG) + rv = errno = EFBIG; +#elif defined (EOVERFLOW) + rv = errno = EOVERFLOW; +#else + rv = errno = EINVAL; +#endif + goto truncate_exit; + } + + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + { + close (file); + goto truncate_exit; + } + + chars_read = read (file, buffer, file_size); + close (file); + + if (chars_read <= 0) + { + rv = (chars_read < 0) ? errno : 0; + goto truncate_exit; + } + + /* Count backwards from the end of buffer until we have passed + LINES lines. */ + for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--) + { + if (*bp == '\n') + lines--; + } + + /* If this is the first line, then the file contains exactly the + number of lines we want to truncate to, so we don't need to do + anything. It's the first line if we don't find a newline between + 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; + } + + /* Write only if there are more lines in the file than we want to + truncate to. */ + if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) + { + write (file, bp, chars_read - (bp - buffer)); + +#if defined (__BEOS__) + /* BeOS ignores O_TRUNC. */ + ftruncate (file, chars_read - (bp - buffer)); +#endif + + close (file); + } + + truncate_exit: + + FREE (buffer); + + free (filename); + return rv; +} + +/* Workhorse function for writing history. Writes NELEMENT entries + from the history list to FILENAME. OVERWRITE is non-zero if you + wish to replace FILENAME with the entries. */ +static int +history_do_write (filename, nelements, overwrite) + const char *filename; + int nelements, overwrite; +{ + register int i; + char *output; + int file, mode, rv; + 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; +#endif + output = history_filename (filename); + rv = 0; + + if ((file = open (output, mode, 0600)) == -1) + { + FREE (output); + return (errno); + } + +#ifdef HAVE_MMAP + cursize = overwrite ? 0 : lseek (file, 0, SEEK_END); +#endif + + if (nelements > history_length) + nelements = history_length; + + /* Build a buffer of all the lines to write, and write them in one syscall. + Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */ + { + HIST_ENTRY **the_history; /* local */ + register int j; + int buffer_size; + char *buffer; + + 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); + + /* Allocate the buffer, and fill it. */ +#ifdef HAVE_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); + if ((void *)buffer == MAP_FAILED) + { +mmap_error: + rv = errno; + FREE (output); + close (file); + return rv; + } +#else + buffer = (char *)malloc (buffer_size); + if (buffer == 0) + { + rv = errno; + FREE (output); + close (file); + return rv; + } +#endif + + for (j = 0, i = history_length - nelements; i < history_length; i++) + { + strcpy (buffer + j, the_history[i]->line); + j += strlen (the_history[i]->line); + buffer[j++] = '\n'; + } + +#ifdef HAVE_MMAP + if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0) + rv = errno; +#else + if (write (file, buffer, buffer_size) < 0) + rv = errno; + free (buffer); +#endif + } + + close (file); + + FREE (output); + + return (rv); +} + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +int +append_history (nelements, filename) + int nelements; + const char *filename; +{ + return (history_do_write (filename, nelements, HISTORY_APPEND)); +} + +/* Overwrite FILENAME with the current history. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history ().*/ +int +write_history (filename) + const char *filename; +{ + return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); +} diff --git a/readline-4.3.orig/histlib.h b/readline-4.3.orig/histlib.h new file mode 100644 index 0000000..c39af71 --- /dev/null +++ b/readline-4.3.orig/histlib.h @@ -0,0 +1,82 @@ +/* histlib.h -- internal definitions for the history library. */ +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_HISTLIB_H_) +#define _HISTLIB_H_ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#ifndef savestring +#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef _rl_digit_p +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') +#endif + +#ifndef _rl_digit_value +#define _rl_digit_value(c) ((c) - '0') +#endif + +#ifndef member +# ifndef strchr +extern char *strchr (); +# endif +#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef FREE +# define FREE(x) if (x) free (x) +#endif + +/* Possible history errors passed to hist_error. */ +#define EVENT_NOT_FOUND 0 +#define BAD_WORD_SPEC 1 +#define SUBST_FAILED 2 +#define BAD_MODIFIER 3 +#define NO_PREV_SUBST 4 + +/* Possible definitions for history starting point specification. */ +#define ANCHORED_SEARCH 1 +#define NON_ANCHORED_SEARCH 0 + +/* Possible definitions for what style of writing the history file we want. */ +#define HISTORY_APPEND 0 +#define HISTORY_OVERWRITE 1 + +/* Some variable definitions shared across history source files. */ +extern int history_offset; + +#endif /* !_HISTLIB_H_ */ diff --git a/readline-4.3.orig/history.c b/readline-4.3.orig/history.c new file mode 100644 index 0000000..4242f33 --- /dev/null +++ b/readline-4.3.orig/history.c @@ -0,0 +1,381 @@ +/* History.c -- standalone history library */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "history.h" +#include "histlib.h" + +#include "xmalloc.h" + +/* The number of slots to increase the_history by. */ +#define DEFAULT_HISTORY_GROW_SIZE 50 + +/* **************************************************************** */ +/* */ +/* History Functions */ +/* */ +/* **************************************************************** */ + +/* An array of HIST_ENTRY. This is where we store the history. */ +static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL; + +/* Non-zero means that we have enforced a limit on the amount of + history that we save. */ +static int history_stifled; + +/* The current number of slots allocated to the input_history. */ +static int history_size; + +/* If HISTORY_STIFLED is non-zero, then this is the maximum number of + entries to remember. */ +int history_max_entries; +int max_input_history; /* backwards compatibility */ + +/* The current location of the interactive history pointer. Just makes + life easier for outside callers. */ +int history_offset; + +/* The number of strings currently stored in the history list. */ +int history_length; + +/* The logical `base' of the history array. It defaults to 1. */ +int history_base = 1; + +/* Return the current HISTORY_STATE of the history. */ +HISTORY_STATE * +history_get_history_state () +{ + HISTORY_STATE *state; + + state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE)); + state->entries = the_history; + state->offset = history_offset; + state->length = history_length; + state->size = history_size; + state->flags = 0; + if (history_stifled) + state->flags |= HS_STIFLED; + + return (state); +} + +/* Set the state of the current history array to STATE. */ +void +history_set_history_state (state) + HISTORY_STATE *state; +{ + the_history = state->entries; + history_offset = state->offset; + history_length = state->length; + history_size = state->size; + if (state->flags & HS_STIFLED) + history_stifled = 1; +} + +/* Begin a session in which the history functions might be used. This + initializes interactive variables. */ +void +using_history () +{ + history_offset = history_length; +} + +/* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines. */ +int +history_total_bytes () +{ + register int i, result; + + for (i = result = 0; the_history && the_history[i]; i++) + result += strlen (the_history[i]->line); + + return (result); +} + +/* Returns the magic number which says what history element we are + looking at now. In this implementation, it returns history_offset. */ +int +where_history () +{ + return (history_offset); +} + +/* Make the current history item be the one at POS, an absolute index. + Returns zero if POS is out of range, else non-zero. */ +int +history_set_pos (pos) + int pos; +{ + if (pos > history_length || pos < 0 || !the_history) + return (0); + history_offset = pos; + return (1); +} + +/* Return the current history array. The caller has to be carefull, since this + is the actual array of data, and could be bashed or made corrupt easily. + The array is terminated with a NULL pointer. */ +HIST_ENTRY ** +history_list () +{ + return (the_history); +} + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +HIST_ENTRY * +current_history () +{ + return ((history_offset == history_length) || the_history == 0) + ? (HIST_ENTRY *)NULL + : the_history[history_offset]; +} + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry then return + a NULL pointer. */ +HIST_ENTRY * +previous_history () +{ + return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; +} + +/* Move history_offset forward to the next history entry, and return + a pointer to that entry. If there is no next entry then return a + NULL pointer. */ +HIST_ENTRY * +next_history () +{ + return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; +} + +/* Return the history entry which is logically at OFFSET in the history array. + OFFSET is relative to history_base. */ +HIST_ENTRY * +history_get (offset) + int offset; +{ + int local_index; + + local_index = offset - history_base; + return (local_index >= history_length || local_index < 0 || !the_history) + ? (HIST_ENTRY *)NULL + : the_history[local_index]; +} + +/* Place STRING at the end of the history list. The data field + is set to NULL. */ +void +add_history (string) + const char *string; +{ + HIST_ENTRY *temp; + + if (history_stifled && (history_length == history_max_entries)) + { + register int i; + + /* If the history is stifled, and history_length is zero, + and it equals history_max_entries, we don't save items. */ + if (history_length == 0) + return; + + /* If there is something in the slot, then remove it. */ + if (the_history[0]) + { + free (the_history[0]->line); + free (the_history[0]); + } + + /* Copy the rest of the entries, moving down one slot. */ + for (i = 0; i < history_length; i++) + the_history[i] = the_history[i + 1]; + + history_base++; + } + else + { + if (history_size == 0) + { + history_size = DEFAULT_HISTORY_GROW_SIZE; + the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); + history_length = 1; + } + else + { + if (history_length == (history_size - 1)) + { + history_size += DEFAULT_HISTORY_GROW_SIZE; + the_history = (HIST_ENTRY **) + xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); + } + history_length++; + } + } + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + temp->line = savestring (string); + temp->data = (char *)NULL; + + the_history[history_length] = (HIST_ENTRY *)NULL; + the_history[history_length - 1] = temp; +} + +/* 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. */ +HIST_ENTRY * +replace_history_entry (which, line, data) + int which; + const char *line; + histdata_t data; +{ + HIST_ENTRY *temp, *old_value; + + if (which >= history_length) + return ((HIST_ENTRY *)NULL); + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + old_value = the_history[which]; + + temp->line = savestring (line); + temp->data = data; + the_history[which] = temp; + + return (old_value); +} + +/* Remove history element WHICH from the history. The removed + element is returned to you so you can free the line, data, + and containing structure. */ +HIST_ENTRY * +remove_history (which) + int 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]; + + for (i = which; i < history_length; i++) + the_history[i] = the_history[i + 1]; + + history_length--; + } + + return (return_value); +} + +/* Stifle the history list, remembering only MAX number of lines. */ +void +stifle_history (max) + int max; +{ + register int i, j; + + if (max < 0) + max = 0; + + if (history_length > 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]); + } + + history_base = i; + for (j = 0, i = history_length - max; j < max; i++, j++) + the_history[j] = the_history[i]; + the_history[j] = (HIST_ENTRY *)NULL; + history_length = j; + } + + history_stifled = 1; + max_input_history = history_max_entries = max; +} + +/* Stop stifling the history. This returns the previous maximum + number of history entries. The value is positive if the history + was stifled, negative if it wasn't. */ +int +unstifle_history () +{ + if (history_stifled) + { + history_stifled = 0; + return (history_max_entries); + } + else + return (-history_max_entries); +} + +int +history_is_stifled () +{ + return (history_stifled); +} + +void +clear_history () +{ + register int i; + + /* This loses because we cannot free the data. */ + for (i = 0; i < history_length; i++) + { + free (the_history[i]->line); + free (the_history[i]); + the_history[i] = (HIST_ENTRY *)NULL; + } + + history_offset = history_length = 0; +} diff --git a/readline-4.3.orig/history.h b/readline-4.3.orig/history.h new file mode 100644 index 0000000..58b5de4 --- /dev/null +++ b/readline-4.3.orig/history.h @@ -0,0 +1,246 @@ +/* History.h -- the names of functions that you can call in history. */ +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _HISTORY_H_ +#define _HISTORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined READLINE_LIBRARY +# include "rlstdc.h" +# include "rltypedefs.h" +#else +# include +# include +#endif + +#ifdef __STDC__ +typedef void *histdata_t; +#else +typedef char *histdata_t; +#endif + +/* The structure used to store a history entry. */ +typedef struct _hist_entry { + char *line; + histdata_t data; +} HIST_ENTRY; + +/* 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. */ + 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; + +/* Flag values for the `flags' member of HISTORY_STATE. */ +#define HS_STIFLED 0x01 + +/* Initialization and state management. */ + +/* Begin a session in which the history functions might be used. This + just initializes the interactive variables. */ +extern void using_history PARAMS((void)); + +/* Return the current HISTORY_STATE of the history. */ +extern HISTORY_STATE *history_get_history_state PARAMS((void)); + +/* Set the state of the current history array to STATE. */ +extern void history_set_history_state PARAMS((HISTORY_STATE *)); + +/* Manage the history list. */ + +/* Place STRING at the end of the history list. + The associated data field (if any) is set to NULL. */ +extern void add_history 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)); + +/* 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. */ +extern HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t)); + +/* Clear the history list and start over. */ +extern void clear_history PARAMS((void)); + +/* Stifle the history list, remembering only MAX number of entries. */ +extern void stifle_history PARAMS((int)); + +/* Stop stifling the history. This returns the previous amount the + history was stifled by. The value is positive if the history was + stifled, negative if it wasn't. */ +extern int unstifle_history PARAMS((void)); + +/* Return 1 if the history is stifled, 0 if it is not. */ +extern int history_is_stifled PARAMS((void)); + +/* Information about the history list. */ + +/* Return a NULL terminated array of HIST_ENTRY which is the current input + history. Element 0 of this list is the beginning of time. If there + is no history, return NULL. */ +extern HIST_ENTRY **history_list PARAMS((void)); + +/* Returns the number which says what history element we are now + looking at. */ +extern int where_history PARAMS((void)); + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +extern HIST_ENTRY *current_history PARAMS((void)); + +/* Return the history entry which is logically at OFFSET in the history + array. OFFSET is relative to history_base. */ +extern HIST_ENTRY *history_get PARAMS((int)); + +/* 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)); + +/* Moving around the history list. */ + +/* Set the position in the history list to POS. */ +extern int history_set_pos PARAMS((int)); + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry, return + a NULL pointer. */ +extern HIST_ENTRY *previous_history PARAMS((void)); + +/* Move history_offset forward to the next item in the input_history, + and return the a pointer to that entry. If there is no next entry, + return a NULL pointer. */ +extern HIST_ENTRY *next_history PARAMS((void)); + +/* Searching the history list. */ + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, + else through subsequent. If the string is found, then + current_history () is the history entry, and the value of this function + is the offset in the line of that history entry that the string was + found in. Otherwise, nothing is changed, and a -1 is returned. */ +extern int history_search PARAMS((const char *, int)); + +/* Search the history for STRING, starting at history_offset. + The search is anchored: matching lines must begin with string. + DIRECTION is as in history_search(). */ +extern int history_search_prefix PARAMS((const char *, int)); + +/* Search for STRING in the history list, starting at POS, an + absolute index into the list. DIR, if negative, says to search + backwards from POS, else forwards. + Returns the absolute index of the history element where STRING + was found, or -1 otherwise. */ +extern int history_search_pos PARAMS((const char *, int, int)); + +/* Managing the history file. */ + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +extern int read_history PARAMS((const char *)); + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +extern int read_history_range PARAMS((const char *, int, int)); + +/* Write the current history to FILENAME. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history (). */ +extern int write_history PARAMS((const char *)); + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +extern int append_history PARAMS((int, const char *)); + +/* Truncate the history file, leaving only the last NLINES lines. */ +extern int history_truncate_file PARAMS((const char *, int)); + +/* History expansion. */ + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + -1) If there was an error in expansion. + 2) If the returned line should just be printed. + + If an error ocurred in expansion, then OUTPUT contains a descriptive + error message. */ +extern int history_expand PARAMS((char *, char **)); + +/* Extract a string segment consisting of the FIRST through LAST + arguments present in STRING. Arguments are broken up as in + the shell. */ +extern char *history_arg_extract PARAMS((int, int, const char *)); + +/* Return the text of the history event beginning at the current + offset into STRING. Pass STRING with *INDEX equal to the + history_expansion_char that begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. */ +extern char *get_history_event PARAMS((const char *, int *, int)); + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +extern char **history_tokenize PARAMS((const char *)); + +/* Exported history variables. */ +extern int history_base; +extern int history_length; +extern int history_max_entries; +extern char history_expansion_char; +extern char history_subst_char; +extern char *history_word_delimiters; +extern char history_comment_char; +extern char *history_no_expand_chars; +extern char *history_search_delimiter_chars; +extern int history_quotes_inhibit_expansion; + +/* Backwards compatibility */ +extern int max_input_history; + +/* If set, this function is called to decide whether or not a particular + history expansion should be treated as a special case for the calling + application and not expanded. */ +extern rl_linebuf_func_t *history_inhibit_expansion_function; + +#ifdef __cplusplus +} +#endif + +#endif /* !_HISTORY_H_ */ diff --git a/readline-4.3.orig/histsearch.c b/readline-4.3.orig/histsearch.c new file mode 100644 index 0000000..d94fd6c --- /dev/null +++ b/readline-4.3.orig/histsearch.c @@ -0,0 +1,195 @@ +/* histsearch.c -- searching the history list. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "history.h" +#include "histlib.h" + +/* The list of alternate characters that can delimit a history search + string. */ +char *history_search_delimiter_chars = (char *)NULL; + +static int history_search_internal PARAMS((const char *, int, int)); + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, else + through subsequent. If ANCHORED is non-zero, the string must + appear at the beginning of a history line, otherwise, the string + may appear anywhere in the line. If the string is found, then + current_history () is the history entry, and the value of this + function is the offset in the line of that history entry that the + string was found in. Otherwise, nothing is changed, and a -1 is + returned. */ + +static int +history_search_internal (string, direction, anchored) + const char *string; + int direction, anchored; +{ + register int i, reverse; + register char *line; + register int line_index; + int string_len; + HIST_ENTRY **the_history; /* local */ + + i = history_offset; + reverse = (direction < 0); + + /* Take care of trivial cases first. */ + if (string == 0 || *string == '\0') + return (-1); + + if (!history_length || ((i == history_length) && !reverse)) + return (-1); + + if (reverse && (i == history_length)) + i--; + +#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) + + the_history = history_list (); + string_len = strlen (string); + while (1) + { + /* Search each line in the history list for STRING. */ + + /* At limit for direction? */ + if ((reverse && i < 0) || (!reverse && i == history_length)) + return (-1); + + line = the_history[i]->line; + line_index = strlen (line); + + /* If STRING is longer than line, no match. */ + if (string_len > line_index) + { + NEXT_LINE (); + continue; + } + + /* Handle anchored searches first. */ + if (anchored == ANCHORED_SEARCH) + { + if (STREQN (string, line, string_len)) + { + history_offset = i; + return (0); + } + + NEXT_LINE (); + continue; + } + + /* Do substring search. */ + if (reverse) + { + line_index -= string_len; + + while (line_index >= 0) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index--; + } + } + else + { + register int limit; + + limit = line_index - string_len + 1; + line_index = 0; + + while (line_index < limit) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index++; + } + } + NEXT_LINE (); + } +} + +/* Do a non-anchored search for STRING through the history in DIRECTION. */ +int +history_search (string, direction) + const char *string; + int direction; +{ + return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); +} + +/* Do an anchored search for string through the history in DIRECTION. */ +int +history_search_prefix (string, direction) + const char *string; + int direction; +{ + return (history_search_internal (string, direction, ANCHORED_SEARCH)); +} + +/* Search for STRING in the history list. DIR is < 0 for searching + backwards. POS is an absolute index into the history list at + which point to begin searching. */ +int +history_search_pos (string, dir, pos) + const char *string; + int dir, pos; +{ + int ret, old; + + old = where_history (); + history_set_pos (pos); + if (history_search (string, dir) == -1) + { + history_set_pos (old); + return (-1); + } + ret = where_history (); + history_set_pos (old); + return ret; +} diff --git a/readline-4.3.orig/input.c b/readline-4.3.orig/input.c new file mode 100644 index 0000000..841f05d --- /dev/null +++ b/readline-4.3.orig/input.c @@ -0,0 +1,540 @@ +/* input.c -- character input functions for readline. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#if defined (FIONREAD_IN_SYS_IOCTL) +# include +#endif + +#include +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* What kind of non-blocking I/O do we have? */ +#if !defined (O_NDELAY) && defined (O_NONBLOCK) +# define O_NDELAY O_NONBLOCK /* Posix style */ +#endif + +/* Non-null means it is a pointer to a function to run while waiting for + character input. */ +rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; + +rl_getc_func_t *rl_getc_function = rl_getc; + +static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */ + +static int ibuffer_space PARAMS((void)); +static int rl_get_char PARAMS((int *)); +static int rl_gather_tyi PARAMS((void)); + +/* **************************************************************** */ +/* */ +/* Character Input Buffering */ +/* */ +/* **************************************************************** */ + +static int pop_index, push_index; +static unsigned char ibuffer[512]; +static int ibuffer_len = sizeof (ibuffer) - 1; + +#define any_typein (push_index != pop_index) + +int +_rl_any_typein () +{ + return any_typein; +} + +/* Return the amount of space available in the buffer for stuffing + characters. */ +static int +ibuffer_space () +{ + if (pop_index > push_index) + return (pop_index - push_index - 1); + else + return (ibuffer_len - (push_index - pop_index)); +} + +/* Get a key from the buffer of characters to be read. + Return the key in KEY. + Result is KEY if there was a key, or 0 if there wasn't. */ +static int +rl_get_char (key) + int *key; +{ + if (push_index == pop_index) + return (0); + + *key = ibuffer[pop_index++]; + + if (pop_index >= ibuffer_len) + pop_index = 0; + + return (1); +} + +/* Stuff KEY into the *front* of the input buffer. + Returns non-zero if successful, zero if there is + no space left in the buffer. */ +int +_rl_unget_char (key) + int key; +{ + if (ibuffer_space ()) + { + pop_index--; + if (pop_index < 0) + pop_index = ibuffer_len - 1; + ibuffer[pop_index] = key; + return (1); + } + return (0); +} + +/* 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). */ +static int +rl_gather_tyi () +{ + int tty; + register int tem, result; + int chars_avail; + char input; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = _keyboard_input_timeout; + result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); + if (result <= 0) + return 0; /* Nothing to read. */ +#endif + + result = -1; +#if defined (FIONREAD) + errno = 0; + result = ioctl (tty, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; +#endif + +#if defined (O_NDELAY) + if (result == -1) + { + tem = fcntl (tty, F_GETFL, 0); + + fcntl (tty, F_SETFL, (tem | O_NDELAY)); + chars_avail = read (tty, &input, 1); + + fcntl (tty, F_SETFL, tem); + if (chars_avail == -1 && errno == EAGAIN) + return 0; + } +#endif /* O_NDELAY */ + + /* If there's nothing available, don't waste time trying to read + something. */ + if (chars_avail <= 0) + return 0; + + tem = ibuffer_space (); + + if (chars_avail > tem) + chars_avail = tem; + + /* One cannot read all of the available input. I can only read a single + character at a time, or else programs which require input can be + thwarted. If the buffer is larger than one character, I lose. + Damn! */ + if (tem < ibuffer_len) + chars_avail = 0; + + if (result != -1) + { + while (chars_avail--) + rl_stuff_char ((*rl_getc_function) (rl_instream)); + } + else + { + if (chars_avail) + rl_stuff_char (input); + } + + return 1; +} + +int +rl_set_keyboard_input_timeout (u) + int u; +{ + int o; + + o = _keyboard_input_timeout; + if (u > 0) + _keyboard_input_timeout = u; + return (o); +} + +/* Is there input available to be read on the readline input file + descriptor? Only works if the system has select(2) or FIONREAD. + Uses the value of _keyboard_input_timeout as the timeout; if another + readline function wants to specify a timeout and not leave it up to + the user, it should use _rl_input_queued(timeout_value_in_microseconds) + instead. */ +int +_rl_input_available () +{ +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif +#if !defined (HAVE_SELECT) && defined(FIONREAD) + int chars_avail; +#endif + int tty; + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = _keyboard_input_timeout; + return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); +#else + +#if defined (FIONREAD) + if (ioctl (tty, FIONREAD, &chars_avail) == 0) + return (chars_avail); +#endif + +#endif + + return 0; +} + +int +_rl_input_queued (t) + int t; +{ + int old_timeout, r; + + old_timeout = rl_set_keyboard_input_timeout (t); + r = _rl_input_available (); + rl_set_keyboard_input_timeout (old_timeout); + return r; +} + +void +_rl_insert_typein (c) + int c; +{ + int key, t, i; + char *string; + + i = key = 0; + string = (char *)xmalloc (ibuffer_len + 1); + string[i++] = (char) c; + + while ((t = rl_get_char (&key)) && + _rl_keymap[key].type == ISFUNC && + _rl_keymap[key].function == rl_insert) + string[i++] = key; + + if (t) + _rl_unget_char (key); + + string[i] = '\0'; + rl_insert_text (string); + free (string); +} + +/* Add KEY to the buffer of characters to be read. Returns 1 if the + character was stuffed correctly; 0 otherwise. */ +int +rl_stuff_char (key) + int key; +{ + if (ibuffer_space () == 0) + return 0; + + if (key == EOF) + { + key = NEWLINE; + rl_pending_input = EOF; + RL_SETSTATE (RL_STATE_INPUTPENDING); + } + ibuffer[push_index++] = key; + if (push_index >= ibuffer_len) + push_index = 0; + + return 1; +} + +/* Make C be the next command to be executed. */ +int +rl_execute_next (c) + int c; +{ + rl_pending_input = c; + RL_SETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* Clear any pending input pushed with rl_execute_next() */ +int +rl_clear_pending_input () +{ + rl_pending_input = 0; + RL_UNSETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Input */ +/* */ +/* **************************************************************** */ + +/* Read a key, including pending input. */ +int +rl_read_key () +{ + int c; + + rl_key_sequence_length++; + + if (rl_pending_input) + { + c = rl_pending_input; + rl_clear_pending_input (); + } + else + { + /* If input is coming from a macro, then use that. */ + if (c = _rl_next_macro_key ()) + return (c); + + /* If the user has an event function, then call it periodically. */ + if (rl_event_hook) + { + while (rl_event_hook && rl_get_char (&c) == 0) + { + (*rl_event_hook) (); + if (rl_done) /* XXX - experimental */ + return ('\n'); + if (rl_gather_tyi () < 0) /* XXX - EIO */ + { + rl_done = 1; + return ('\n'); + } + } + } + else + { + if (rl_get_char (&c) == 0) + c = (*rl_getc_function) (rl_instream); + } + } + + return (c); +} + +int +rl_getc (stream) + FILE *stream; +{ + int result; + unsigned char c; + + while (1) + { + result = read (fileno (stream), &c, sizeof (unsigned char)); + + if (result == sizeof (unsigned char)) + return (c); + + /* If zero characters are returned, then the file that we are + reading from is empty! Return EOF in that case. */ + if (result == 0) + return (EOF); + +#if defined (__BEOS__) + if (errno == EINTR) + continue; +#endif + +#if defined (EWOULDBLOCK) +# define X_EWOULDBLOCK EWOULDBLOCK +#else +# define X_EWOULDBLOCK -99 +#endif + +#if defined (EAGAIN) +# define X_EAGAIN EAGAIN +#else +# define X_EAGAIN -99 +#endif + + if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) + { + if (sh_unset_nodelay_mode (fileno (stream)) < 0) + return (EOF); + continue; + } + +#undef X_EWOULDBLOCK +#undef X_EAGAIN + + /* If the error that we received was SIGINT, then try again, + this is simply an interrupted system call to read (). + Otherwise, some error ocurred, also signifying EOF. */ + if (errno != EINTR) + return (EOF); + } +} + +#if defined (HANDLE_MULTIBYTE) +/* read multibyte char */ +int +_rl_read_mbchar (mbchar, size) + char *mbchar; + int size; +{ + int mb_len = 0; + size_t mbchar_bytes_length; + wchar_t wc; + mbstate_t ps, ps_back; + + memset(&ps, 0, sizeof (mbstate_t)); + memset(&ps_back, 0, sizeof (mbstate_t)); + + while (mb_len < size) + { + RL_SETSTATE(RL_STATE_MOREINPUT); + mbchar[mb_len++] = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps); + if (mbchar_bytes_length == (size_t)(-1)) + break; /* invalid byte sequence for the current locale */ + else if (mbchar_bytes_length == (size_t)(-2)) + { + /* shorted bytes */ + ps = ps_back; + continue; + } + else if (mbchar_bytes_length > (size_t)(0)) + break; + } + + return mb_len; +} + +/* Read a multibyte-character string whose first character is FIRST into + the buffer MB of length MBLEN. Returns the last character read, which + may be FIRST. Used by the search functions, among others. Very similar + to _rl_read_mbchar. */ +int +_rl_read_mbstring (first, mb, mblen) + int first; + char *mb; + int mblen; +{ + int i, c; + mbstate_t ps; + + c = first; + memset (mb, 0, mblen); + for (i = 0; i < mblen; i++) + { + mb[i] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_get_char_len (mb, &ps) == -2) + { + /* Read more for multibyte character */ + RL_SETSTATE (RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE (RL_STATE_MOREINPUT); + } + else + break; + } + return c; +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/readline-4.3.orig/isearch.c b/readline-4.3.orig/isearch.c new file mode 100644 index 0000000..c1ea5b3 --- /dev/null +++ b/readline-4.3.orig/isearch.c @@ -0,0 +1,560 @@ +/* **************************************************************** */ +/* */ +/* I-Search and Searching */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2002 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Variables exported to other files in the readline library. */ +char *_rl_isearch_terminators = (char *)NULL; + +/* 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)); + +/* 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; + +/* Last search string and its length. */ +static char *last_isearch_string; +static int last_isearch_string_len; + +static char *default_isearch_terminators = "\033\012"; + +/* Search backwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_reverse_search_history (sign, key) + int sign, key; +{ + return (rl_search_history (-sign, key)); +} + +/* Search forwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_forward_search_history (sign, key) + int sign, key; +{ + return (rl_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, + WHERE is the history list number of the current line. If it is + -1, then this line is the starting one. */ +static void +rl_display_search (search_string, reverse_p, where) + char *search_string; + int reverse_p, where; +{ + char *message; + int msglen, searchlen; + + searchlen = (search_string && *search_string) ? strlen (search_string) : 0; + + message = (char *)xmalloc (searchlen + 33); + msglen = 0; + +#if defined (NOTDEF) + if (where != -1) + { + sprintf (message, "[%d]", where + history_base); + msglen = strlen (message); + } +#endif /* NOTDEF */ + + message[msglen++] = '('; + + if (reverse_p) + { + strcpy (message + msglen, "reverse-"); + msglen += 8; + } + + strcpy (message + msglen, "i-search)`"); + msglen += 10; + + if (search_string) + { + strcpy (message + msglen, search_string); + msglen += searchlen; + } + + strcpy (message + msglen, "': "); + + rl_message ("%s", message); + free (message); + (*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; +{ + /* 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; + + 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; + + /* 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; + + 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 + : default_isearch_terminators; + + /* Create an arrary of pointers to the lines that we want to search. */ + rl_maybe_replace_line (); + i = 0; + if (hlist) + for (i = 0; hlist[i]; i++); + + /* 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; + + if (_rl_saved_line_for_history) + 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; + } + + hlen++; + + /* The line where we start the search. */ + i = orig_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 */ + + /* Normalize DIRECTION into 1 or -1. */ + direction = (direction >= 0) ? 1 : -1; + + rl_display_search (search_string, reverse, -1); + + sline = rl_line_buffer; + sline_len = strlen (sline); + line_index = rl_point; + + found = failed = 0; + for (;;) + { + rl_command_func_t *f = (rl_command_func_t *)NULL; + + /* Read a key and decide how to proceed. */ + 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, 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; + } + + /* 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; + } + +#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 (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c)) + { + /* This sets rl_pending_input to c; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (c); + break; + } + } + else +#endif + if (c >= 0 && ENDSRCH_CHAR (c)) + { + /* This sets rl_pending_input to c; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (c); + break; + } + + switch (c) + { + 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 (); + break; + + /* switch directions */ + case -2: + direction = -direction; + reverse = direction < 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; + + 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) + { + rl_ding (); + 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; + + case -6: /* C-Y */ + /* skip over portion of line we already matched */ + wstart = rl_point + search_string_index; + if (wstart >= rl_end) + { + rl_ding (); + 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; + } + + for (found = failed = 0;;) + { + int limit = sline_len - search_string_index + 1; + + /* 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; + + /* 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 (failed) + break; + + /* Now set up the line for searching... */ + line_index = reverse ? sline_len - search_string_index : 0; + } + + if (failed) + { + /* We cannot find the search string. Ding the bell. */ + rl_ding (); + i = last_found_line; + continue; /* XXX - was 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 (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); + } + } + + /* 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. */ + + /* First put back the original state. */ + strcpy (rl_line_buffer, lines[orig_line]); + + rl_restore_prompt (); + + /* Save the search string for possible later use. */ + FREE (last_isearch_string); + last_isearch_string = search_string; + last_isearch_string_len = search_string_index; + + 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 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) + { + if (last_found_line == orig_line) + line_index = orig_point; + else + line_index = strlen (rl_line_buffer); + rl_mark = orig_mark; + } + + 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 (); + + FREE (allocated_line); + free (lines); + + RL_UNSETSTATE(RL_STATE_ISEARCH); + + return 0; +} diff --git a/readline-4.3.orig/keymaps.c b/readline-4.3.orig/keymaps.c new file mode 100644 index 0000000..12506d3 --- /dev/null +++ b/readline-4.3.orig/keymaps.c @@ -0,0 +1,150 @@ +/* keymaps.c -- Functions and keymaps for the GNU Readline library. */ + +/* Copyright (C) 1988,1989 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include /* for FILE * definition for readline.h */ + +#include "readline.h" +#include "rlconf.h" + +#include "emacs_keymap.c" + +#if defined (VI_MODE) +#include "vi_keymap.c" +#endif + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Functions for manipulating Keymaps. */ +/* */ +/* **************************************************************** */ + + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +Keymap +rl_make_bare_keymap () +{ + register int i; + Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY)); + + for (i = 0; i < KEYMAP_SIZE; i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = (rl_command_func_t *)NULL; + } + + for (i = 'A'; i < ('Z' + 1); i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = rl_do_lowercase_version; + } + + return (keymap); +} + +/* Return a new keymap which is a copy of MAP. */ +Keymap +rl_copy_keymap (map) + Keymap map; +{ + register int i; + Keymap temp = rl_make_bare_keymap (); + + for (i = 0; i < KEYMAP_SIZE; i++) + { + temp[i].type = map[i].type; + temp[i].function = map[i].function; + } + return (temp); +} + +/* Return a new keymap with the printing characters bound to rl_insert, + the uppercase Meta characters bound to run their lowercase equivalents, + and the Meta digits bound to produce numeric arguments. */ +Keymap +rl_make_keymap () +{ + register int i; + Keymap newmap; + + newmap = rl_make_bare_keymap (); + + /* All ASCII printing characters are self-inserting. */ + for (i = ' '; i < 127; i++) + newmap[i].function = rl_insert; + + newmap[TAB].function = rl_insert; + newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */ + 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++) + newmap[i].function = rl_insert; +#endif /* KEYMAP_SIZE > 128 */ + + return (newmap); +} + +/* Free the storage associated with MAP. */ +void +rl_discard_keymap (map) + Keymap map; +{ + int i; + + if (!map) + return; + + for (i = 0; i < KEYMAP_SIZE; i++) + { + switch (map[i].type) + { + case ISFUNC: + break; + + case ISKMAP: + rl_discard_keymap ((Keymap)map[i].function); + break; + + case ISMACR: + free ((char *)map[i].function); + break; + } + } +} diff --git a/readline-4.3.orig/keymaps.h b/readline-4.3.orig/keymaps.h new file mode 100644 index 0000000..66fa2a5 --- /dev/null +++ b/readline-4.3.orig/keymaps.h @@ -0,0 +1,103 @@ +/* keymaps.h -- Manipulation of readline keymaps. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _KEYMAPS_H_ +#define _KEYMAPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "chardefs.h" +# include "rltypedefs.h" +#else +# include +# include +# include +#endif + +/* A keymap contains one entry for each key in the ASCII set. + Each entry consists of a type and a pointer. + FUNCTION is the address of a function to run, or the + address of a keymap to indirect through. + TYPE says which kind of thing FUNCTION is. */ +typedef struct _keymap_entry { + char type; + rl_command_func_t *function; +} KEYMAP_ENTRY; + +/* This must be large enough to hold bindings for all of the characters + in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x, + and so on) plus one for subsequence matching. */ +#define KEYMAP_SIZE 257 +#define ANYOTHERKEY KEYMAP_SIZE-1 + +/* I wanted to make the above structure contain a union of: + union { rl_command_func_t *function; struct _keymap_entry *keymap; } value; + but this made it impossible for me to create a static array. + Maybe I need C lessons. */ + +typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; +typedef KEYMAP_ENTRY *Keymap; + +/* The values that TYPE can have in a keymap entry. */ +#define ISFUNC 0 +#define ISKMAP 1 +#define ISMACR 2 + +extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap; + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); + +/* Return a new keymap which is a copy of MAP. */ +extern Keymap rl_copy_keymap PARAMS((Keymap)); + +/* 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. */ +extern Keymap rl_make_keymap PARAMS((void)); + +/* Free the storage associated with a keymap. */ +extern void rl_discard_keymap PARAMS((Keymap)); + +/* These functions actually appear in bind.c */ + +/* Return the keymap corresponding to a given name. Names look like + `emacs' or `emacs-meta' or `vi-insert'. */ +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); + +/* Return the current keymap. */ +extern Keymap rl_get_keymap PARAMS((void)); + +/* Set the current keymap to MAP. */ +extern void rl_set_keymap PARAMS((Keymap)); + +#ifdef __cplusplus +} +#endif + +#endif /* _KEYMAPS_H_ */ diff --git a/readline-4.3.orig/kill.c b/readline-4.3.orig/kill.c new file mode 100644 index 0000000..a616b92 --- /dev/null +++ b/readline-4.3.orig/kill.c @@ -0,0 +1,652 @@ +/* kill.c -- kill ring management. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Killing Mechanism */ +/* */ +/* **************************************************************** */ + +/* What we assume for a max number of kills. */ +#define DEFAULT_MAX_KILLS 10 + +/* The real variable to look at to find out when to flush kills. */ +static int rl_max_kills = DEFAULT_MAX_KILLS; + +/* Where to store killed text. */ +static char **rl_kill_ring = (char **)NULL; + +/* Where we are in the kill ring. */ +static int rl_kill_index; + +/* How many slots we have in the kill ring. */ +static int rl_kill_ring_length; + +static int _rl_copy_to_kill_ring PARAMS((char *, int)); +static int region_kill_internal PARAMS((int)); +static int _rl_copy_word_as_kill PARAMS((int, int)); +static int rl_yank_nth_arg_internal PARAMS((int, int, int)); + +/* How to say that you only want to save a certain amount + of kill material. */ +int +rl_set_retained_kills (num) + int num; +{ + return 0; +} + +/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. + This uses TEXT directly, so the caller must not free it. If APPEND is + non-zero, and the last command was a kill, the text is appended to the + current kill ring slot, otherwise prepended. */ +static int +_rl_copy_to_kill_ring (text, append) + char *text; + int append; +{ + char *old, *new; + int slot; + + /* First, find the slot to work with. */ + if (_rl_last_command_was_kill == 0) + { + /* Get a new slot. */ + if (rl_kill_ring == 0) + { + /* If we don't have any defined, then make one. */ + rl_kill_ring = (char **) + xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); + rl_kill_ring[slot = 0] = (char *)NULL; + } + else + { + /* We have to add a new slot on the end, unless we have + exceeded the max limit for remembering kills. */ + slot = rl_kill_ring_length; + if (slot == rl_max_kills) + { + register int i; + free (rl_kill_ring[0]); + for (i = 0; i < slot; i++) + rl_kill_ring[i] = rl_kill_ring[i + 1]; + } + else + { + slot = rl_kill_ring_length += 1; + rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); + } + rl_kill_ring[--slot] = (char *)NULL; + } + } + else + slot = rl_kill_ring_length - 1; + + /* If the last command was a kill, prepend or append. */ + if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) + { + old = rl_kill_ring[slot]; + new = (char *)xmalloc (1 + strlen (old) + strlen (text)); + + if (append) + { + strcpy (new, old); + strcat (new, text); + } + else + { + strcpy (new, text); + strcat (new, old); + } + free (old); + free (text); + rl_kill_ring[slot] = new; + } + else + rl_kill_ring[slot] = text; + + rl_kill_index = slot; + return 0; +} + +/* The way to kill something. This appends or prepends to the last + kill, if the last command was a kill command. if FROM is less + than TO, then the text is appended, otherwise prepended. If the + last command was not a kill command, then a new slot is made for + this kill. */ +int +rl_kill_text (from, to) + int from, to; +{ + char *text; + + /* Is there anything to kill? */ + if (from == to) + { + _rl_last_command_was_kill++; + return 0; + } + + text = rl_copy_text (from, to); + + /* Delete the copied text from the line. */ + rl_delete_text (from, to); + + _rl_copy_to_kill_ring (text, from < to); + + _rl_last_command_was_kill++; + return 0; +} + +/* Now REMEMBER! In order to do prepending or appending correctly, kill + commands always make rl_point's original position be the FROM argument, + and rl_point's extent be the TO argument. */ + +/* **************************************************************** */ +/* */ +/* Killing Commands */ +/* */ +/* **************************************************************** */ + +/* Delete the word at point, saving the text in the kill ring. */ +int +rl_kill_word (count, key) + int count, key; +{ + int orig_point; + + if (count < 0) + return (rl_backward_kill_word (-count, key)); + else + { + orig_point = rl_point; + rl_forward_word (count, key); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Rubout the word before point, placing it on the kill ring. */ +int +rl_backward_kill_word (count, ignore) + int count, ignore; +{ + int orig_point; + + if (count < 0) + return (rl_kill_word (-count, ignore)); + else + { + orig_point = rl_point; + rl_backward_word (count, ignore); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill from here to the end of the line. If DIRECTION is negative, kill + back to the line start instead. */ +int +rl_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point; + + if (direction < 0) + return (rl_backward_kill_line (1, ignore)); + else + { + orig_point = rl_point; + rl_end_of_line (1, ignore); + if (orig_point != rl_point) + rl_kill_text (orig_point, rl_point); + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill backwards to the start of the line. If DIRECTION is negative, kill + forwards to the line end instead. */ +int +rl_backward_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point; + + if (direction < 0) + return (rl_kill_line (1, ignore)); + else + { + if (!rl_point) + rl_ding (); + else + { + orig_point = rl_point; + rl_beg_of_line (1, ignore); + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + } + return 0; +} + +/* Kill the whole line, no matter where point is. */ +int +rl_kill_full_line (count, ignore) + int count, ignore; +{ + rl_begin_undo_group (); + rl_point = 0; + rl_kill_text (rl_point, rl_end); + rl_mark = 0; + rl_end_undo_group (); + return 0; +} + +/* The next two functions mimic unix line editing behaviour, except they + save the deleted text on the kill ring. This is safer than not saving + it, and since we have a ring, nobody should get screwed. */ + +/* This does what C-w does in Unix. We can't prevent people from + using behaviour that they expect. */ +int +rl_unix_word_rubout (count, key) + int count, key; +{ + int orig_point; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) + rl_point--; + } + + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Here is C-u doing what Unix does. You don't *have* to use these + key-bindings. We have a choice of killing the entire line, or + killing from where we are to the start of the line. We choose the + latter, because if you are a Unix weenie, then you haven't backspaced + into the line at all, and if you aren't, then you know what you are + doing. */ +int +rl_unix_line_discard (count, key) + int count, key; +{ + if (rl_point == 0) + rl_ding (); + else + { + rl_kill_text (rl_point, 0); + rl_point = 0; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Copy the text in the `region' to the kill ring. If DELETE is non-zero, + delete the text from the line as well. */ +static int +region_kill_internal (delete) + int delete; +{ + char *text; + + if (rl_mark != rl_point) + { + text = rl_copy_text (rl_point, rl_mark); + if (delete) + rl_delete_text (rl_point, rl_mark); + _rl_copy_to_kill_ring (text, rl_point < rl_mark); + } + + _rl_last_command_was_kill++; + return 0; +} + +/* Copy the text in the region to the kill ring. */ +int +rl_copy_region_to_kill (count, ignore) + int count, ignore; +{ + return (region_kill_internal (0)); +} + +/* Kill the text between the point and mark. */ +int +rl_kill_region (count, ignore) + int count, ignore; +{ + int r, npoint; + + npoint = (rl_point < rl_mark) ? rl_point : rl_mark; + r = region_kill_internal (1); + _rl_fix_point (1); + rl_point = npoint; + return r; +} + +/* Copy COUNT words to the kill ring. DIR says which direction we look + to find the words. */ +static int +_rl_copy_word_as_kill (count, dir) + int count, dir; +{ + int om, op, r; + + om = rl_mark; + op = rl_point; + + if (dir > 0) + rl_forward_word (count, 0); + else + rl_backward_word (count, 0); + + rl_mark = rl_point; + + if (dir > 0) + rl_backward_word (count, 0); + else + rl_forward_word (count, 0); + + r = region_kill_internal (0); + + rl_mark = om; + rl_point = op; + + return r; +} + +int +rl_copy_forward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_backward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, 1)); +} + +int +rl_copy_backward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_forward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, -1)); +} + +/* Yank back the last killed text. This ignores arguments. */ +int +rl_yank (count, ignore) + int count, ignore; +{ + if (rl_kill_ring == 0) + { + _rl_abort_internal (); + return -1; + } + + _rl_set_mark_at_pos (rl_point); + rl_insert_text (rl_kill_ring[rl_kill_index]); + return 0; +} + +/* If the last command was yank, or yank_pop, and the text just + before point is identical to the current kill item, then + delete that text from the line, rotate the index down, and + yank back some other text. */ +int +rl_yank_pop (count, key) + int count, key; +{ + int l, n; + + if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || + !rl_kill_ring) + { + _rl_abort_internal (); + return -1; + } + + l = strlen (rl_kill_ring[rl_kill_index]); + n = rl_point - l; + if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) + { + rl_delete_text (n, rl_point); + rl_point = n; + rl_kill_index--; + if (rl_kill_index < 0) + rl_kill_index = rl_kill_ring_length - 1; + rl_yank (1, 0); + return 0; + } + else + { + _rl_abort_internal (); + return -1; + } +} + +/* Yank the COUNTh argument from the previous history line, skipping + HISTORY_SKIP lines before looking for the `previous line'. */ +static int +rl_yank_nth_arg_internal (count, ignore, history_skip) + int count, ignore, history_skip; +{ + register HIST_ENTRY *entry; + char *arg; + int i, pos; + + pos = where_history (); + + if (history_skip) + { + for (i = 0; i < history_skip; i++) + entry = previous_history (); + } + + entry = previous_history (); + + history_set_pos (pos); + + if (entry == 0) + { + rl_ding (); + return -1; + } + + arg = history_arg_extract (count, count, entry->line); + if (!arg || !*arg) + { + rl_ding (); + return -1; + } + + rl_begin_undo_group (); + + _rl_set_mark_at_pos (rl_point); + +#if defined (VI_MODE) + /* Vi mode always inserts a space before yanking the argument, and it + inserts it right *after* rl_point. */ + if (rl_editing_mode == vi_mode) + { + rl_vi_append_mode (1, ignore); + rl_insert_text (" "); + } +#endif /* VI_MODE */ + + rl_insert_text (arg); + free (arg); + + rl_end_undo_group (); + return 0; +} + +/* Yank the COUNTth argument from the previous history line. */ +int +rl_yank_nth_arg (count, ignore) + int count, ignore; +{ + return (rl_yank_nth_arg_internal (count, ignore, 0)); +} + +/* Yank the last argument from the previous history line. This `knows' + how rl_yank_nth_arg treats a count of `$'. With an argument, this + behaves the same as rl_yank_nth_arg. */ +int +rl_yank_last_arg (count, key) + int count, key; +{ + static int history_skip = 0; + static int explicit_arg_p = 0; + static int count_passed = 1; + static int direction = 1; + static int undo_needed = 0; + int retval; + + if (rl_last_func != rl_yank_last_arg) + { + history_skip = 0; + explicit_arg_p = rl_explicit_arg; + count_passed = count; + direction = 1; + } + else + { + if (undo_needed) + rl_do_undo (); + if (count < 1) + direction = -direction; + history_skip += direction; + if (history_skip < 0) + history_skip = 0; + } + + if (explicit_arg_p) + retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); + else + retval = rl_yank_nth_arg_internal ('$', key, history_skip); + + undo_needed = retval == 0; + return retval; +} + +/* A special paste command for users of Cygnus's cygwin32. */ +#if defined (__CYGWIN__) +#include + +int +rl_paste_from_clipboard (count, key) + int count, key; +{ + char *data, *ptr; + int len; + + if (OpenClipboard (NULL) == 0) + return (0); + + data = (char *)GetClipboardData (CF_TEXT); + if (data) + { + ptr = strchr (data, '\r'); + if (ptr) + { + len = ptr - data; + ptr = (char *)xmalloc (len + 1); + ptr[len] = '\0'; + strncpy (ptr, data, len); + } + else + ptr = data; + _rl_set_mark_at_pos (rl_point); + rl_insert_text (ptr); + if (ptr != data) + free (ptr); + CloseClipboard (); + } + return (0); +} +#endif /* __CYGWIN__ */ diff --git a/readline-4.3.orig/macro.c b/readline-4.3.orig/macro.c new file mode 100644 index 0000000..b73c3af --- /dev/null +++ b/readline-4.3.orig/macro.c @@ -0,0 +1,262 @@ +/* macro.c -- keyboard macros for readline. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Hacking Keyboard Macros */ +/* */ +/* **************************************************************** */ + +/* The currently executing macro string. If this is non-zero, + then it is a malloc ()'ed string where input is coming from. */ +char *rl_executing_macro = (char *)NULL; + +/* The offset in the above string to the next character to be read. */ +static int executing_macro_index; + +/* The current macro string being built. Characters get stuffed + in here by add_macro_char (). */ +static char *current_macro = (char *)NULL; + +/* The size of the buffer allocated to current_macro. */ +static int current_macro_size; + +/* The index at which characters are being added to current_macro. */ +static int current_macro_index; + +/* A structure used to save nested macro strings. + It is a linked list of string/index for each saved macro. */ +struct saved_macro { + struct saved_macro *next; + char *string; + int sindex; +}; + +/* The list of saved macros. */ +static struct saved_macro *macro_list = (struct saved_macro *)NULL; + +/* Set up to read subsequent input from STRING. + STRING is free ()'ed when we are done with it. */ +void +_rl_with_macro_input (string) + char *string; +{ + _rl_push_executing_macro (); + rl_executing_macro = string; + executing_macro_index = 0; + RL_SETSTATE(RL_STATE_MACROINPUT); +} + +/* Return the next character available from a macro, or 0 if + there are no macro characters. */ +int +_rl_next_macro_key () +{ + if (rl_executing_macro == 0) + return (0); + + if (rl_executing_macro[executing_macro_index] == 0) + { + _rl_pop_executing_macro (); + return (_rl_next_macro_key ()); + } + + return (rl_executing_macro[executing_macro_index++]); +} + +/* Save the currently executing macro on a stack of saved macros. */ +void +_rl_push_executing_macro () +{ + struct saved_macro *saver; + + saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); + saver->next = macro_list; + saver->sindex = executing_macro_index; + saver->string = rl_executing_macro; + + macro_list = saver; +} + +/* Discard the current macro, replacing it with the one + on the top of the stack of saved macros. */ +void +_rl_pop_executing_macro () +{ + struct saved_macro *macro; + + FREE (rl_executing_macro); + rl_executing_macro = (char *)NULL; + executing_macro_index = 0; + + if (macro_list) + { + macro = macro_list; + rl_executing_macro = macro_list->string; + executing_macro_index = macro_list->sindex; + macro_list = macro_list->next; + free (macro); + } + + if (rl_executing_macro == 0) + RL_UNSETSTATE(RL_STATE_MACROINPUT); +} + +/* Add a character to the macro being built. */ +void +_rl_add_macro_char (c) + int c; +{ + if (current_macro_index + 1 >= current_macro_size) + { + if (current_macro == 0) + current_macro = (char *)xmalloc (current_macro_size = 25); + else + current_macro = (char *)xrealloc (current_macro, current_macro_size += 25); + } + + current_macro[current_macro_index++] = c; + current_macro[current_macro_index] = '\0'; +} + +void +_rl_kill_kbd_macro () +{ + if (current_macro) + { + free (current_macro); + current_macro = (char *) NULL; + } + current_macro_size = current_macro_index = 0; + + FREE (rl_executing_macro); + rl_executing_macro = (char *) NULL; + executing_macro_index = 0; + + RL_UNSETSTATE(RL_STATE_MACRODEF); +} + +/* Begin defining a keyboard macro. + Keystrokes are recorded as they are executed. + End the definition with rl_end_kbd_macro (). + If a numeric argument was explicitly typed, then append this + definition to the end of the existing macro, and start by + re-executing the existing macro. */ +int +rl_start_kbd_macro (ignore1, ignore2) + int ignore1, ignore2; +{ + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + _rl_abort_internal (); + return -1; + } + + if (rl_explicit_arg) + { + if (current_macro) + _rl_with_macro_input (savestring (current_macro)); + } + else + current_macro_index = 0; + + RL_SETSTATE(RL_STATE_MACRODEF); + return 0; +} + +/* Stop defining a keyboard macro. + A numeric argument says to execute the macro right now, + that many times, counting the definition as the first time. */ +int +rl_end_kbd_macro (count, ignore) + int count, ignore; +{ + if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) + { + _rl_abort_internal (); + return -1; + } + + current_macro_index -= rl_key_sequence_length - 1; + current_macro[current_macro_index] = '\0'; + + RL_UNSETSTATE(RL_STATE_MACRODEF); + + return (rl_call_last_kbd_macro (--count, 0)); +} + +/* Execute the most recently defined keyboard macro. + COUNT says how many times to execute it. */ +int +rl_call_last_kbd_macro (count, ignore) + int count, ignore; +{ + if (current_macro == 0) + _rl_abort_internal (); + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + rl_ding (); /* no recursive macros */ + current_macro[--current_macro_index] = '\0'; /* erase this char */ + return 0; + } + + while (count--) + _rl_with_macro_input (savestring (current_macro)); + return 0; +} + +void +rl_push_macro_input (macro) + char *macro; +{ + _rl_with_macro_input (macro); +} diff --git a/readline-4.3.orig/mbutil.c b/readline-4.3.orig/mbutil.c new file mode 100644 index 0000000..50302f0 --- /dev/null +++ b/readline-4.3.orig/mbutil.c @@ -0,0 +1,337 @@ +/* mbutil.c -- readline multibyte character utility functions */ + +/* Copyright (C) 2001 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Declared here so it can be shared between the readline and history + libraries. */ +#if defined (HANDLE_MULTIBYTE) +int rl_byte_oriented = 0; +#else +int rl_byte_oriented = 1; +#endif + +/* **************************************************************** */ +/* */ +/* Multibyte Character Utility Functions */ +/* */ +/* **************************************************************** */ + +#if defined(HANDLE_MULTIBYTE) + +static int +_rl_find_next_mbchar_internal (string, seed, count, find_non_zero) + char *string; + int seed, count, find_non_zero; +{ + size_t tmp = 0; + mbstate_t ps; + int point = 0; + wchar_t wc; + + memset(&ps, 0, sizeof (mbstate_t)); + if (seed < 0) + seed = 0; + if (count <= 0) + return seed; + + 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 --; + + 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) + { + /* invalid bytes. asume a byte represents a character */ + point++; + count--; + /* reset states. */ + memset(&ps, 0, sizeof(mbstate_t)); + } + else if (tmp == (size_t)0) + /* found '\0' char */ + break; + else + { + /* valid bytes */ + point += tmp; + if (find_non_zero) + { + if (wcwidth (wc) == 0) + continue; + else + count--; + } + else + count--; + } + } + + if (find_non_zero) + { + tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); + while (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)) + break; + } + } + return point; +} + +static int +_rl_find_prev_mbchar_internal (string, seed, find_non_zero) + char *string; + int seed, find_non_zero; +{ + mbstate_t ps; + int prev, non_zero_prev, point, length; + size_t tmp; + wchar_t wc; + + memset(&ps, 0, sizeof(mbstate_t)); + length = strlen(string); + + if (seed < 0) + return 0; + else if (length < seed) + return length; + + prev = non_zero_prev = point = 0; + while (point < seed) + { + tmp = mbrtowc (&wc, string + point, length - point, &ps); + if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + { + /* in this case, bytes are invalid or shorted to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + tmp = 1; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + memset(&ps, 0, sizeof (mbstate_t)); + } + else if (tmp == 0) + break; /* Found '\0' char. Can this happen? */ + else + { + if (find_non_zero) + { + if (wcwidth (wc) != 0) + prev = point; + } + else + prev = point; + } + + point += tmp; + } + + return prev; +} + +/* return the number of bytes parsed from the multibyte sequence starting + at src, if a non-L'\0' wide character was recognized. It returns 0, + if a L'\0' wide character was recognized. It returns (size_t)(-1), + if an invalid multibyte sequence was encountered. It returns (size_t)(-2) + if it couldn't parse a complete multibyte character. */ +int +_rl_get_char_len (src, ps) + char *src; + mbstate_t *ps; +{ + size_t tmp; + + tmp = mbrlen((const char *)src, (size_t)strlen (src), ps); + if (tmp == (size_t)(-2)) + { + /* shorted to compose multibyte char */ + memset (ps, 0, sizeof(mbstate_t)); + return -2; + } + else if (tmp == (size_t)(-1)) + { + /* invalid to compose multibyte char */ + /* initialize the conversion state */ + memset (ps, 0, sizeof(mbstate_t)); + return -1; + } + else if (tmp == (size_t)0) + return 0; + else + return (int)tmp; +} + +/* compare the specified two characters. If the characters matched, + return 1. Otherwise return 0. */ +int +_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) + char *buf1, *buf2; + mbstate_t *ps1, *ps2; + int pos1, pos2; +{ + int i, w1, w2; + + if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || + (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 || + (w1 != w2) || + (buf1[pos1] != buf2[pos2])) + return 0; + + for (i = 1; i < w1; i++) + if (buf1[pos1+i] != buf2[pos2+i]) + return 0; + + return 1; +} + +/* adjust pointed byte and find mbstate of the point of string. + adjusted point will be point <= adjusted_point, and returns + differences of the byte(adjusted_point - point). + if point is invalied (point < 0 || more than string length), + it returns -1 */ +int +_rl_adjust_point(string, point, ps) + char *string; + int point; + mbstate_t *ps; +{ + size_t tmp = 0; + int length; + int pos = 0; + + length = strlen(string); + if (point < 0) + return -1; + if (length < point) + return -1; + + while (pos < point) + { + tmp = mbrlen (string + pos, length - pos, ps); + if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + { + /* in this case, bytes are invalid or shorted to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + pos++; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + memset (ps, 0, sizeof (mbstate_t)); + } + else + pos += tmp; + } + + return (pos - point); +} + +int +_rl_is_mbchar_matched (string, seed, end, mbchar, length) + char *string; + int seed, end; + char *mbchar; + int length; +{ + int i; + + if ((end - seed) < length) + return 0; + + for (i = 0; i < length; i++) + if (string[seed + i] != mbchar[i]) + return 0; + return 1; +} +#endif /* HANDLE_MULTIBYTE */ + +/* Find next `count' characters started byte point of the specified seed. + If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte + characters. */ +#undef _rl_find_next_mbchar +int +_rl_find_next_mbchar (string, seed, count, flags) + char *string; + int seed, count, flags; +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_next_mbchar_internal (string, seed, count, flags); +#else + return (seed + count); +#endif +} + +/* Find previous character started byte point of the specified seed. + Returned point will be point <= seed. If flags is MB_FIND_NONZERO, + we look for non-zero-width multibyte characters. */ +#undef _rl_find_prev_mbchar +int +_rl_find_prev_mbchar (string, seed, flags) + char *string; + int seed, flags; +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_prev_mbchar_internal (string, seed, flags); +#else + return ((seed == 0) ? seed : seed - 1); +#endif +} diff --git a/readline-4.3.orig/misc.c b/readline-4.3.orig/misc.c new file mode 100644 index 0000000..f3775d3 --- /dev/null +++ b/readline-4.3.orig/misc.c @@ -0,0 +1,496 @@ +/* misc.c -- miscellaneous bindable readline functions. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +static int rl_digit_loop PARAMS((void)); +static void _rl_history_set_point PARAMS((void)); + +/* Forward declarations used in this file */ +void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +/* If non-zero, rl_get_previous_history and rl_get_next_history attempt + to preserve the value of rl_point from line to line. */ +int _rl_history_preserve_point = 0; + +/* 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; + +/* **************************************************************** */ +/* */ +/* Numeric Arguments */ +/* */ +/* **************************************************************** */ + +/* Handle C-u style numeric args, as well as M--, and M-digits. */ +static int +rl_digit_loop () +{ + int key, c, sawminus, sawdigits; + + rl_save_prompt (); + + 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; + } + + /* 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)); + } + } + + c = UNMETA (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) + { + rl_numeric_arg = sawminus = 1; + rl_arg_sign = -1; + } + else + { + /* Make M-- command equivalent to M--1 command. */ + if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0) + rl_explicit_arg = 1; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return (_rl_dispatch (key, _rl_keymap)); + } + } + + /*NOTREACHED*/ +} + +/* 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 ()); +} + +/* What to do when you abort reading an argument. */ +int +rl_discard_argument () +{ + rl_ding (); + rl_clear_message (); + _rl_init_argument (); + return 0; +} + +/* Create a default argument. */ +int +_rl_init_argument () +{ + rl_numeric_arg = rl_arg_sign = 1; + rl_explicit_arg = 0; + return 0; +} + +/* C-u, universal argument. Multiply the current argument by 4. + Read a key. If the key has nothing to do with arguments, then + dispatch on it. If the key is the abort character then abort. */ +int +rl_universal_argument (count, key) + int count, key; +{ + rl_numeric_arg *= 4; + return (rl_digit_loop ()); +} + +/* **************************************************************** */ +/* */ +/* History Utilities */ +/* */ +/* **************************************************************** */ + +/* We already have a history library, and that is what we use to control + the history features of readline. This is our local interface to + the history mechanism. */ + +/* While we are editing the history, this is the saved + version of the original line. */ +HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL; + +/* Set the history pointer back to the last entry in the history. */ +void +_rl_start_using_history () +{ + using_history (); + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Free the contents (and containing structure) of a HIST_ENTRY. */ +void +_rl_free_history_entry (entry) + HIST_ENTRY *entry; +{ + if (entry == 0) + return; + if (entry->line) + free (entry->line); + free (entry); +} + +/* Perhaps put back the current line if it has changed. */ +int +rl_maybe_replace_line () +{ + HIST_ENTRY *temp; + + temp = current_history (); + /* If the current line has changed, save the changes. */ + if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) + { + temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); + free (temp->line); + free (temp); + } + return 0; +} + +/* Restore the _rl_saved_line_for_history if there is one. */ +int +rl_maybe_unsave_line () +{ + if (_rl_saved_line_for_history) + { + 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); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + rl_point = rl_end; /* rl_replace_line sets rl_end */ + } + else + rl_ding (); + return 0; +} + +/* Save the current line in _rl_saved_line_for_history. */ +int +rl_maybe_save_line () +{ + if (_rl_saved_line_for_history == 0) + { + _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->data = (char *)rl_undo_list; + } + return 0; +} + +int +_rl_free_saved_history_line () +{ + if (_rl_saved_line_for_history) + { + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + } + return 0; +} + +static void +_rl_history_set_point () +{ + rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) + ? _rl_history_saved_point + : rl_end; + if (rl_point > rl_end) + rl_point = rl_end; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_point = 0; +#endif /* VI_MODE */ + + if (rl_editing_mode == emacs_mode) + rl_mark = (rl_point == rl_end ? 0 : rl_end); +} + +void +rl_replace_from_history (entry, flags) + HIST_ENTRY *entry; + int flags; /* currently unused */ +{ + rl_replace_line (entry->line, 0); + rl_undo_list = (UNDO_LIST *)entry->data; + rl_point = rl_end; + rl_mark = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + rl_point = 0; + rl_mark = rl_end; + } +#endif +} + +/* **************************************************************** */ +/* */ +/* History Commands */ +/* */ +/* **************************************************************** */ + +/* Meta-< goes to the start of the history. */ +int +rl_beginning_of_history (count, key) + int count, key; +{ + return (rl_get_previous_history (1 + where_history (), key)); +} + +/* Meta-> goes to the end of the history. (The current line). */ +int +rl_end_of_history (count, key) + int count, key; +{ + rl_maybe_replace_line (); + using_history (); + rl_maybe_unsave_line (); + return 0; +} + +/* Move down to the next history line. */ +int +rl_get_next_history (count, key) + int count, key; +{ + HIST_ENTRY *temp; + + if (count < 0) + return (rl_get_previous_history (-count, key)); + + if (count == 0) + return 0; + + rl_maybe_replace_line (); + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = next_history (); + if (!temp) + break; + --count; + } + + if (temp == 0) + rl_maybe_unsave_line (); + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + return 0; +} + +/* Get the previous item out of our interactive history, making it the current + line. If there is no previous history, just ding. */ +int +rl_get_previous_history (count, key) + int count, key; +{ + HIST_ENTRY *old_temp, *temp; + + if (count < 0) + return (rl_get_next_history (-count, key)); + + if (count == 0) + return 0; + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + /* If we don't have a line saved, then save this one. */ + rl_maybe_save_line (); + + /* If the current line has changed, save the changes. */ + rl_maybe_replace_line (); + + temp = old_temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = previous_history (); + if (temp == 0) + break; + + old_temp = temp; + --count; + } + + /* If there was a large argument, and we moved back to the start of the + history, that is not an error. So use the last value found. */ + if (!temp && old_temp) + temp = old_temp; + + if (temp == 0) + rl_ding (); + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + return 0; +} + +/* **************************************************************** */ +/* */ +/* Editing Modes */ +/* */ +/* **************************************************************** */ +/* How to toggle back and forth between editing modes. */ +int +rl_vi_editing_mode (count, key) + int count, key; +{ +#if defined (VI_MODE) + _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ + rl_editing_mode = vi_mode; + rl_vi_insertion_mode (1, key); +#endif /* VI_MODE */ + + return 0; +} + +int +rl_emacs_editing_mode (count, key) + int count, key; +{ + rl_editing_mode = emacs_mode; + _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ + _rl_keymap = emacs_standard_keymap; + return 0; +} + +/* Function for the rest of the library to use to set insert/overwrite mode. */ +void +_rl_set_insert_mode (im, force) + int im, force; +{ +#ifdef CURSOR_MODE + _rl_set_cursor (im, force); +#endif + + rl_insert_mode = im; +} + +/* Toggle overwrite mode. A positive explicit argument selects overwrite + mode. A negative or zero explicit argument selects insert mode. */ +int +rl_overwrite_mode (count, key) + int count, key; +{ + if (rl_explicit_arg == 0) + _rl_set_insert_mode (rl_insert_mode ^ 1, 0); + else if (count > 0) + _rl_set_insert_mode (RL_IM_OVERWRITE, 0); + else + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return 0; +} diff --git a/readline-4.3.orig/nls.c b/readline-4.3.orig/nls.c new file mode 100644 index 0000000..706c819 --- /dev/null +++ b/readline-4.3.orig/nls.c @@ -0,0 +1,225 @@ +/* nls.c -- skeletal internationalization code. */ + +/* Copyright (C) 1996 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +#include "rldefs.h" +#include "readline.h" +#include "rlshell.h" +#include "rlprivate.h" + +#if !defined (HAVE_SETLOCALE) +/* A list of legal values for the LANG or LC_CTYPE environment variables. + If a locale name in this list is the value for the LC_ALL, LC_CTYPE, + or LANG environment variable (using the first of those with a value), + readline eight-bit mode is enabled. */ +static char *legal_lang_values[] = +{ + "iso88591", + "iso88592", + "iso88593", + "iso88594", + "iso88595", + "iso88596", + "iso88597", + "iso88598", + "iso88599", + "iso885910", + "koi8r", + 0 +}; + +static char *normalize_codeset PARAMS((char *)); +static char *find_codeset PARAMS((char *, size_t *)); +#endif /* !HAVE_SETLOCALE */ + +/* 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. */ +int +_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; + + /* Set the LC_CTYPE locale category from environment variables. */ + t = setlocale (LC_CTYPE, ""); + if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + return (1); + } + else + return (0); + +#else /* !HAVE_SETLOCALE */ + char *lspec, *t; + int i; + + /* 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"); + if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) + return (0); + for (i = 0; t && legal_lang_values[i]; i++) + if (STREQ (t, legal_lang_values[i])) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + break; + } + free (t); + return (legal_lang_values[i] ? 1 : 0); + +#endif /* !HAVE_SETLOCALE */ +} + +#if !defined (HAVE_SETLOCALE) +static char * +normalize_codeset (codeset) + char *codeset; +{ + size_t namelen, i; + int len, all_digits; + char *wp, *retval; + + codeset = find_codeset (codeset, &namelen); + + if (codeset == 0) + return (codeset); + + all_digits = 1; + for (len = 0, i = 0; i < namelen; i++) + { + if (ISALNUM ((unsigned char)codeset[i])) + { + len++; + all_digits &= _rl_digit_p (codeset[i]); + } + } + + retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1); + if (retval == 0) + return ((char *)0); + + wp = retval; + /* Add `iso' to beginning of an all-digit codeset */ + if (all_digits) + { + *wp++ = 'i'; + *wp++ = 's'; + *wp++ = 'o'; + } + + for (i = 0; i < namelen; i++) + if (ISALPHA ((unsigned char)codeset[i])) + *wp++ = _rl_to_lower (codeset[i]); + else if (_rl_digit_p (codeset[i])) + *wp++ = codeset[i]; + *wp = '\0'; + + return retval; +} + +/* Isolate codeset portion of locale specification. */ +static char * +find_codeset (name, lenp) + char *name; + size_t *lenp; +{ + char *cp, *language, *result; + + cp = language = name; + result = (char *)0; + + while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',') + cp++; + + /* This does not make sense: language has to be specified. As + an exception we allow the variable to contain only the codeset + name. Perhaps there are funny codeset names. */ + if (language == cp) + { + *lenp = strlen (language); + result = language; + } + else + { + /* Next is the territory. */ + if (*cp == '_') + do + ++cp; + while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_'); + + /* Now, finally, is the codeset. */ + result = cp; + if (*cp == '.') + do + ++cp; + while (*cp && *cp != '@'); + + if (cp - result > 2) + { + result++; + *lenp = cp - result; + } + else + { + *lenp = strlen (language); + result = language; + } + } + + return result; +} +#endif /* !HAVE_SETLOCALE */ diff --git a/readline-4.3.orig/parens.c b/readline-4.3.orig/parens.c new file mode 100644 index 0000000..54ef1f3 --- /dev/null +++ b/readline-4.3.orig/parens.c @@ -0,0 +1,179 @@ +/* parens.c -- Implementation of matching parentheses feature. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 "rlconf.h" + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT +#endif + +#if defined (HAVE_SELECT) +# include +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#include "readline.h" +#include "rlprivate.h" + +static int find_matching_open PARAMS((char *, int, int)); + +/* Non-zero means try to blink the matching open parenthesis when the + close parenthesis is inserted. */ +#if defined (HAVE_SELECT) +int rl_blink_matching_paren = 1; +#else /* !HAVE_SELECT */ +int rl_blink_matching_paren = 0; +#endif /* !HAVE_SELECT */ + +static int _paren_blink_usec = 500000; + +/* Change emacs_standard_keymap to have bindings for paren matching when + ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */ +void +_rl_enable_paren_matching (on_or_off) + int on_or_off; +{ + if (on_or_off) + { /* ([{ */ + rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap); + } + else + { /* ([{ */ + rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap); + } +} + +int +rl_set_paren_blink_timeout (u) + int u; +{ + int o; + + o = _paren_blink_usec; + if (u > 0) + _paren_blink_usec = u; + return (o); +} + +int +rl_insert_close (count, invoking_key) + int count, invoking_key; +{ + if (rl_explicit_arg || !rl_blink_matching_paren) + _rl_insert_char (count, invoking_key); + else + { +#if defined (HAVE_SELECT) + int orig_point, match_point, ready; + struct timeval timer; + fd_set readfds; + + _rl_insert_char (1, invoking_key); + (*rl_redisplay_function) (); + match_point = + find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); + + /* Emacs might message or ring the bell here, but I don't. */ + if (match_point < 0) + return -1; + + FD_ZERO (&readfds); + FD_SET (fileno (rl_instream), &readfds); + timer.tv_sec = 0; + timer.tv_usec = _paren_blink_usec; + + orig_point = rl_point; + rl_point = match_point; + (*rl_redisplay_function) (); + ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + rl_point = orig_point; +#else /* !HAVE_SELECT */ + _rl_insert_char (count, invoking_key); +#endif /* !HAVE_SELECT */ + } + return 0; +} + +static int +find_matching_open (string, from, closer) + char *string; + int from, closer; +{ + register int i; + int opener, level, delimiter; + + switch (closer) + { + case ']': opener = '['; break; + case '}': opener = '{'; break; + case ')': opener = '('; break; + default: + return (-1); + } + + level = 1; /* The closer passed in counts as 1. */ + delimiter = 0; /* Delimited state unknown. */ + + for (i = from; i > -1; i--) + { + if (delimiter && (string[i] == delimiter)) + delimiter = 0; + else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i])) + delimiter = string[i]; + else if (!delimiter && (string[i] == closer)) + level++; + else if (!delimiter && (string[i] == opener)) + level--; + + if (!level) + break; + } + return (i); +} diff --git a/readline-4.3.orig/posixdir.h b/readline-4.3.orig/posixdir.h new file mode 100644 index 0000000..505e279 --- /dev/null +++ b/readline-4.3.orig/posixdir.h @@ -0,0 +1,57 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +/* This file should be included instead of or . */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include +# define D_NAMLEN(d) (strlen ((d)->d_name)) +#else +# if defined (HAVE_SYS_NDIR_H) +# include +# endif +# if defined (HAVE_SYS_DIR_H) +# include +# endif +# if defined (HAVE_NDIR_H) +# include +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO) +# define d_fileno d_ino +#endif + +#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_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 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* _POSIX_SOURCE */ + +#endif /* !_POSIXDIR_H_ */ diff --git a/readline-4.3.orig/posixjmp.h b/readline-4.3.orig/posixjmp.h new file mode 100644 index 0000000..b52aa00 --- /dev/null +++ b/readline-4.3.orig/posixjmp.h @@ -0,0 +1,40 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf +# if !defined (__OPENNT) +# undef setjmp +# define setjmp(x) sigsetjmp((x), 1) +# undef longjmp +# define longjmp(x, n) siglongjmp((x), (n)) +# endif /* !__OPENNT */ +#else +# define procenv_t jmp_buf +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/readline-4.3.orig/posixstat.h b/readline-4.3.orig/posixstat.h new file mode 100644 index 0000000..c93b528 --- /dev/null +++ b/readline-4.3.orig/posixstat.h @@ -0,0 +1,142 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/readline-4.3.orig/readline.c b/readline-4.3.orig/readline.c new file mode 100644 index 0000000..28801f1 --- /dev/null +++ b/readline-4.3.orig/readline.c @@ -0,0 +1,973 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include +#include "posixjmp.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#ifndef RL_LIBRARY_VERSION +# define RL_LIBRARY_VERSION "4.3" +#endif + +#ifndef RL_READLINE_VERSION +# define RL_READLINE_VERSION 0x0403 +#endif + +extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +/* Forward declarations used in this file. */ +static char *readline_internal PARAMS((void)); +static void readline_initialize_everything PARAMS((void)); + +static void bind_arrow_keys_internal PARAMS((Keymap)); +static void bind_arrow_keys PARAMS((void)); + +static void readline_default_bindings PARAMS((void)); + +/* **************************************************************** */ +/* */ +/* Line editing input utility */ +/* */ +/* **************************************************************** */ + +const char *rl_library_version = RL_LIBRARY_VERSION; + +int rl_readline_version = RL_READLINE_VERSION; + +/* True if this is `real' readline as opposed to some stub substitute. */ +int rl_gnu_readline_p = 1; + +/* A pointer to the keymap that is currently in use. + 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; + +/* The current insert mode: input (the default) or overwrite */ +int rl_insert_mode = RL_IM_DEFAULT; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +int rl_dispatching; + +/* Non-zero if the previous command was a kill command. */ +int _rl_last_command_was_kill = 0; + +/* The current value of the numeric argument specified by the user. */ +int rl_numeric_arg = 1; + +/* Non-zero if an argument was typed. */ +int rl_explicit_arg = 0; + +/* Temporary value used while generating the argument. */ +int rl_arg_sign = 1; + +/* Non-zero means we have been called at least once before. */ +static int rl_initialized; + +#if 0 +/* If non-zero, this program is running in an EMACS buffer. */ +static int running_in_emacs; +#endif + +/* Flags word encapsulating the current readline state. */ +int rl_readline_state = RL_STATE_NONE; + +/* The current offset in the current input line. */ +int rl_point; + +/* Mark in the current input line. */ +int rl_mark; + +/* Length of the current input line. */ +int rl_end; + +/* Make this non-zero to return the current input_line. */ +int rl_done; + +/* The last function executed by readline. */ +rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL; + +/* Top level environment for readline_internal (). */ +procenv_t readline_top_level; + +/* The streams we interact with. */ +FILE *_rl_in_stream, *_rl_out_stream; + +/* The names of the streams that we do input and output to. */ +FILE *rl_instream = (FILE *)NULL; +FILE *rl_outstream = (FILE *)NULL; + +/* Non-zero means echo characters as they are read. Defaults to no echo; + set to 1 if there is a controlling terminal, we can get its attributes, + and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings + for the code that sets it. */ +int readline_echoing_p = 0; + +/* Current prompt. */ +char *rl_prompt = (char *)NULL; +int rl_visible_prompt_length = 0; + +/* Set to non-zero by calling application if it has already printed rl_prompt + and does not want readline to do it the first time. */ +int rl_already_prompted = 0; + +/* The number of characters read in order to type this complete command. */ +int rl_key_sequence_length = 0; + +/* If non-zero, then this is the address of a function to call just + before readline_internal_setup () prints the first prompt. */ +rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL; + +/* What we use internally. You should always refer to RL_LINE_BUFFER. */ +static char *the_line; + +/* The character that can generate an EOF. Really read from + the terminal driver... just defaulted here. */ +int _rl_eof_char = CTRL ('D'); + +/* Non-zero makes this the next keystroke to read. */ +int rl_pending_input = 0; + +/* Pointer to a useful terminal name. */ +const char *rl_terminal_name = (const char *)NULL; + +/* Non-zero means to always use horizontal scrolling in line display. */ +int _rl_horizontal_scroll_mode = 0; + +/* Non-zero means to display an asterisk at the starts of history lines + which have been modified. */ +int _rl_mark_modified_lines = 0; + +/* The style of `bell' notification preferred. This can be set to NO_BELL, + AUDIBLE_BELL, or VISIBLE_BELL. */ +int _rl_bell_preference = AUDIBLE_BELL; + +/* String inserted into the line by rl_insert_comment (). */ +char *_rl_comment_begin; + +/* Keymap holding the function currently being executed. */ +Keymap rl_executing_keymap; + +/* Non-zero means to erase entire line, including prompt, on empty input lines. */ +int rl_erase_empty_line = 0; + +/* Non-zero means to read only this many characters rather than up to a + character bound to accept-line. */ +int rl_num_chars_to_read; + +/* Line buffer and maintenence. */ +char *rl_line_buffer = (char *)NULL; +int rl_line_buffer_len = 0; + +/* Forward declarations used by the display, termcap, and history code. */ + +/* **************************************************************** */ +/* */ +/* `Forward' declarations */ +/* */ +/* **************************************************************** */ + +/* Non-zero means do not parse any lines other than comments and + parser directives. */ +unsigned char _rl_parsing_conditionalized_out = 0; + +/* Non-zero means to convert characters with the meta bit set to + escape-prefixed characters so we can indirect through + emacs_meta_keymap or vi_escape_keymap. */ +int _rl_convert_meta_chars_to_ascii = 1; + +/* Non-zero means to output characters with the meta bit set directly + rather than as a meta-prefixed escape sequence. */ +int _rl_output_meta_chars = 0; + +/* **************************************************************** */ +/* */ +/* Top Level Functions */ +/* */ +/* **************************************************************** */ + +/* Non-zero means treat 0200 bit in terminal input as Meta bit. */ +int _rl_meta_flag = 0; /* Forward declaration */ + +/* Set up the prompt and expand it. Called from readline() and + rl_callback_handler_install (). */ +int +rl_set_prompt (prompt) + const char *prompt; +{ + FREE (rl_prompt); + rl_prompt = prompt ? savestring (prompt) : (char *)NULL; + + rl_visible_prompt_length = rl_expand_prompt (rl_prompt); + return 0; +} + +/* Read a line of input. Prompt with PROMPT. An empty PROMPT means + none. A return value of NULL means that EOF was encountered. */ +char * +readline (prompt) + const char *prompt; +{ + char *value; + + /* If we are at EOF return a NULL string. */ + if (rl_pending_input == EOF) + { + rl_clear_pending_input (); + return ((char *)NULL); + } + + rl_set_prompt (prompt); + + rl_initialize (); + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + rl_set_signals (); +#endif + + value = readline_internal (); + (*rl_deprep_term_function) (); + +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + + return (value); +} + +#if defined (READLINE_CALLBACKS) +# define STATIC_CALLBACK +#else +# define STATIC_CALLBACK static +#endif + +STATIC_CALLBACK void +readline_internal_setup () +{ + char *nprompt; + + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + if (rl_startup_hook) + (*rl_startup_hook) (); + + /* If we're not echoing, we still want to at least print a prompt, because + rl_redisplay will not do it for us. If the calling application has a + custom redisplay function, though, let that function handle it. */ + if (readline_echoing_p == 0 && rl_redisplay_function == rl_redisplay) + { + if (rl_prompt && rl_already_prompted == 0) + { + nprompt = _rl_strip_prompt (rl_prompt); + fprintf (_rl_out_stream, "%s", nprompt); + fflush (_rl_out_stream); + free (nprompt); + } + } + else + { + if (rl_prompt && rl_already_prompted) + rl_on_new_line_with_prompt (); + else + rl_on_new_line (); + (*rl_redisplay_function) (); + } + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_vi_insertion_mode (1, 0); +#endif /* VI_MODE */ + + if (rl_pre_input_hook) + (*rl_pre_input_hook) (); +} + +STATIC_CALLBACK char * +readline_internal_teardown (eof) + int eof; +{ + char *temp; + HIST_ENTRY *entry; + + /* Restore the original of this history line, iff the line that we + are editing was originally in the history, AND the line has changed. */ + entry = current_history (); + + if (entry && rl_undo_list) + { + temp = savestring (the_line); + rl_revert_line (1, 0); + entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL); + _rl_free_history_entry (entry); + + strcpy (the_line, temp); + free (temp); + } + + /* At any rate, it is highly likely that this line has an undo list. Get + rid of it now. */ + if (rl_undo_list) + rl_free_undo_list (); + + /* Restore normal cursor, if available. */ + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return (eof ? (char *)NULL : savestring (the_line)); +} + +STATIC_CALLBACK int +#if defined (READLINE_CALLBACKS) +readline_internal_char () +#else +readline_internal_charloop () +#endif +{ + static int lastc, eof_found; + int c, code, lk; + + lastc = -1; + eof_found = 0; + +#if !defined (READLINE_CALLBACKS) + while (rl_done == 0) + { +#endif + lk = _rl_last_command_was_kill; + + code = setjmp (readline_top_level); + + if (code) + (*rl_redisplay_function) (); + + if (rl_pending_input == 0) + { + /* Then initialize the argument and number of keys read. */ + _rl_init_argument (); + rl_key_sequence_length = 0; + } + + RL_SETSTATE(RL_STATE_READCMD); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_READCMD); + + /* EOF typed to a non-blank line is a . */ + if (c == EOF && rl_end) + c = NEWLINE; + + /* The character _rl_eof_char typed to blank line, and not as the + previous character is interpreted as EOF. */ + if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end) + { +#if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); + return (rl_done = 1); +#else + eof_found = 1; + break; +#endif + } + + lastc = c; + _rl_dispatch ((unsigned char)c, _rl_keymap); + + /* If there was no change in _rl_last_command_was_kill, then no kill + has taken place. Note that if input is pending we are reading + a prefix command, so nothing has changed yet. */ + 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 (); + +#if defined (READLINE_CALLBACKS) + return 0; +#else + } + + return (eof_found); +#endif +} + +#if defined (READLINE_CALLBACKS) +static int +readline_internal_charloop () +{ + int eof = 1; + + while (rl_done == 0) + eof = readline_internal_char (); + return (eof); +} +#endif /* READLINE_CALLBACKS */ + +/* Read a line of input from the global rl_instream, doing output on + the global rl_outstream. + If rl_prompt is non-null, then that is our prompt. */ +static char * +readline_internal () +{ + int eof; + + readline_internal_setup (); + eof = readline_internal_charloop (); + return (readline_internal_teardown (eof)); +} + +void +_rl_init_line_state () +{ + rl_point = rl_end = rl_mark = 0; + the_line = rl_line_buffer; + the_line[0] = 0; +} + +void +_rl_set_the_line () +{ + the_line = rl_line_buffer; +} + +/* 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. */ +int +_rl_dispatch (key, map) + register int key; + Keymap map; +{ + return _rl_dispatch_subseq (key, map, 0); +} + +int +_rl_dispatch_subseq (key, map, got_subseq) + register int key; + Keymap map; + int got_subseq; +{ + int r, newkey; + char *macro; + rl_command_func_t *func; + + if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + { + if (map[ESC].type == ISKMAP) + { + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (ESC); + map = FUNCTION_TO_KEYMAP (map, ESC); + key = UNMETA (key); + rl_key_sequence_length += 2; + return (_rl_dispatch (key, map)); + } + else + rl_ding (); + return 0; + } + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (key); + + r = 0; + switch (map[key].type) + { + case ISFUNC: + func = map[key].function; + if (func) + { + /* Special case rl_do_lowercase_version (). */ + if (func == rl_do_lowercase_version) + return (_rl_dispatch (_rl_to_lower (key), map)); + + 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); + RL_UNSETSTATE(RL_STATE_DISPATCHING); + rl_dispatching = 0; + + /* If we have input pending, then the last command was a prefix + command. Don't change the state of rl_last_func. Otherwise, + remember the last command executed in this variable. */ + if (rl_pending_input == 0 && map[key].function != rl_digit_argument) + rl_last_func = map[key].function; + } + else if (map[ANYOTHERKEY].function) + { + /* OK, there's no function bound in this map, but there is a + shadow function that was overridden when the current keymap + was created. Return -2 to note that. */ + _rl_unget_char (key); + return -2; + } + else if (got_subseq) + { + /* Return -1 to note that we're in a subsequence, but we don't + have a matching key, nor was one overridden. This means + we need to back up the recursion chain and find the last + subsequence that is bound to a function. */ + _rl_unget_char (key); + return -1; + } + else + { + _rl_abort_internal (); + return -1; + } + break; + + case ISKMAP: + if (map[key].function != 0) + { +#if defined (VI_MODE) + /* The only way this test will be true is if a subsequence has been + bound starting with ESC, generally the arrow keys. What we do is + check whether there's input in the queue, which there generally + will be if an arrow key has been pressed, and, if there's not, + just dispatch to (what we assume is) rl_vi_movement_mode right + away. This is essentially an input test with a zero timeout. */ + if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap + && _rl_input_queued (0) == 0) + return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); +#endif + + rl_key_sequence_length++; + + 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); + + 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; + } + } + else + { + _rl_abort_internal (); + return -1; + } + break; + + case ISMACR: + if (map[key].function != 0) + { + macro = savestring ((char *)map[key].function); + _rl_with_macro_input (macro); + return 0; + } + break; + } +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && + _rl_vi_textmod_command (key)) + _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); +#endif + return (r); +} + +/* **************************************************************** */ +/* */ +/* Initializations */ +/* */ +/* **************************************************************** */ + +/* Initialize readline (and terminal if not already). */ +int +rl_initialize () +{ + /* If we have never been called before, initialize the + terminal and data structures. */ + if (!rl_initialized) + { + RL_SETSTATE(RL_STATE_INITIALIZING); + readline_initialize_everything (); + RL_UNSETSTATE(RL_STATE_INITIALIZING); + rl_initialized++; + RL_SETSTATE(RL_STATE_INITIALIZED); + } + + /* Initalize the current line information. */ + _rl_init_line_state (); + + /* We aren't done yet. We haven't even gotten started yet! */ + rl_done = 0; + RL_UNSETSTATE(RL_STATE_DONE); + + /* Tell the history routines what is going on. */ + _rl_start_using_history (); + + /* Make the display buffer match the state of the line. */ + rl_reset_line_state (); + + /* No such function typed yet. */ + rl_last_func = (rl_command_func_t *)NULL; + + /* Parsing of key-bindings begins in an enabled state. */ + _rl_parsing_conditionalized_out = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + _rl_vi_initialize_line (); +#endif + + /* Each line starts in insert mode (the default). */ + _rl_set_insert_mode (RL_IM_DEFAULT, 1); + + return 0; +} + +#if 0 +#if defined (__EMX__) +static void +_emx_build_environ () +{ + TIB *tibp; + PIB *pibp; + char *t, **tp; + int c; + + DosGetInfoBlocks (&tibp, &pibp); + t = pibp->pib_pchenv; + for (c = 1; *t; c++) + t += strlen (t) + 1; + tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *)); + t = pibp->pib_pchenv; + while (*t) + { + *tp++ = t; + t += strlen (t) + 1; + } + *tp = 0; +} +#endif /* __EMX__ */ +#endif + +/* Initialize the entire state of the world. */ +static void +readline_initialize_everything () +{ +#if 0 +#if defined (__EMX__) + if (environ == 0) + _emx_build_environ (); +#endif +#endif + +#if 0 + /* Find out if we are running in Emacs -- UNUSED. */ + running_in_emacs = sh_get_env_value ("EMACS") != (char *)0; +#endif + + /* Set up input and output if they are not already set up. */ + if (!rl_instream) + rl_instream = stdin; + + if (!rl_outstream) + rl_outstream = stdout; + + /* Bind _rl_in_stream and _rl_out_stream immediately. These values + may change, but they may also be used before readline_internal () + is called. */ + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + /* Allocate data structures. */ + if (rl_line_buffer == 0) + rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); + + /* Initialize the terminal interface. */ + if (rl_terminal_name == 0) + rl_terminal_name = sh_get_env_value ("TERM"); + _rl_init_terminal_io (rl_terminal_name); + + /* Bind tty characters to readline functions. */ + readline_default_bindings (); + + /* Initialize the function names. */ + rl_initialize_funmap (); + + /* Decide whether we should automatically go into eight-bit mode. */ + _rl_init_eightbit (); + + /* Read in the init file. */ + rl_read_init_file ((char *)NULL); + + /* XXX */ + if (_rl_horizontal_scroll_mode && _rl_term_autowrap) + { + _rl_screenwidth--; + _rl_screenchars -= _rl_screenheight; + } + + /* Override the effect of any `set keymap' assignments in the + inputrc file. */ + rl_set_keymap_from_edit_mode (); + + /* Try to bind a common arrow key prefix, if not already bound. */ + bind_arrow_keys (); + + /* Enable the meta key, if this terminal has one. */ + if (_rl_enable_meta) + _rl_enable_meta_key (); + + /* 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; +} + +/* If this system allows us to look at the values of the regular + input editing characters, then bind them to their readline + equivalents, iff the characters are not bound to keymaps. */ +static void +readline_default_bindings () +{ + rl_tty_set_default_bindings (_rl_keymap); +} + +/* Bind some common arrow key sequences in MAP. */ +static void +bind_arrow_keys_internal (map) + Keymap map; +{ + Keymap xkeymap; + + xkeymap = _rl_keymap; + _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); +#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; +} + +/* Try and bind the common arrow key prefixes after giving termcap and + the inputrc file a chance to bind them and create `real' keymaps + for the arrow key prefix. */ +static void +bind_arrow_keys () +{ + bind_arrow_keys_internal (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_arrow_keys_internal (vi_movement_keymap); + bind_arrow_keys_internal (vi_insertion_keymap); +#endif +} + +/* **************************************************************** */ +/* */ +/* Saving and Restoring Readline's state */ +/* */ +/* **************************************************************** */ + +int +rl_save_state (sp) + struct readline_state *sp; +{ + if (sp == 0) + return -1; + + sp->point = rl_point; + sp->end = rl_end; + sp->mark = rl_mark; + sp->buffer = rl_line_buffer; + sp->buflen = rl_line_buffer_len; + sp->ul = rl_undo_list; + sp->prompt = rl_prompt; + + sp->rlstate = rl_readline_state; + sp->done = rl_done; + sp->kmap = _rl_keymap; + + sp->lastfunc = rl_last_func; + sp->insmode = rl_insert_mode; + sp->edmode = rl_editing_mode; + sp->kseqlen = rl_key_sequence_length; + sp->inf = rl_instream; + sp->outf = rl_outstream; + sp->pendingin = rl_pending_input; + sp->macro = rl_executing_macro; + + sp->catchsigs = rl_catch_signals; + sp->catchsigwinch = rl_catch_sigwinch; + + return (0); +} + +int +rl_restore_state (sp) + struct readline_state *sp; +{ + if (sp == 0) + return -1; + + rl_point = sp->point; + rl_end = sp->end; + rl_mark = sp->mark; + the_line = rl_line_buffer = sp->buffer; + rl_line_buffer_len = sp->buflen; + rl_undo_list = sp->ul; + rl_prompt = sp->prompt; + + rl_readline_state = sp->rlstate; + rl_done = sp->done; + _rl_keymap = sp->kmap; + + rl_last_func = sp->lastfunc; + rl_insert_mode = sp->insmode; + rl_editing_mode = sp->edmode; + rl_key_sequence_length = sp->kseqlen; + rl_instream = sp->inf; + rl_outstream = sp->outf; + rl_pending_input = sp->pendingin; + rl_executing_macro = sp->macro; + + rl_catch_signals = sp->catchsigs; + rl_catch_sigwinch = sp->catchsigwinch; + + return (0); +} diff --git a/readline-4.3.orig/readline.h b/readline-4.3.orig/readline.h new file mode 100644 index 0000000..f11b3d0 --- /dev/null +++ b/readline-4.3.orig/readline.h @@ -0,0 +1,799 @@ +/* Readline.h -- the names of functions callable from within readline. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_READLINE_H_) +#define _READLINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "rltypedefs.h" +# include "keymaps.h" +# include "tilde.h" +#else +# include +# include +# include +# include +#endif + +/* Hex-encoded Readline version number. */ +#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */ +#define RL_VERSION_MAJOR 4 +#define RL_VERSION_MINOR 3 + +/* Readline data structures. */ + +/* Maintaining the state of undo. We remember individual deletes and inserts + on a chain of things to do. */ + +/* The actions that undo knows how to undo. Notice that UNDO_DELETE means + to insert some text, and UNDO_INSERT means to delete some text. I.e., + the code tells undo what to undo, not how to undo it. */ +enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + +/* What an element of THE_UNDO_LIST looks like. */ +typedef struct undo_list { + struct undo_list *next; + int start, end; /* Where the change took place. */ + char *text; /* The text to insert, if undoing a delete. */ + enum undo_code what; /* Delete, Insert, Begin, End. */ +} UNDO_LIST; + +/* The current undo list for RL_LINE_BUFFER. */ +extern UNDO_LIST *rl_undo_list; + +/* The data structure for mapping textual names to code addresses. */ +typedef struct _funmap { + const char *name; + rl_command_func_t *function; +} FUNMAP; + +extern FUNMAP **funmap; + +/* **************************************************************** */ +/* */ +/* Functions available to bind to key sequences */ +/* */ +/* **************************************************************** */ + +/* Bindable commands for numeric arguments. */ +extern int rl_digit_argument PARAMS((int, int)); +extern int rl_universal_argument PARAMS((int, int)); + +/* Bindable commands for moving the cursor. */ +extern int rl_forward_byte PARAMS((int, int)); +extern int rl_forward_char PARAMS((int, int)); +extern int rl_forward PARAMS((int, int)); +extern int rl_backward_byte PARAMS((int, int)); +extern int rl_backward_char PARAMS((int, int)); +extern int rl_backward PARAMS((int, int)); +extern int rl_beg_of_line PARAMS((int, int)); +extern int rl_end_of_line PARAMS((int, int)); +extern int rl_forward_word PARAMS((int, int)); +extern int rl_backward_word PARAMS((int, int)); +extern int rl_refresh_line PARAMS((int, int)); +extern int rl_clear_screen PARAMS((int, int)); +extern int rl_arrow_keys PARAMS((int, int)); + +/* Bindable commands for inserting and deleting text. */ +extern int rl_insert PARAMS((int, int)); +extern int rl_quoted_insert PARAMS((int, int)); +extern int rl_tab_insert PARAMS((int, int)); +extern int rl_newline PARAMS((int, int)); +extern int rl_do_lowercase_version PARAMS((int, int)); +extern int rl_rubout PARAMS((int, int)); +extern int rl_delete PARAMS((int, int)); +extern int rl_rubout_or_delete PARAMS((int, int)); +extern int rl_delete_horizontal_space PARAMS((int, int)); +extern int rl_delete_or_show_completions PARAMS((int, int)); +extern int rl_insert_comment PARAMS((int, int)); + +/* Bindable commands for changing case. */ +extern int rl_upcase_word PARAMS((int, int)); +extern int rl_downcase_word PARAMS((int, int)); +extern int rl_capitalize_word PARAMS((int, int)); + +/* Bindable commands for transposing characters and words. */ +extern int rl_transpose_words PARAMS((int, int)); +extern int rl_transpose_chars PARAMS((int, int)); + +/* Bindable commands for searching within a line. */ +extern int rl_char_search PARAMS((int, int)); +extern int rl_backward_char_search PARAMS((int, int)); + +/* Bindable commands for readline's interface to the command history. */ +extern int rl_beginning_of_history PARAMS((int, int)); +extern int rl_end_of_history PARAMS((int, int)); +extern int rl_get_next_history PARAMS((int, int)); +extern int rl_get_previous_history PARAMS((int, int)); + +/* Bindable commands for managing the mark and region. */ +extern int rl_set_mark PARAMS((int, int)); +extern int rl_exchange_point_and_mark PARAMS((int, int)); + +/* Bindable commands to set the editing mode (emacs or vi). */ +extern int rl_vi_editing_mode PARAMS((int, int)); +extern int rl_emacs_editing_mode PARAMS((int, int)); + +/* Bindable commands to change the insert mode (insert or overwrite) */ +extern int rl_overwrite_mode PARAMS((int, int)); + +/* Bindable commands for managing key bindings. */ +extern int rl_re_read_init_file PARAMS((int, int)); +extern int rl_dump_functions PARAMS((int, int)); +extern int rl_dump_macros PARAMS((int, int)); +extern int rl_dump_variables PARAMS((int, int)); + +/* Bindable commands for word completion. */ +extern int rl_complete PARAMS((int, int)); +extern int rl_possible_completions PARAMS((int, int)); +extern int rl_insert_completions PARAMS((int, int)); +extern int rl_menu_complete PARAMS((int, int)); + +/* Bindable commands for killing and yanking text, and managing the kill ring. */ +extern int rl_kill_word PARAMS((int, int)); +extern int rl_backward_kill_word PARAMS((int, int)); +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_line_discard PARAMS((int, int)); +extern int rl_copy_region_to_kill PARAMS((int, int)); +extern int rl_kill_region PARAMS((int, int)); +extern int rl_copy_forward_word PARAMS((int, int)); +extern int rl_copy_backward_word PARAMS((int, int)); +extern int rl_yank PARAMS((int, int)); +extern int rl_yank_pop PARAMS((int, int)); +extern int rl_yank_nth_arg PARAMS((int, int)); +extern int rl_yank_last_arg PARAMS((int, int)); +/* Not available unless __CYGWIN__ is defined. */ +#ifdef __CYGWIN__ +extern int rl_paste_from_clipboard PARAMS((int, int)); +#endif + +/* Bindable commands for incremental searching. */ +extern int rl_reverse_search_history PARAMS((int, int)); +extern int rl_forward_search_history PARAMS((int, int)); + +/* Bindable keyboard macro commands. */ +extern int rl_start_kbd_macro PARAMS((int, int)); +extern int rl_end_kbd_macro PARAMS((int, int)); +extern int rl_call_last_kbd_macro PARAMS((int, int)); + +/* Bindable undo commands. */ +extern int rl_revert_line PARAMS((int, int)); +extern int rl_undo_command PARAMS((int, int)); + +/* Bindable tilde expansion commands. */ +extern int rl_tilde_expand PARAMS((int, int)); + +/* Bindable terminal control commands. */ +extern int rl_restart_output PARAMS((int, int)); +extern int rl_stop_output PARAMS((int, int)); + +/* Miscellaneous bindable commands. */ +extern int rl_abort PARAMS((int, int)); +extern int rl_tty_status PARAMS((int, int)); + +/* Bindable commands for incremental and non-incremental history searching. */ +extern int rl_history_search_forward PARAMS((int, int)); +extern int rl_history_search_backward PARAMS((int, int)); +extern int rl_noninc_forward_search PARAMS((int, int)); +extern int rl_noninc_reverse_search PARAMS((int, int)); +extern int rl_noninc_forward_search_again PARAMS((int, int)); +extern int rl_noninc_reverse_search_again PARAMS((int, int)); + +/* Bindable command used when inserting a matching close character. */ +extern int rl_insert_close PARAMS((int, int)); + +/* Not available unless READLINE_CALLBACKS is defined. */ +extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *)); +extern void rl_callback_read_char PARAMS((void)); +extern void rl_callback_handler_remove PARAMS((void)); + +/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ +/* VI-mode bindable commands. */ +extern int rl_vi_redo PARAMS((int, int)); +extern int rl_vi_undo PARAMS((int, int)); +extern int rl_vi_yank_arg PARAMS((int, int)); +extern int rl_vi_fetch_history PARAMS((int, int)); +extern int rl_vi_search_again PARAMS((int, int)); +extern int rl_vi_search PARAMS((int, int)); +extern int rl_vi_complete PARAMS((int, int)); +extern int rl_vi_tilde_expand PARAMS((int, int)); +extern int rl_vi_prev_word PARAMS((int, int)); +extern int rl_vi_next_word PARAMS((int, int)); +extern int rl_vi_end_word PARAMS((int, int)); +extern int rl_vi_insert_beg PARAMS((int, int)); +extern int rl_vi_append_mode PARAMS((int, int)); +extern int rl_vi_append_eol PARAMS((int, int)); +extern int rl_vi_eof_maybe PARAMS((int, int)); +extern int rl_vi_insertion_mode PARAMS((int, int)); +extern int rl_vi_movement_mode PARAMS((int, int)); +extern int rl_vi_arg_digit PARAMS((int, int)); +extern int rl_vi_change_case PARAMS((int, int)); +extern int rl_vi_put PARAMS((int, int)); +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_delete PARAMS((int, int)); +extern int rl_vi_back_to_indent PARAMS((int, int)); +extern int rl_vi_first_print PARAMS((int, int)); +extern int rl_vi_char_search PARAMS((int, int)); +extern int rl_vi_match PARAMS((int, int)); +extern int rl_vi_change_char PARAMS((int, int)); +extern int rl_vi_subst PARAMS((int, int)); +extern int rl_vi_overstrike PARAMS((int, int)); +extern int rl_vi_overstrike_delete PARAMS((int, int)); +extern int rl_vi_replace PARAMS((int, int)); +extern int rl_vi_set_mark PARAMS((int, int)); +extern int rl_vi_goto_mark PARAMS((int, int)); + +/* VI-mode utility functions. */ +extern int rl_vi_check PARAMS((void)); +extern int rl_vi_domove PARAMS((int, int *)); +extern int rl_vi_bracktype PARAMS((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)); +extern int rl_vi_eWord PARAMS((int, int)); +extern int rl_vi_fword PARAMS((int, int)); +extern int rl_vi_bword PARAMS((int, int)); +extern int rl_vi_eword PARAMS((int, int)); + +/* **************************************************************** */ +/* */ +/* Well Published Functions */ +/* */ +/* **************************************************************** */ + +/* Readline functions. */ +/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ +extern char *readline PARAMS((const char *)); + +extern int rl_set_prompt PARAMS((const char *)); +extern int rl_expand_prompt PARAMS((char *)); + +extern int rl_initialize PARAMS((void)); + +/* Undocumented; unused by readline */ +extern int rl_discard_argument PARAMS((void)); + +/* Utility functions to bind keys to readline commands. */ +extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int)); +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_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_generic_bind PARAMS((int, const char *, char *, Keymap)); +extern int rl_variable_bind PARAMS((const char *, const char *)); + +/* Backwards compatibility, use rl_generic_bind instead. */ +extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); + +/* Undocumented in the texinfo manual; not really useful to programs. */ +extern int rl_translate_keyseq PARAMS((const char *, char *, int *)); +extern char *rl_untranslate_keyseq PARAMS((int)); + +extern rl_command_func_t *rl_named_function PARAMS((const char *)); +extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *)); + +extern void rl_list_funmap_names PARAMS((void)); +extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap)); +extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *)); + +extern void rl_function_dumper PARAMS((int)); +extern void rl_macro_dumper PARAMS((int)); +extern void rl_variable_dumper PARAMS((int)); + +extern int rl_read_init_file PARAMS((const char *)); +extern int rl_parse_and_bind PARAMS((char *)); + +/* Functions for manipulating keymaps. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); +extern Keymap rl_copy_keymap PARAMS((Keymap)); +extern Keymap rl_make_keymap PARAMS((void)); +extern void rl_discard_keymap PARAMS((Keymap)); + +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); +extern char *rl_get_keymap_name PARAMS((Keymap)); +extern void rl_set_keymap PARAMS((Keymap)); +extern Keymap rl_get_keymap PARAMS((void)); +/* Undocumented; used internally only. */ +extern void rl_set_keymap_from_edit_mode PARAMS((void)); +extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); + +/* Functions for manipulating the funmap, which maps command names to functions. */ +extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); +extern const char **rl_funmap_names PARAMS((void)); +/* Undocumented, only used internally -- there is only one funmap, and this + function may be called only once. */ +extern void rl_initialize_funmap PARAMS((void)); + +/* Utility functions for managing keyboard macros. */ +extern void rl_push_macro_input PARAMS((char *)); + +/* Functions for undoing, from undo.c */ +extern void rl_add_undo PARAMS((enum undo_code, int, int, char *)); +extern void rl_free_undo_list PARAMS((void)); +extern int rl_do_undo PARAMS((void)); +extern int rl_begin_undo_group PARAMS((void)); +extern int rl_end_undo_group PARAMS((void)); +extern int rl_modifying PARAMS((int, int)); + +/* Functions for redisplay. */ +extern void rl_redisplay PARAMS((void)); +extern int rl_on_new_line PARAMS((void)); +extern int rl_on_new_line_with_prompt PARAMS((void)); +extern int rl_forced_update_display PARAMS((void)); +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) +extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +extern int rl_message (); +#endif + +extern int rl_show_char PARAMS((int)); + +/* Undocumented in texinfo manual. */ +extern int rl_character_len PARAMS((int, int)); + +/* Save and restore internal prompt redisplay information. */ +extern void rl_save_prompt PARAMS((void)); +extern void rl_restore_prompt PARAMS((void)); + +/* Modifying text. */ +extern void rl_replace_line PARAMS((const char *, int)); +extern int rl_insert_text PARAMS((const char *)); +extern int rl_delete_text PARAMS((int, int)); +extern int rl_kill_text PARAMS((int, int)); +extern char *rl_copy_text PARAMS((int, int)); + +/* Terminal and tty mode management. */ +extern void rl_prep_terminal PARAMS((int)); +extern void rl_deprep_terminal PARAMS((void)); +extern void rl_tty_set_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 char *rl_get_termcap PARAMS((const char *)); + +/* Functions for character input. */ +extern int rl_stuff_char PARAMS((int)); +extern int rl_execute_next PARAMS((int)); +extern int rl_clear_pending_input PARAMS((void)); +extern int rl_read_key PARAMS((void)); +extern int rl_getc PARAMS((FILE *)); +extern int rl_set_keyboard_input_timeout PARAMS((int)); + +/* `Public' utility functions . */ +extern void rl_extend_line_buffer PARAMS((int)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); + +/* Readline signal handling, from signals.c */ +extern int rl_set_signals PARAMS((void)); +extern int rl_clear_signals PARAMS((void)); +extern void rl_cleanup_after_signal PARAMS((void)); +extern void rl_reset_after_signal PARAMS((void)); +extern void rl_free_line_state PARAMS((void)); + +extern int rl_set_paren_blink_timeout PARAMS((int)); + +/* Undocumented. */ +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +/* Completion functions. */ +extern int rl_complete_internal PARAMS((int)); +extern void rl_display_match_list PARAMS((char **, int, int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +extern int rl_completion_mode PARAMS((rl_command_func_t *)); + +#if 0 +/* Backwards compatibility (compat.c). These will go away sometime. */ +extern void free_undo_list PARAMS((void)); +extern int maybe_save_line PARAMS((void)); +extern int maybe_unsave_line PARAMS((void)); +extern int maybe_replace_line PARAMS((void)); + +extern int ding PARAMS((void)); +extern int alphabetic PARAMS((int)); +extern int crlf PARAMS((void)); + +extern char **completion_matches PARAMS((char *, rl_compentry_func_t *)); +extern char *username_completion_function PARAMS((const char *, int)); +extern char *filename_completion_function PARAMS((const char *, int)); +#endif + +/* **************************************************************** */ +/* */ +/* Well Published Variables */ +/* */ +/* **************************************************************** */ + +/* The version of this incarnation of the readline library. */ +extern const char *rl_library_version; /* e.g., "4.2" */ +extern int rl_readline_version; /* e.g., 0x0402 */ + +/* True if this is real GNU readline. */ +extern int rl_gnu_readline_p; + +/* Flags word encapsulating the current readline state. */ +extern int rl_readline_state; + +/* Says which editing mode readline is currently using. 1 means emacs mode; + 0 means vi mode. */ +extern int rl_editing_mode; + +/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means + overwrite mode. Reset to insert mode on each input line. */ +extern int rl_insert_mode; + +/* The name of the calling program. You should initialize this to + whatever was in argv[0]. It is used when parsing conditionals. */ +extern const char *rl_readline_name; + +/* The prompt readline uses. This is set from the argument to + readline (), and should not be assigned to directly. */ +extern char *rl_prompt; + +/* The line buffer that is in use. */ +extern char *rl_line_buffer; + +/* The location of point, and end. */ +extern int rl_point; +extern int rl_end; + +/* The mark, or saved cursor position. */ +extern int rl_mark; + +/* Flag to indicate that readline has finished with the current input + line and should return it. */ +extern int rl_done; + +/* If set to a character value, that will be the next keystroke read. */ +extern int rl_pending_input; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +extern int rl_dispatching; + +/* Non-zero if the user typed a numeric argument before executing the + current function. */ +extern int rl_explicit_arg; + +/* The current value of the numeric argument specified by the user. */ +extern int rl_numeric_arg; + +/* The address of the last command function Readline executed. */ +extern rl_command_func_t *rl_last_func; + +/* The name of the terminal to use. */ +extern const char *rl_terminal_name; + +/* The input and output streams. */ +extern FILE *rl_instream; +extern FILE *rl_outstream; + +/* 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; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +extern rl_hook_func_t *rl_pre_input_hook; + +/* The address of a function to call periodically while Readline is + awaiting character input, or NULL, for no event handling. */ +extern rl_hook_func_t *rl_event_hook; + +/* The address of the function to call to fetch a character from the current + Readline input stream */ +extern rl_getc_func_t *rl_getc_function; + +extern rl_voidfunc_t *rl_redisplay_function; + +extern rl_vintfunc_t *rl_prep_term_function; +extern rl_voidfunc_t *rl_deprep_term_function; + +/* Dispatch variables. */ +extern Keymap rl_executing_keymap; +extern Keymap rl_binding_keymap; + +/* Display variables. */ +/* If non-zero, readline will erase the entire line, including any prompt, + if the only thing typed on an otherwise-blank line is something bound to + rl_newline. */ +extern int rl_erase_empty_line; + +/* If non-zero, the application has already printed the prompt (rl_prompt) + before calling readline, so readline should not output it the first time + redisplay is done. */ +extern int rl_already_prompted; + +/* A non-zero value means to read only this many characters rather than + up to a character bound to accept-line. */ +extern int rl_num_chars_to_read; + +/* The text of a currently-executing keyboard macro. */ +extern char *rl_executing_macro; + +/* Variables to control readline signal handling. */ +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +extern int rl_catch_signals; + +/* If non-zero, readline will install a signal handler for SIGWINCH + that also attempts to call any calling application's SIGWINCH signal + handler. Note that the terminal is not cleaned up before the + application's signal handler is called; use rl_cleanup_after_signal() + to do that. */ +extern int rl_catch_sigwinch; + +/* Completion variables. */ +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default + filename completer. */ +extern rl_compentry_func_t *rl_completion_entry_function; + +/* If rl_ignore_some_completions_function is non-NULL it is the address + of a function to call after all of the possible matches have been + generated, but before the actual completion is done to the input line. + The function is called with one argument; a NULL terminated array + of (char *). If your function removes any of the elements, they + must be free()'ed. */ +extern rl_compignore_func_t *rl_ignore_some_completions_function; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +extern rl_completion_func_t *rl_attempted_completion_function; + +/* The basic list of characters that signal a break between words for the + completer routine. The initial contents of this variable is what + breaks words in the shell, i.e. "n\"\\'`@$>". */ +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; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +extern const char *rl_completer_quote_characters; + +/* List of quote characters which cause a word break. */ +extern const char *rl_basic_quote_characters; + +/* List of characters that need to be quoted in filenames by the completer. */ +extern const char *rl_filename_quote_characters; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +extern const char *rl_special_prefixes; + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. It + changes what is displayed when the possible completions are printed + or inserted. */ +extern rl_icppfunc_t *rl_directory_completion_hook; + +/* If non-zero, this is the address of a function to call when completing + a directory name. This function takes the address of the directory name + to be modified as an argument. Unlike rl_directory_completion_hook, it + only modifies the directory name used in opendir(2), not what is displayed + when the possible completions are printed or inserted. It is called + before rl_directory_completion_hook. I'm not happy with how this works + yet, so it's undocumented. */ +extern rl_icppfunc_t *rl_directory_rewrite_hook; + +/* Backwards compatibility with previous versions of readline. */ +#define rl_symbolic_link_hook rl_directory_completion_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 instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +extern rl_compdisp_func_t *rl_completion_display_matches_hook; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +extern int rl_filename_completion_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 + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +extern int rl_filename_quoting_desired; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +extern rl_quote_func_t *rl_filename_quoting_function; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. */ +extern rl_dequote_func_t *rl_filename_dequoting_function; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +extern rl_linebuf_func_t *rl_char_is_quoted_p; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +extern int rl_attempted_completion_over; + +/* Set to a character describing the type of completion being attempted by + rl_complete_internal; available for use by application completion + functions. */ +extern int rl_completion_type; + +/* 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; + +/* If set to non-zero by an application completion function, + 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; + +/* 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 + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +extern int rl_completion_mark_symlink_dirs; + +/* If non-zero, then disallow duplicates in the matches. */ +extern int rl_ignore_completion_duplicates; + +/* If this is non-zero, completion is (temporarily) inhibited, and the + completion character will be inserted as any other. */ +extern int rl_inhibit_completion; + +/* Definitions available for use by readline clients. */ +#define RL_PROMPT_START_IGNORE '\001' +#define RL_PROMPT_END_IGNORE '\002' + +/* Possible values for do_replace argument to rl_filename_quoting_function, + called by rl_complete_internal. */ +#define NO_MATCH 0 +#define SINGLE_MATCH 1 +#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_SETSTATE(x) (rl_readline_state |= (x)) +#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) +#define RL_ISSTATE(x) (rl_readline_state & (x)) + +struct readline_state { + /* line state */ + int point; + int end; + int mark; + char *buffer; + int buflen; + UNDO_LIST *ul; + char *prompt; + + /* global state */ + int rlstate; + int done; + Keymap kmap; + + /* input state */ + rl_command_func_t *lastfunc; + int insmode; + int edmode; + int kseqlen; + FILE *inf; + FILE *outf; + int pendingin; + char *macro; + + /* signal state */ + int catchsigs; + int catchsigwinch; + + /* reserved for future expansion, so the struct size doesn't change */ + char reserved[64]; +}; + +extern int rl_save_state PARAMS((struct readline_state *)); +extern int rl_restore_state PARAMS((struct readline_state *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _READLINE_H_ */ diff --git a/readline-4.3.orig/rlconf.h b/readline-4.3.orig/rlconf.h new file mode 100644 index 0000000..c651fd8 --- /dev/null +++ b/readline-4.3.orig/rlconf.h @@ -0,0 +1,60 @@ +/* rlconf.h -- readline configuration definitions */ + +/* Copyright (C) 1994 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLCONF_H_) +#define _RLCONF_H_ + +/* Define this if you want the vi-mode editing available. */ +#define VI_MODE + +/* Define this to get an indication of file type when listing completions. */ +#define VISIBLE_STATS + +/* This definition is needed by readline.c, rltty.c, and signals.c. */ +/* If on, then readline handles signals in a way that doesn't screw. */ +#define HANDLE_SIGNALS + +/* Ugly but working hack for binding prefix meta. */ +#define PREFIX_META_HACK + +/* The final, last-ditch effort file name for an init file. */ +#define DEFAULT_INPUTRC "~/.inputrc" + +/* If defined, expand tabs to spaces. */ +#define DISPLAY_TABS + +/* If defined, use the terminal escape sequence to move the cursor forward + over a character when updating the line rather than rewriting it. */ +/* #define HACK_TERMCAP_MOTION */ + +/* The string inserted by the `insert comment' command. */ +#define RL_COMMENT_BEGIN_DEFAULT "#" + +/* Define this if you want code that allows readline to be used in an + X `callback' style. */ +#define READLINE_CALLBACKS + +/* Define this if you want the cursor to indicate insert or overwrite mode. */ +/* #define CURSOR_MODE */ + +#endif /* _RLCONF_H_ */ diff --git a/readline-4.3.orig/rldefs.h b/readline-4.3.orig/rldefs.h new file mode 100644 index 0000000..4a28bd1 --- /dev/null +++ b/readline-4.3.orig/rldefs.h @@ -0,0 +1,156 @@ +/* rldefs.h -- an attempt to isolate some of the system-specific defines + 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. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLDEFS_H_) +#define _RLDEFS_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include "rlstdc.h" + +#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 +# endif +#endif + +/* Posix macro to check file in statbuf for directory-ness. + This requires that be included before this test. */ +#if defined (S_IFDIR) && !defined (S_ISDIR) +# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif + +/* Decide which flavor of the header file describing the C library + string functions to include and include it. */ + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#if defined (PREFER_STDARG) +# include +#else +# if defined (PREFER_VARARGS) +# include +# endif +#endif + +#if defined (HAVE_STRCASECMP) +#define _rl_stricmp strcasecmp +#define _rl_strnicmp strncasecmp +#else +extern int _rl_stricmp PARAMS((char *, char *)); +extern int _rl_strnicmp PARAMS((char *, char *, int)); +#endif + +#if defined (HAVE_STRPBRK) +# define _rl_strpbrk(a,b) strpbrk((a),(b)) +#else +extern char *_rl_strpbrk PARAMS((const char *, const char *)); +#endif + +#if !defined (emacs_mode) +# define no_mode -1 +# define vi_mode 0 +# define emacs_mode 1 +#endif + +#if !defined (RL_IM_INSERT) +# define RL_IM_INSERT 1 +# define RL_IM_OVERWRITE 0 +# +# define RL_IM_DEFAULT RL_IM_INSERT +#endif + +/* If you cast map[key].function to type (Keymap) on a Cray, + the compiler takes the value of map[key].function and + divides it by 4 to convert between pointer types (pointers + to functions and pointers to structs are different sizes). + This is not what is wanted. */ +#if defined (CRAY) +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data)) +#else +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data) +#endif + +#ifndef savestring +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif + +/* Possible values for _rl_bell_preference. */ +#define NO_BELL 0 +#define AUDIBLE_BELL 1 +#define VISIBLE_BELL 2 + +/* Definitions used when searching the line for characters. */ +/* NOTE: it is necessary that opposite directions are inverses */ +#define FTO 1 /* forward to */ +#define BTO -1 /* backward to */ +#define FFIND 2 /* forward find */ +#define BFIND -2 /* backward find */ + +/* Possible values for the found_quote flags word used by the completion + functions. It says what kind of (shell-like) quoting we found anywhere + in the line. */ +#define RL_QF_SINGLE_QUOTE 0x01 +#define RL_QF_DOUBLE_QUOTE 0x02 +#define RL_QF_BACKSLASH 0x04 +#define RL_QF_OTHER_QUOTE 0x08 + +/* Default readline line buffer length. */ +#define DEFAULT_BUFFER_SIZE 256 + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#if !defined (FREE) +# define FREE(x) if (x) free (x) +#endif + +#if !defined (SWAP) +# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) +#endif + +/* CONFIGURATION SECTION */ +#include "rlconf.h" + +#endif /* !_RLDEFS_H_ */ diff --git a/readline-4.3.orig/rlmbutil.h b/readline-4.3.orig/rlmbutil.h new file mode 100644 index 0000000..27ca32b --- /dev/null +++ b/readline-4.3.orig/rlmbutil.h @@ -0,0 +1,108 @@ +/* rlmbutil.h -- utility functions for multibyte characters. */ + +/* Copyright (C) 2001 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_MBUTIL_H_) +#define _RL_MBUTIL_H_ + +#include "rlstdc.h" + +/************************************************/ +/* check multibyte capability for I18N code */ +/************************************************/ + +/* For platforms which support the ISO C amendement 1 functionality we + support user defined character classes. */ + /* Solaris 2.5 has a bug: must be included before . */ +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) +# include +# include +# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */ +# define HANDLE_MULTIBYTE 1 +# endif +#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 +# include +# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) +# undef MB_LEN_MAX +# endif +# if !defined (MB_LEN_MAX) +# define MB_LEN_MAX 16 +# endif +#endif + +/************************************************/ +/* end of multibyte capability checks for I18N */ +/************************************************/ + +/* + * Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar: + * + * MB_FIND_ANY find any multibyte character + * MB_FIND_NONZERO find a non-zero-width multibyte character + */ + +#define MB_FIND_ANY 0x00 +#define MB_FIND_NONZERO 0x01 + +extern int _rl_find_prev_mbchar PARAMS((char *, int, int)); +extern int _rl_find_next_mbchar PARAMS((char *, int, int, int)); + +#ifdef HANDLE_MULTIBYTE + +extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *)); +extern int _rl_get_char_len PARAMS((char *, mbstate_t *)); +extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *)); + +extern int _rl_read_mbchar PARAMS((char *, int)); +extern int _rl_read_mbstring PARAMS((int, char *, int)); + +extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); + +#else /* !HANDLE_MULTIBYTE */ + +#undef MB_LEN_MAX +#undef MB_CUR_MAX + +#define MB_LEN_MAX 1 +#define MB_CUR_MAX 1 + +#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1)) +#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2)) + +#endif /* !HANDLE_MULTIBYTE */ + +extern int rl_byte_oriented; + +#endif /* _RL_MBUTIL_H_ */ diff --git a/readline-4.3.orig/rlprivate.h b/readline-4.3.orig/rlprivate.h new file mode 100644 index 0000000..ccb9144 --- /dev/null +++ b/readline-4.3.orig/rlprivate.h @@ -0,0 +1,284 @@ +/* rlprivate.h -- functions and variables global to the readline library, + but not intended for use by applications. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_PRIVATE_H_) +#define _RL_PRIVATE_H_ + +#include "rlconf.h" /* for VISIBLE_STATS */ +#include "rlstdc.h" +#include "posixjmp.h" /* defines procenv_t */ + +/************************************************************************* + * * + * Global functions undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/************************************************************************* + * * + * Global variables undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/* complete.c */ +extern int rl_complete_with_tilde_expansion; +#if defined (VISIBLE_STATS) +extern int rl_visible_stats; +#endif /* VISIBLE_STATS */ + +/* readline.c */ +extern int rl_line_buffer_len; +extern int rl_arg_sign; +extern int rl_visible_prompt_length; +extern int readline_echoing_p; +extern int rl_key_sequence_length; +extern int rl_byte_oriented; + +/* display.c */ +extern int rl_display_fixed; + +/* parens.c */ +extern int rl_blink_matching_paren; + +/************************************************************************* + * * + * Global functions and variables unsed and undocumented * + * * + *************************************************************************/ + +/* kill.c */ +extern int rl_set_retained_kills PARAMS((int)); + +/* terminal.c */ +extern void _rl_set_screen_size PARAMS((int, int)); + +/* undo.c */ +extern int _rl_fix_last_undo_of_type PARAMS((int, int, int)); + +/* util.c */ +extern char *_rl_savestring PARAMS((const char *)); + +/************************************************************************* + * * + * Functions and variables private to the readline library * + * * + *************************************************************************/ + +/* NOTE: Functions and variables prefixed with `_rl_' are + pseudo-global: they are global so they can be shared + between files in the readline library, but are not intended + to be visible to readline callers. */ + +/************************************************************************* + * Undocumented private functions * + *************************************************************************/ + +#if defined(READLINE_CALLBACKS) + +/* readline.c */ +extern void readline_internal_setup PARAMS((void)); +extern char *readline_internal_teardown PARAMS((int)); +extern int readline_internal_char PARAMS((void)); + +#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 *)); +extern void _rl_free_match_list PARAMS((char **)); + +/* display.c */ +extern char *_rl_strip_prompt PARAMS((char *)); +extern void _rl_move_cursor_relative PARAMS((int, const char *)); +extern void _rl_move_vert PARAMS((int)); +extern void _rl_save_prompt PARAMS((void)); +extern void _rl_restore_prompt PARAMS((void)); +extern char *_rl_make_prompt_for_search PARAMS((int)); +extern void _rl_erase_at_end_of_line PARAMS((int)); +extern void _rl_clear_to_eol PARAMS((int)); +extern void _rl_clear_screen PARAMS((void)); +extern void _rl_update_final PARAMS((void)); +extern void _rl_redisplay_after_sigwinch PARAMS((void)); +extern void _rl_clean_up_for_exit PARAMS((void)); +extern void _rl_erase_entire_line PARAMS((void)); +extern int _rl_current_display_line PARAMS((void)); + +/* input.c */ +extern int _rl_any_typein PARAMS((void)); +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)); + +/* macro.c */ +extern void _rl_with_macro_input PARAMS((char *)); +extern int _rl_next_macro_key PARAMS((void)); +extern void _rl_push_executing_macro PARAMS((void)); +extern void _rl_pop_executing_macro PARAMS((void)); +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 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)); + +/* nls.c */ +extern int _rl_init_eightbit PARAMS((void)); + +/* parens.c */ +extern void _rl_enable_paren_matching PARAMS((int)); + +/* readline.c */ +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)); + +/* rltty.c */ +extern int _rl_disable_tty_signals PARAMS((void)); +extern int _rl_restore_tty_signals PARAMS((void)); + +/* terminal.c */ +extern void _rl_get_screen_size PARAMS((int, int)); +extern int _rl_init_terminal_io PARAMS((const char *)); +#ifdef _MINIX +extern void _rl_output_character_function PARAMS((int)); +#else +extern int _rl_output_character_function PARAMS((int)); +#endif +extern void _rl_output_some_chars PARAMS((const char *, int)); +extern int _rl_backspace PARAMS((int)); +extern void _rl_enable_meta_key PARAMS((void)); +extern void _rl_control_keypad PARAMS((int)); +extern void _rl_set_cursor PARAMS((int, int)); + +/* text.c */ +extern void _rl_fix_point PARAMS((int)); +extern int _rl_replace_text PARAMS((const char *, int, int)); +extern int _rl_insert_char PARAMS((int, int)); +extern int _rl_overwrite_char PARAMS((int, int)); +extern int _rl_overwrite_rubout PARAMS((int, int)); +extern int _rl_rubout_char PARAMS((int, int)); +#if defined (HANDLE_MULTIBYTE) +extern int _rl_char_search_internal PARAMS((int, int, char *, int)); +#else +extern int _rl_char_search_internal PARAMS((int, int, int)); +#endif +extern int _rl_set_mark_at_pos PARAMS((int)); + +/* util.c */ +extern int _rl_abort_internal PARAMS((void)); +extern char *_rl_strindex PARAMS((const char *, const char *)); +extern int _rl_qsort_string_compare PARAMS((char **, char **)); +extern int (_rl_uppercase_p) PARAMS((int)); +extern int (_rl_lowercase_p) PARAMS((int)); +extern int (_rl_pure_alphabetic) PARAMS((int)); +extern int (_rl_digit_p) PARAMS((int)); +extern int (_rl_to_lower) PARAMS((int)); +extern int (_rl_to_upper) PARAMS((int)); +extern int (_rl_digit_value) PARAMS((int)); + +/* vi_mode.c */ +extern void _rl_vi_initialize_line PARAMS((void)); +extern void _rl_vi_reset_last PARAMS((void)); +extern void _rl_vi_set_last PARAMS((int, int, int)); +extern int _rl_vi_textmod_command PARAMS((int)); +extern void _rl_vi_done_inserting PARAMS((void)); + +/************************************************************************* + * Undocumented private variables * + *************************************************************************/ + +/* bind.c */ +extern const char *_rl_possible_control_prefixes[]; +extern const char *_rl_possible_meta_prefixes[]; + +/* complete.c */ +extern int _rl_complete_show_all; +extern int _rl_complete_mark_directories; +extern int _rl_complete_mark_symlink_dirs; +extern int _rl_print_completions_horizontally; +extern int _rl_completion_case_fold; +extern int _rl_match_hidden_files; +extern int _rl_page_completions; + +/* display.c */ +extern int _rl_vis_botlin; +extern int _rl_last_c_pos; +extern int _rl_suppress_redisplay; +extern char *rl_display_prompt; + +/* isearch.c */ +extern char *_rl_isearch_terminators; + +/* macro.c */ +extern char *_rl_executing_macro; + +/* misc.c */ +extern int _rl_history_preserve_point; +extern int _rl_history_saved_point; + +/* readline.c */ +extern int _rl_horizontal_scroll_mode; +extern int _rl_mark_modified_lines; +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 char *_rl_comment_begin; +extern unsigned char _rl_parsing_conditionalized_out; +extern Keymap _rl_keymap; +extern FILE *_rl_in_stream; +extern FILE *_rl_out_stream; +extern int _rl_last_command_was_kill; +extern int _rl_eof_char; +extern procenv_t readline_top_level; + +/* terminal.c */ +extern int _rl_enable_keypad; +extern int _rl_enable_meta; +extern char *_rl_term_clreol; +extern char *_rl_term_clrpag; +extern char *_rl_term_im; +extern char *_rl_term_ic; +extern char *_rl_term_ei; +extern char *_rl_term_DC; +extern char *_rl_term_up; +extern char *_rl_term_dc; +extern char *_rl_term_cr; +extern char *_rl_term_IC; +extern int _rl_screenheight; +extern int _rl_screenwidth; +extern int _rl_screenchars; +extern int _rl_terminal_can_insert; +extern int _rl_term_autowrap; + +/* undo.c */ +extern int _rl_doing_an_undo; +extern int _rl_undo_group_level; + +#endif /* _RL_PRIVATE_H_ */ diff --git a/readline-4.3.orig/rlshell.h b/readline-4.3.orig/rlshell.h new file mode 100644 index 0000000..3c03fba --- /dev/null +++ b/readline-4.3.orig/rlshell.h @@ -0,0 +1,34 @@ +/* rlshell.h -- utility functions normally provided by bash. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_SHELL_H_) +#define _RL_SHELL_H_ + +#include "rlstdc.h" + +extern char *sh_single_quote PARAMS((char *)); +extern void sh_set_lines_and_columns PARAMS((int, int)); +extern char *sh_get_env_value PARAMS((const char *)); +extern char *sh_get_home_dir PARAMS((void)); +extern int sh_unset_nodelay_mode PARAMS((int)); + +#endif /* _RL_SHELL_H_ */ diff --git a/readline-4.3.orig/rlstdc.h b/readline-4.3.orig/rlstdc.h new file mode 100644 index 0000000..d6a22b3 --- /dev/null +++ b/readline-4.3.orig/rlstdc.h @@ -0,0 +1,45 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C + compilers. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_RL_STDC_H_) +#define _RL_STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# define __attribute__(x) +# endif +#endif + +#endif /* !_RL_STDC_H_ */ diff --git a/readline-4.3.orig/rltty.c b/readline-4.3.orig/rltty.c new file mode 100644 index 0000000..755efeb --- /dev/null +++ b/readline-4.3.orig/rltty.c @@ -0,0 +1,911 @@ +/* rltty.c -- functions to prepare and restore the terminal for readline's + use. */ + +/* Copyright (C) 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include +#endif /* GWINSZ_IN_SYS_IOCTL */ + +#include "rltty.h" +#include "readline.h" +#include "rlprivate.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; +rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; + +static void block_sigint PARAMS((void)); +static void release_sigint PARAMS((void)); + +static void set_winsize PARAMS((int)); + +/* **************************************************************** */ +/* */ +/* Signal Management */ +/* */ +/* **************************************************************** */ + +#if defined (HAVE_POSIX_SIGNALS) +static sigset_t sigint_set, sigint_oset; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) +static int sigint_oldmask; +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +static int sigint_blocked; + +/* Cause SIGINT to not be delivered until the corresponding call to + release_sigint(). */ +static void +block_sigint () +{ + if (sigint_blocked) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&sigint_set); + sigemptyset (&sigint_oset); + sigaddset (&sigint_set, SIGINT); + sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigint_oldmask = sigblock (sigmask (SIGINT)); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sighold (SIGINT); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigint_blocked = 1; +} + +/* Allow SIGINT to be delivered. */ +static void +release_sigint () +{ + if (sigint_blocked == 0) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL); +#else +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (sigint_oldmask); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sigrelse (SIGINT); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigint_blocked = 0; +} + +/* **************************************************************** */ +/* */ +/* Saving and Restoring the TTY */ +/* */ +/* **************************************************************** */ + +/* Non-zero means that the terminal is in a prepped state. */ +static int terminal_prepped; + +static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars; + +/* If non-zero, means that this process has called tcflow(fd, TCOOFF) + and output is suspended. */ +#if defined (__ksr1__) +static int ksrflow; +#endif + +/* Dummy call to force a backgrounded readline to stop before it tries + to get the tty settings. */ +static void +set_winsize (tty) + int tty; +{ +#if defined (TIOCGWINSZ) + struct winsize w; + + if (ioctl (tty, TIOCGWINSZ, &w) == 0) + (void) ioctl (tty, TIOCSWINSZ, &w); +#endif /* TIOCGWINSZ */ +} + +#if defined (NEW_TTY_DRIVER) + +/* Values for the `flags' field of a struct bsdtty. This tells which + elements of the struct bsdtty have been fetched from the system and + are valid. */ +#define SGTTY_SET 0x01 +#define LFLAG_SET 0x02 +#define TCHARS_SET 0x04 +#define LTCHARS_SET 0x08 + +struct bsdtty { + struct sgttyb sgttyb; /* Basic BSD tty driver information. */ + int lflag; /* Local mode flags, like LPASS8. */ +#if defined (TIOCGETC) + struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */ +#endif +#if defined (TIOCGLTC) + struct ltchars ltchars; /* 4.2 BSD editing characters */ +#endif + int flags; /* Bitmap saying which parts of the struct are valid. */ +}; + +#define TIOTYPE struct bsdtty + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +static void +save_tty_chars (tiop) + TIOTYPE *tiop; +{ + _rl_last_tty_chars = _rl_tty_chars; + + if (tiop->flags & SGTTY_SET) + { + _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase; + _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill; + } + + if (tiop->flags & TCHARS_SET) + { + _rl_tty_chars.t_intr = tiop->tchars.t_intrc; + _rl_tty_chars.t_quit = tiop->tchars.t_quitc; + _rl_tty_chars.t_start = tiop->tchars.t_startc; + _rl_tty_chars.t_stop = tiop->tchars.t_stopc; + _rl_tty_chars.t_eof = tiop->tchars.t_eofc; + _rl_tty_chars.t_eol = '\n'; + _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc; + } + + if (tiop->flags & LTCHARS_SET) + { + _rl_tty_chars.t_susp = tiop->ltchars.t_suspc; + _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc; + _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc; + _rl_tty_chars.t_flush = tiop->ltchars.t_flushc; + _rl_tty_chars.t_werase = tiop->ltchars.t_werasc; + _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc; + } + + _rl_tty_chars.t_status = -1; +} + +static int +get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + set_winsize (tty); + + tiop->flags = tiop->lflag = 0; + + if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) + return -1; + tiop->flags |= SGTTY_SET; + +#if defined (TIOCLGET) + if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0) + tiop->flags |= LFLAG_SET; +#endif + +#if defined (TIOCGETC) + if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0) + tiop->flags |= TCHARS_SET; +#endif + +#if defined (TIOCGLTC) + if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0) + tiop->flags |= LTCHARS_SET; +#endif + + return 0; +} + +static int +set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + if (tiop->flags & SGTTY_SET) + { + ioctl (tty, TIOCSETN, &(tiop->sgttyb)); + tiop->flags &= ~SGTTY_SET; + } + readline_echoing_p = 1; + +#if defined (TIOCLSET) + if (tiop->flags & LFLAG_SET) + { + ioctl (tty, TIOCLSET, &(tiop->lflag)); + tiop->flags &= ~LFLAG_SET; + } +#endif + +#if defined (TIOCSETC) + if (tiop->flags & TCHARS_SET) + { + ioctl (tty, TIOCSETC, &(tiop->tchars)); + tiop->flags &= ~TCHARS_SET; + } +#endif + +#if defined (TIOCSLTC) + if (tiop->flags & LTCHARS_SET) + { + ioctl (tty, TIOCSLTC, &(tiop->ltchars)); + tiop->flags &= ~LTCHARS_SET; + } +#endif + + return 0; +} + +static void +prepare_terminal_settings (meta_flag, oldtio, tiop) + int meta_flag; + TIOTYPE oldtio, *tiop; +{ + readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); + + /* Copy the original settings to the structure we're going to use for + our settings. */ + tiop->sgttyb = oldtio.sgttyb; + tiop->lflag = oldtio.lflag; +#if defined (TIOCGETC) + tiop->tchars = oldtio.tchars; +#endif +#if defined (TIOCGLTC) + tiop->ltchars = oldtio.ltchars; +#endif + tiop->flags = oldtio.flags; + + /* First, the basic settings to put us into character-at-a-time, no-echo + input mode. */ + tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD); + tiop->sgttyb.sg_flags |= CBREAK; + + /* If this terminal doesn't care how the 8th bit is used, then we can + use it for the meta-key. If only one of even or odd parity is + specified, then the terminal is using parity, and we cannot. */ +#if !defined (ANYP) +# define ANYP (EVENP | ODDP) +#endif + if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) || + ((oldtio.sgttyb.sg_flags & ANYP) == 0)) + { + tiop->sgttyb.sg_flags |= ANYP; + + /* Hack on local mode flags if we can. */ +#if defined (TIOCLGET) +# if defined (LPASS8) + tiop->lflag |= LPASS8; +# endif /* LPASS8 */ +#endif /* TIOCLGET */ + } + +#if defined (TIOCGETC) +# if defined (USE_XON_XOFF) + /* Get rid of terminal output start and stop characters. */ + tiop->tchars.t_stopc = -1; /* C-s */ + tiop->tchars.t_startc = -1; /* C-q */ + + /* If there is an XON character, bind it to restart the output. */ + if (oldtio.tchars.t_startc != -1) + rl_bind_key (oldtio.tchars.t_startc, rl_restart_output); +# endif /* USE_XON_XOFF */ + + /* If there is an EOF char, bind _rl_eof_char to it. */ + if (oldtio.tchars.t_eofc != -1) + _rl_eof_char = oldtio.tchars.t_eofc; + +# if defined (NO_KILL_INTR) + /* Get rid of terminal-generated SIGQUIT and SIGINT. */ + tiop->tchars.t_quitc = -1; /* C-\ */ + tiop->tchars.t_intrc = -1; /* C-c */ +# endif /* NO_KILL_INTR */ +#endif /* TIOCGETC */ + +#if defined (TIOCGLTC) + /* Make the interrupt keys go away. Just enough to make people happy. */ + tiop->ltchars.t_dsuspc = -1; /* C-y */ + tiop->ltchars.t_lnextc = -1; /* C-v */ +#endif /* TIOCGLTC */ +} + +#else /* !defined (NEW_TTY_DRIVER) */ + +#if !defined (VMIN) +# define VMIN VEOF +#endif + +#if !defined (VTIME) +# define VTIME VEOL +#endif + +#if defined (TERMIOS_TTY_DRIVER) +# define TIOTYPE struct termios +# define DRAIN_OUTPUT(fd) tcdrain (fd) +# define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) +# ifdef M_UNIX +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) +# else +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) +# endif /* !M_UNIX */ +#else +# define TIOTYPE struct termio +# define DRAIN_OUTPUT(fd) +# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) +# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop)) +#endif /* !TERMIOS_TTY_DRIVER */ + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +#if defined (FLUSHO) +# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) +#else +# define OUTPUT_BEING_FLUSHED(tp) 0 +#endif + +static void +save_tty_chars (tiop) + TIOTYPE *tiop; +{ + _rl_last_tty_chars = _rl_tty_chars; + + _rl_tty_chars.t_eof = tiop->c_cc[VEOF]; + _rl_tty_chars.t_eol = tiop->c_cc[VEOL]; +#ifdef VEOL2 + _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2]; +#endif + _rl_tty_chars.t_erase = tiop->c_cc[VERASE]; +#ifdef VWERASE + _rl_tty_chars.t_werase = tiop->c_cc[VWERASE]; +#endif + _rl_tty_chars.t_kill = tiop->c_cc[VKILL]; +#ifdef VREPRINT + _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT]; +#endif + _rl_tty_chars.t_intr = tiop->c_cc[VINTR]; + _rl_tty_chars.t_quit = tiop->c_cc[VQUIT]; +#ifdef VSUSP + _rl_tty_chars.t_susp = tiop->c_cc[VSUSP]; +#endif +#ifdef VDSUSP + _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP]; +#endif +#ifdef VSTART + _rl_tty_chars.t_start = tiop->c_cc[VSTART]; +#endif +#ifdef VSTOP + _rl_tty_chars.t_stop = tiop->c_cc[VSTOP]; +#endif +#ifdef VLNEXT + _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT]; +#endif +#ifdef VDISCARD + _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD]; +#endif +#ifdef VSTATUS + _rl_tty_chars.t_status = tiop->c_cc[VSTATUS]; +#endif +} + +#if defined (_AIX) || defined (_AIX41) +/* Currently this is only used on AIX */ +static void +rltty_warning (msg) + char *msg; +{ + fprintf (stderr, "readline: warning: %s\n", msg); +} +#endif + +#if defined (_AIX) +void +setopost(tp) +TIOTYPE *tp; +{ + if ((tp->c_oflag & OPOST) == 0) + { + rltty_warning ("turning on OPOST for terminal\r"); + tp->c_oflag |= OPOST|ONLCR; + } +} +#endif + +static int +_get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + int ioctl_ret; + + while (1) + { + ioctl_ret = GETATTR (tty, tiop); + if (ioctl_ret < 0) + { + if (errno != EINTR) + return -1; + else + continue; + } + if (OUTPUT_BEING_FLUSHED (tiop)) + { +#if defined (FLUSHO) && defined (_AIX41) + rltty_warning ("turning off output flushing"); + tiop->c_lflag &= ~FLUSHO; + break; +#else + continue; +#endif + } + break; + } + + return 0; +} + +static int +get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + set_winsize (tty); + + if (_get_tty_settings (tty, tiop) < 0) + return -1; + +#if defined (_AIX) + setopost(tiop); +#endif + + return 0; +} + +static int +_set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + while (SETATTR (tty, tiop) < 0) + { + if (errno != EINTR) + return -1; + errno = 0; + } + return 0; +} + +static int +set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + if (_set_tty_settings (tty, tiop) < 0) + return -1; + +#if 0 + +#if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (tty, TCOON); + } +# else /* !ksr1 */ + tcflow (tty, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +#else + ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ +#endif /* !TERMIOS_TTY_DRIVER */ + +#endif /* 0 */ + + return 0; +} + +static void +prepare_terminal_settings (meta_flag, oldtio, tiop) + int meta_flag; + TIOTYPE oldtio, *tiop; +{ + readline_echoing_p = (oldtio.c_lflag & ECHO); + + tiop->c_lflag &= ~(ICANON | ECHO); + + if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) + _rl_eof_char = oldtio.c_cc[VEOF]; + +#if defined (USE_XON_XOFF) +#if defined (IXANY) + tiop->c_iflag &= ~(IXON | IXOFF | IXANY); +#else + /* `strict' Posix systems do not define IXANY. */ + tiop->c_iflag &= ~(IXON | IXOFF); +#endif /* IXANY */ +#endif /* USE_XON_XOFF */ + + /* Only turn this off if we are using all 8 bits. */ + if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag) + tiop->c_iflag &= ~(ISTRIP | INPCK); + + /* Make sure we differentiate between CR and NL on input. */ + tiop->c_iflag &= ~(ICRNL | INLCR); + +#if !defined (HANDLE_SIGNALS) + tiop->c_lflag &= ~ISIG; +#else + tiop->c_lflag |= ISIG; +#endif + + tiop->c_cc[VMIN] = 1; + tiop->c_cc[VTIME] = 0; + +#if defined (FLUSHO) + if (OUTPUT_BEING_FLUSHED (tiop)) + { + tiop->c_lflag &= ~FLUSHO; + oldtio.c_lflag &= ~FLUSHO; + } +#endif + + /* Turn off characters that we need on Posix systems with job control, + just to be sure. This includes ^Y and ^V. This should not really + be necessary. */ +#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE) + +#if defined (VLNEXT) + tiop->c_cc[VLNEXT] = _POSIX_VDISABLE; +#endif + +#if defined (VDSUSP) + tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; +#endif + +#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ +} +#endif /* NEW_TTY_DRIVER */ + +/* Put the terminal in CBREAK mode so that we can detect key presses. */ +void +rl_prep_terminal (meta_flag) + int meta_flag; +{ + int tty; + TIOTYPE tio; + + if (terminal_prepped) + return; + + /* Try to keep this function from being INTerrupted. */ + block_sigint (); + + tty = fileno (rl_instream); + + if (get_tty_settings (tty, &tio) < 0) + { + release_sigint (); + return; + } + + otio = tio; + + save_tty_chars (&otio); + + prepare_terminal_settings (meta_flag, otio, &tio); + + if (set_tty_settings (tty, &tio) < 0) + { + release_sigint (); + return; + } + + if (_rl_enable_keypad) + _rl_control_keypad (1); + + fflush (rl_outstream); + terminal_prepped = 1; + RL_SETSTATE(RL_STATE_TERMPREPPED); + + release_sigint (); +} + +/* Restore the terminal's normal settings and modes. */ +void +rl_deprep_terminal () +{ + int tty; + + if (!terminal_prepped) + return; + + /* Try to keep this function from being interrupted. */ + block_sigint (); + + tty = fileno (rl_instream); + + if (_rl_enable_keypad) + _rl_control_keypad (0); + + fflush (rl_outstream); + + if (set_tty_settings (tty, &otio) < 0) + { + release_sigint (); + return; + } + + terminal_prepped = 0; + RL_UNSETSTATE(RL_STATE_TERMPREPPED); + + release_sigint (); +} + +/* **************************************************************** */ +/* */ +/* Bogus Flow Control */ +/* */ +/* **************************************************************** */ + +int +rl_restart_output (count, key) + int count, key; +{ + int fildes = fileno (rl_outstream); +#if defined (TIOCSTART) +#if defined (apollo) + ioctl (&fildes, TIOCSTART, 0); +#else + ioctl (fildes, TIOCSTART, 0); +#endif /* apollo */ + +#else /* !TIOCSTART */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (fildes, TCOON); + } +# else /* !ksr1 */ + tcflow (fildes, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +# else /* !TERMIOS_TTY_DRIVER */ +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTART */ + + return 0; +} + +int +rl_stop_output (count, key) + int count, key; +{ + int fildes = fileno (rl_instream); + +#if defined (TIOCSTOP) +# if defined (apollo) + ioctl (&fildes, TIOCSTOP, 0); +# else + ioctl (fildes, TIOCSTOP, 0); +# endif /* apollo */ +#else /* !TIOCSTOP */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + ksrflow = 1; +# endif /* ksr1 */ + tcflow (fildes, TCOOFF); +# else +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTOP */ + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Default Key Bindings */ +/* */ +/* **************************************************************** */ + +/* 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; +{ + TIOTYPE ttybuff; + int tty = fileno (rl_instream); + +#if defined (NEW_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) + + if (get_tty_settings (tty, &ttybuff) == 0) + { + if (ttybuff.flags & SGTTY_SET) + { + 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 */ + } + +#else /* !NEW_TTY_DRIVER */ + +#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) + + if (get_tty_settings (tty, &ttybuff) == 0) + { + 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); +# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ + +# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) + SET_SPECIAL (VWERASE, rl_unix_word_rubout); +# endif /* VWERASE && TERMIOS_TTY_DRIVER */ + } +#endif /* !NEW_TTY_DRIVER */ +} + +/* New public way to set the system default editing chars to their readline + equivalents. */ +void +rl_tty_set_default_bindings (kmap) + Keymap kmap; +{ + rltty_set_default_bindings (kmap); +} + +#if defined (HANDLE_SIGNALS) + +#if defined (NEW_TTY_DRIVER) +int +_rl_disable_tty_signals () +{ + return 0; +} + +int +_rl_restore_tty_signals () +{ + return 0; +} +#else + +static TIOTYPE sigstty, nosigstty; +static int tty_sigs_disabled = 0; + +int +_rl_disable_tty_signals () +{ + if (tty_sigs_disabled) + return 0; + + if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0) + return -1; + + nosigstty = sigstty; + + nosigstty.c_lflag &= ~ISIG; + nosigstty.c_iflag &= ~IXON; + + if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0) + return (_set_tty_settings (fileno (rl_instream), &sigstty)); + + tty_sigs_disabled = 1; + return 0; +} + +int +_rl_restore_tty_signals () +{ + int r; + + if (tty_sigs_disabled == 0) + return 0; + + r = _set_tty_settings (fileno (rl_instream), &sigstty); + + if (r == 0) + tty_sigs_disabled = 0; + + return r; +} +#endif /* !NEW_TTY_DRIVER */ + +#endif /* HANDLE_SIGNALS */ diff --git a/readline-4.3.orig/rltty.h b/readline-4.3.orig/rltty.h new file mode 100644 index 0000000..029a3fb --- /dev/null +++ b/readline-4.3.orig/rltty.h @@ -0,0 +1,82 @@ +/* rltty.h - tty driver-related definitions used by some library files. */ + +/* Copyright (C) 1995 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLTTY_H_) +#define _RLTTY_H_ + +/* Posix systems use termios and the Posix signal functions. */ +#if defined (TERMIOS_TTY_DRIVER) +# include +#endif /* TERMIOS_TTY_DRIVER */ + +/* System V machines use termio. */ +#if defined (TERMIO_TTY_DRIVER) +# include +# if !defined (TCOON) +# define TCOON 1 +# endif +#endif /* TERMIO_TTY_DRIVER */ + +/* Other (BSD) machines use sgtty. */ +#if defined (NEW_TTY_DRIVER) +# include +#endif + +#include "rlwinsize.h" + +/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and + it is not already defined. It is used both to determine if a + special character is disabled and to disable certain special + characters. Posix systems should set to 0, USG systems to -1. */ +#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE) +# if defined (_SVR4_VDISABLE) +# define _POSIX_VDISABLE _SVR4_VDISABLE +# else +# if defined (_POSIX_VERSION) +# define _POSIX_VDISABLE 0 +# else /* !_POSIX_VERSION */ +# define _POSIX_VDISABLE -1 +# endif /* !_POSIX_VERSION */ +# endif /* !_SVR4_DISABLE */ +#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; +} _RL_TTY_CHARS; + +#endif /* _RLTTY_H_ */ diff --git a/readline-4.3.orig/rltypedefs.h b/readline-4.3.orig/rltypedefs.h new file mode 100644 index 0000000..f3280e9 --- /dev/null +++ b/readline-4.3.orig/rltypedefs.h @@ -0,0 +1,88 @@ +/* rltypedefs.h -- Type declarations for readline functions. */ + +/* Copyright (C) 2000 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _RL_TYPEDEFS_H_ +#define _RL_TYPEDEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Old-style */ + +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF + +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); +typedef char **CPPFunction (); + +#endif /* _FUNCTION_DEF */ + +/* New style. */ + +#if !defined (_RL_FUNCTION_TYPEDEF) +# define _RL_FUNCTION_TYPEDEF + +/* Bindable functions */ +typedef int rl_command_func_t PARAMS((int, int)); + +/* Typedefs for the completion system */ +typedef char *rl_compentry_func_t PARAMS((const char *, int)); +typedef char **rl_completion_func_t PARAMS((const char *, int, int)); + +typedef char *rl_quote_func_t PARAMS((char *, int, char *)); +typedef char *rl_dequote_func_t PARAMS((char *, int)); + +typedef int rl_compignore_func_t PARAMS((char **)); + +typedef void rl_compdisp_func_t PARAMS((char **, int, int)); + +/* Type for input and pre-read hook functions like rl_event_hook */ +typedef int rl_hook_func_t PARAMS((void)); + +/* Input function type */ +typedef int rl_getc_func_t PARAMS((FILE *)); + +/* Generic function that takes a character buffer (which could be the readline + line buffer) and an index into it (which could be rl_point) and returns + an int. */ +typedef int rl_linebuf_func_t PARAMS((char *, int)); + +/* `Generic' function pointer typedefs */ +typedef int rl_intfunc_t PARAMS((int)); +#define rl_ivoidfunc_t rl_hook_func_t +typedef int rl_icpfunc_t PARAMS((char *)); +typedef int rl_icppfunc_t PARAMS((char **)); + +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 **)); +#endif /* _RL_FUNCTION_TYPEDEF */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RL_TYPEDEFS_H_ */ diff --git a/readline-4.3.orig/rlwinsize.h b/readline-4.3.orig/rlwinsize.h new file mode 100644 index 0000000..7838154 --- /dev/null +++ b/readline-4.3.orig/rlwinsize.h @@ -0,0 +1,57 @@ +/* rlwinsize.h -- an attempt to isolate some of the system-specific defines + for `struct winsize' and TIOCGWINSZ. */ + +/* Copyright (C) 1997 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLWINSIZE_H_) +#define _RLWINSIZE_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */ + +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ + +#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# include +#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +/* Not in either of the standard places, look around. */ +#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# if defined (HAVE_SYS_STREAM_H) +# include +# endif /* HAVE_SYS_STREAM_H */ +# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */ +# include +# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ +# endif /* HAVE_SYS_PTEM_H */ +# if defined (HAVE_SYS_PTE_H) /* ??? */ +# include +# endif /* HAVE_SYS_PTE_H */ +#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +#endif /* _RL_WINSIZE_H */ + diff --git a/readline-4.3.orig/savestring.c b/readline-4.3.orig/savestring.c new file mode 100644 index 0000000..c7ebeb1 --- /dev/null +++ b/readline-4.3.orig/savestring.c @@ -0,0 +1,36 @@ +/* savestring.c */ + +/* Copyright (C) 1998 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include +#ifdef HAVE_STRING_H +# include +#endif +#include "xmalloc.h" + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +char * +savestring (s) + const char *s; +{ + return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s))); +} diff --git a/readline-4.3.orig/search.c b/readline-4.3.orig/search.c new file mode 100644 index 0000000..7e0d60b --- /dev/null +++ b/readline-4.3.orig/search.c @@ -0,0 +1,465 @@ +/* search.c - code for non-incremental searching in emacs and vi modes. */ + +/* Copyright (C) 1992 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifdef abs +# undef abs +#endif +#define abs(x) (((x) >= 0) ? (x) : -(x)) + +extern HIST_ENTRY *_rl_saved_line_for_history; + +/* Functions imported from the rest of the library. */ +extern int _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +static char *noninc_search_string = (char *) NULL; +static int noninc_history_pos; + +static char *prev_line_found = (char *) NULL; + +static int rl_history_search_len; +static int rl_history_search_pos; +static char *history_search_string; +static int history_string_size; + +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 rl_history_search_internal PARAMS((int, int)); +static void rl_history_search_reinit PARAMS((void)); + +/* 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. */ +static void +make_history_line_current (entry) + HIST_ENTRY *entry; +{ + rl_replace_line (entry->line, 0); + rl_undo_list = (UNDO_LIST *)entry->data; + + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Search the history list for STRING starting at absolute history position + POS. If STRING begins with `^', the search must match STRING at the + beginning of a history line, otherwise a full substring match is performed + for STRING. DIR < 0 means to search backwards through the history list, + DIR >= 0 means to search forward. */ +static int +noninc_search_from_pos (string, pos, dir) + char *string; + int pos, dir; +{ + int ret, old; + + if (pos < 0) + return -1; + + old = where_history (); + if (history_set_pos (pos) == 0) + return -1; + + RL_SETSTATE(RL_STATE_SEARCH); + if (*string == '^') + ret = history_search_prefix (string + 1, dir); + else + ret = history_search (string, dir); + RL_UNSETSTATE(RL_STATE_SEARCH); + + if (ret != -1) + ret = where_history (); + + history_set_pos (old); + return (ret); +} + +/* 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 +noninc_dosearch (string, dir) + char *string; + int dir; +{ + int oldpos, pos; + HIST_ENTRY *entry; + + if (string == 0 || *string == '\0' || noninc_history_pos < 0) + { + rl_ding (); + return; + } + + pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); + if (pos == -1) + { + /* Search failed, current history position unchanged. */ + rl_maybe_unsave_line (); + rl_clear_message (); + rl_point = 0; + rl_ding (); + return; + } + + noninc_history_pos = pos; + + oldpos = where_history (); + history_set_pos (noninc_history_pos); + entry = current_history (); +#if defined (VI_MODE) + if (rl_editing_mode != vi_mode) +#endif + history_set_pos (oldpos); + + make_history_line_current (entry); + + rl_point = 0; + rl_mark = rl_end; + + rl_clear_message (); +} + +/* 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; +{ + int saved_point, saved_mark, c; + char *p; +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; +#endif + + rl_maybe_save_line (); + saved_point = rl_point; + saved_mark = rl_mark; + + /* Use the line buffer to read the search string. */ + rl_line_buffer[0] = 0; + rl_end = rl_point = 0; + + p = _rl_make_prompt_for_search (pchar ? 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_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, MB_LEN_MAX); +#endif + + if (c == 0) + break; + + switch (c) + { + 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; + + default: +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (mb); + else +#endif + _rl_insert_char (1, c); + break; + } + (*rl_redisplay_function) (); + } + + dosearch: + rl_mark = saved_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) + { + rl_ding (); + SEARCH_RETURN; + } + } + else + { + /* We want to start the search from the current history position. */ + noninc_history_pos = where_history (); + FREE (noninc_search_string); + noninc_search_string = savestring (rl_line_buffer); + } + + rl_restore_prompt (); + noninc_dosearch (noninc_search_string, dir); + RL_UNSETSTATE(RL_STATE_NSEARCH); +} + +/* Search forward through the history list for a string. If the vi-mode + code calls this, KEY will be `?'. */ +int +rl_noninc_forward_search (count, key) + int count, key; +{ + noninc_search (1, (key == '?') ? '?' : 0); + return 0; +} + +/* Reverse search the history list for a string. If the vi-mode code + calls this, KEY will be `/'. */ +int +rl_noninc_reverse_search (count, key) + int count, key; +{ + noninc_search (-1, (key == '/') ? '/' : 0); + return 0; +} + +/* Search forward through the history list for the last string searched + for. If there is no saved search string, abort. */ +int +rl_noninc_forward_search_again (count, key) + int count, key; +{ + if (!noninc_search_string) + { + rl_ding (); + return (-1); + } + noninc_dosearch (noninc_search_string, 1); + return 0; +} + +/* Reverse search in the history list for the last string searched + for. If there is no saved search string, abort. */ +int +rl_noninc_reverse_search_again (count, key) + int count, key; +{ + if (!noninc_search_string) + { + rl_ding (); + return (-1); + } + noninc_dosearch (noninc_search_string, -1); + return 0; +} + +static int +rl_history_search_internal (count, dir) + int count, dir; +{ + HIST_ENTRY *temp; + int ret, oldpos; + + rl_maybe_save_line (); + temp = (HIST_ENTRY *)NULL; + + /* Search COUNT times through the history for a line whose prefix + matches history_search_string. When this loop finishes, TEMP, + if non-null, is the history line to copy into the line buffer. */ + while (count) + { + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); + if (ret == -1) + break; + + /* Get the history entry we found. */ + rl_history_search_pos = ret; + oldpos = where_history (); + history_set_pos (rl_history_search_pos); + temp = current_history (); + history_set_pos (oldpos); + + /* Don't find multiple instances of the same line. */ + if (prev_line_found && STREQ (prev_line_found, temp->line)) + continue; + prev_line_found = temp->line; + count--; + } + + /* If we didn't find anything at all, return. */ + if (temp == 0) + { + rl_maybe_unsave_line (); + rl_ding (); + /* If you don't want the saved history line (last match) to show up + in the line buffer after the search fails, change the #if 0 to + #if 1 */ +#if 0 + if (rl_point > rl_history_search_len) + { + rl_point = rl_end = rl_history_search_len; + rl_line_buffer[rl_end] = '\0'; + rl_mark = 0; + } +#else + rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */ + rl_mark = rl_end; +#endif + return 1; + } + + /* Copy the line we found into the current line buffer. */ + make_history_line_current (temp); + + rl_point = rl_history_search_len; + rl_mark = rl_end; + + return 0; +} + +static void +rl_history_search_reinit () +{ + rl_history_search_pos = where_history (); + rl_history_search_len = rl_point; + prev_line_found = (char *)NULL; + if (rl_point) + { + if (rl_history_search_len >= history_string_size - 2) + { + history_string_size = rl_history_search_len + 2; + history_search_string = (char *)xrealloc (history_search_string, history_string_size); + } + history_search_string[0] = '^'; + strncpy (history_search_string + 1, rl_line_buffer, rl_point); + history_search_string[rl_point + 1] = '\0'; + } + _rl_free_saved_history_line (); +} + +/* Search forward in the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_search_forward (count, ignore) + int count, ignore; +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_next_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); +} + +/* Search backward through the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_search_backward (count, ignore) + int count, ignore; +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_previous_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); +} diff --git a/readline-4.3.orig/shell.c b/readline-4.3.orig/shell.c new file mode 100644 index 0000000..ad27cc1 --- /dev/null +++ b/readline-4.3.orig/shell.c @@ -0,0 +1,196 @@ +/* shell.c -- readline utility functions that are normally provided by + bash when readline is linked as part of the shell. */ + +/* Copyright (C) 1997 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include +#include + +#include + +#include "rlstdc.h" +#include "rlshell.h" +#include "xmalloc.h" + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid PARAMS((uid_t)); +#endif /* !HAVE_GETPW_DECLS */ + +#ifndef NULL +# define NULL 0 +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* All of these functions are resolved from bash if we are linking readline + as part of bash. */ + +/* Does shell-like quoting using single quotes. */ +char * +sh_single_quote (string) + char *string; +{ + register int c; + char *result, *r, *s; + + result = (char *)xmalloc (3 + (4 * strlen (string))); + r = result; + *r++ = '\''; + + for (s = string; s && (c = *s); s++) + { + *r++ = c; + + if (c == '\'') + { + *r++ = '\\'; /* insert escaped single quote */ + *r++ = '\''; + *r++ = '\''; /* start new quoted string */ + } + } + + *r++ = '\''; + *r = '\0'; + + return (result); +} + +/* Set the environment variables LINES and COLUMNS to lines and cols, + respectively. */ +void +sh_set_lines_and_columns (lines, cols) + int 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) + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); + sprintf (b, "%d", lines); + setenv ("LINES", b, 1); + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); + sprintf (b, "%d", cols); + setenv ("COLUMNS", b, 1); +# endif /* HAVE_SETENV */ +#endif /* !HAVE_PUTENV */ +} + +char * +sh_get_env_value (varname) + const char *varname; +{ + return ((char *)getenv (varname)); +} + +char * +sh_get_home_dir () +{ + char *home_dir; + struct passwd *entry; + + home_dir = (char *)NULL; + entry = getpwuid (getuid ()); + if (entry) + home_dir = entry->pw_dir; + return (home_dir); +} + +#if !defined (O_NDELAY) +# if defined (FNDELAY) +# define O_NDELAY FNDELAY +# endif +#endif + +int +sh_unset_nodelay_mode (fd) + int fd; +{ + int flags, bflags; + + if ((flags = fcntl (fd, F_GETFL, 0)) < 0) + return -1; + + bflags = 0; + +#ifdef O_NONBLOCK + bflags |= O_NONBLOCK; +#endif + +#ifdef O_NDELAY + bflags |= O_NDELAY; +#endif + + if (flags & bflags) + { + flags &= ~bflags; + return (fcntl (fd, F_SETFL, flags)); + } + + return 0; +} diff --git a/readline-4.3.orig/shlib/Makefile.in b/readline-4.3.orig/shlib/Makefile.in new file mode 100644 index 0000000..0cba57e --- /dev/null +++ b/readline-4.3.orig/shlib/Makefile.in @@ -0,0 +1,437 @@ +## -*- text -*- ## +# Makefile for the GNU readline library shared library support. +# +# Copyright (C) 1998 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 USA. + +RL_LIBRARY_VERSION = @LIBVERSION@ +RL_LIBRARY_NAME = readline + +srcdir = @srcdir@ +VPATH = .:@top_srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv +LN = ln + +SHELL = @MAKE_SHELL@ + +host_os = @host_os@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +libdir = @libdir@ + +# Support an alternate destination root directory for package building +DESTDIR = + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ @CFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +# +# These values are generated for configure by ${topdir}/support/shobj-conf. +# If your system is not supported by that script, but includes facilities for +# dynamic loading of shared objects, please update the script and send the +# changes to bash-maintainers@gnu.org. +# +SHOBJ_CC = @SHOBJ_CC@ +SHOBJ_CFLAGS = @SHOBJ_CFLAGS@ +SHOBJ_LD = @SHOBJ_LD@ + +SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@ +SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@ +SHOBJ_LIBS = @SHOBJ_LIBS@ + +SHLIB_XLDFLAGS = @SHLIB_XLDFLAGS@ +SHLIB_LIBS = @SHLIB_LIBS@ +SHLIB_LIBSUFF = @SHLIB_LIBSUFF@ + +SHLIB_LIBVERSION = @SHLIB_LIBVERSION@ + +SHLIB_STATUS = @SHLIB_STATUS@ + +# shared library versioning +SHLIB_MAJOR= @SHLIB_MAJOR@ +# shared library systems like SVR4's do not use minor versions +SHLIB_MINOR= .@SHLIB_MINOR@ + +# For libraries which include headers from other libraries. +INCLUDES = -I. -I.. -I$(topdir) + +CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) $(INCLUDES) $(LOCAL_CFLAGS) $(CFLAGS) + +.SUFFIXES: .so + +.c.so: + ${RM} $@ + $(SHOBJ_CC) -c $(CCFLAGS) $(SHOBJ_CFLAGS) -o $*.o $< + $(MV) $*.o $@ + +# The name of the main library target. + +SHARED_READLINE = libreadline.$(SHLIB_LIBVERSION) +SHARED_HISTORY = libhistory.$(SHLIB_LIBVERSION) +SHARED_LIBS = $(SHARED_READLINE) $(SHARED_HISTORY) + +# The C code source files for this library. +CSOURCES = $(topdir)/readline.c $(topdir)/funmap.c $(topdir)/keymaps.c \ + $(topdir)/vi_mode.c $(topdir)/parens.c $(topdir)/rltty.c \ + $(topdir)/complete.c $(topdir)/bind.c $(topdir)/isearch.c \ + $(topdir)/display.c $(topdir)/signals.c $(topdir)/emacs_keymap.c \ + $(topdir)/vi_keymap.c $(topdir)/util.c $(topdir)/kill.c \ + $(topdir)/undo.c $(topdir)/macro.c $(topdir)/input.c \ + $(topdir)/callback.c $(topdir)/terminal.c $(topdir)/xmalloc.c \ + $(topdir)/history.c $(topdir)/histsearch.c $(topdir)/histexpand.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 + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \ + ansi_stdlib.h tcap.h xmalloc.h rlprivate.h rlshell.h rlmbutil.h + +SHARED_HISTOBJ = history.so histexpand.so histfile.so histsearch.so shell.so \ + mbutil.so +SHARED_TILDEOBJ = tilde.so +SHARED_OBJ = readline.so vi_mode.so funmap.so keymaps.so parens.so search.so \ + rltty.so complete.so bind.so isearch.so display.so signals.so \ + util.so kill.so undo.so macro.so input.so callback.so terminal.so \ + text.so nls.so misc.so xmalloc.so $(SHARED_HISTOBJ) $(SHARED_TILDEOBJ) \ + compat.so + +########################################################################## + +all: $(SHLIB_STATUS) + +supported: $(SHARED_LIBS) + +unsupported: + @echo "Your system and compiler (${host_os}-${CC}) are not supported by the" + @echo "${topdir}/support/shobj-conf script." + @echo "If your operating system provides facilities for creating" + @echo "shared libraries, please update the script and re-run configure." + @echo "Please send the changes you made to bash-maintainers@gnu.org" + @echo "for inclusion in future bash and readline releases." + +$(SHARED_READLINE): $(SHARED_OBJ) + $(RM) $@ + $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_OBJ) $(SHLIB_LIBS) + +$(SHARED_HISTORY): $(SHARED_HISTOBJ) xmalloc.so + $(RM) $@ + $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_HISTOBJ) xmalloc.so $(SHLIB_LIBS) + +# Since tilde.c is shared between readline and bash, make sure we compile +# it with the right flags when it's built as part of readline +tilde.so: tilde.c + ${RM} $@ + $(SHOBJ_CC) -c $(CCFLAGS) $(SHOBJ_CFLAGS) -DREADLINE_LIBRARY -c -o tilde.o $(topdir)/tilde.c + $(MV) tilde.o $@ + +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) + @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) + @echo uninstall: you may need to run ldconfig + +clean mostlyclean: force + $(RM) $(SHARED_OBJ) $(SHARED_LIBS) + +distclean maintainer-clean: clean + $(RM) Makefile + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Dependencies +bind.so: $(topdir)/ansi_stdlib.h $(topdir)/posixstat.h +bind.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +bind.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +bind.so: $(topdir)/rltypedefs.h +bind.so: $(topdir)/tilde.h $(topdir)/history.h +compat.so: $(topdir)/rlstdc.h +callback.so: $(topdir)/rlconf.h +callback.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h +callback.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +callback.so: $(topdir)/rltypedefs.h +callback.so: $(topdir)/tilde.h +complete.so: $(topdir)/ansi_stdlib.h posixdir.h $(topdir)/posixstat.h +complete.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +complete.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +complete.so: $(topdir)/rltypedefs.h +complete.so: $(topdir)/tilde.h +display.so: $(topdir)/ansi_stdlib.h $(topdir)/posixstat.h +display.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +display.so: $(topdir)/tcap.h +display.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +display.so: $(topdir)/rltypedefs.h +display.so: $(topdir)/tilde.h $(topdir)/history.h +funmap.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +funmap.so: $(topdir)/rltypedefs.h +funmap.so: $(topdir)/rlconf.h $(topdir)/ansi_stdlib.h +funmap.so: ${BUILD_DIR}/config.h $(topdir)/tilde.h +histexpand.so: $(topdir)/ansi_stdlib.h +histexpand.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histexpand.so: ${BUILD_DIR}/config.h +histfile.so: $(topdir)/ansi_stdlib.h +histfile.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histfile.so: ${BUILD_DIR}/config.h +history.so: $(topdir)/ansi_stdlib.h +history.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +history.so: ${BUILD_DIR}/config.h +histsearch.so: $(topdir)/ansi_stdlib.h +histsearch.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histsearch.so: ${BUILD_DIR}/config.h +input.so: $(topdir)/ansi_stdlib.h +input.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +input.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +input.so: $(topdir)/rltypedefs.h +input.so: $(topdir)/tilde.h +isearch.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +isearch.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +isearch.so: $(topdir)/rltypedefs.h +isearch.so: $(topdir)/ansi_stdlib.h $(topdir)/history.h $(topdir)/tilde.h +keymaps.so: emacs_keymap.c vi_keymap.c +keymaps.so: $(topdir)/keymaps.h $(topdir)/chardefs.h $(topdir)/rlconf.h +keymaps.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +keymaps.so: $(topdir)/rltypedefs.h +keymaps.so: ${BUILD_DIR}/config.h $(topdir)/ansi_stdlib.h $(topdir)/tilde.h +kill.so: $(topdir)/ansi_stdlib.h +kill.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +kill.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +kill.so: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rltypedefs.h +macro.so: $(topdir)/ansi_stdlib.h +macro.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +macro.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +macro.so: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rltypedefs.h +mbutil.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +mbutil.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/rltypedefs.h +mbutil.so: $(topdir)/chardefs.h $(topdir)/rlstdc.h +misc.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +misc.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +misc.so: $(topdir)/rltypedefs.h +misc.so: $(topdir)/history.h $(topdir)/tilde.h $(topdir)/ansi_stdlib.h +nls.so: $(topdir)/ansi_stdlib.h +nls.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +nls.o: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +nls.o: $(topdir)/rltypedefs.h +nls.o: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rlstdc.h +parens.so: $(topdir)/rlconf.h ${BUILD_DIR}/config.h +parens.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +parens.so: $(topdir)/rltypedefs.h +parens.so: $(topdir)/tilde.h +rltty.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +rltty.so: $(topdir)/rltty.h $(topdir)/tilde.h +rltty.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +rltty.so: $(topdir)/rltypedefs.h +search.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +search.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +search.so: $(topdir)/ansi_stdlib.h $(topdir)/history.h $(topdir)/tilde.h +search.so: $(topdir)/rltypedefs.h +signals.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +signals.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +signals.so: $(topdir)/history.h $(topdir)/tilde.h +signals.so: $(topdir)/rltypedefs.h +terminal.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +terminal.so: $(topdir)/tcap.h +terminal.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +terminal.so: $(topdir)/tilde.h $(topdir)/history.h +terminal.so: $(topdir)/rltypedefs.h +text.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +text.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +text.so: $(topdir)/rltypedefs.h +text.so: $(topdir)/history.h $(topdir)/tilde.h $(topdir)/ansi_stdlib.h +tilde.so: $(topdir)/ansi_stdlib.h ${BUILD_DIR}/config.h $(topdir)/tilde.h +undo.so: $(topdir)/ansi_stdlib.h +undo.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +undo.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +undo.so: $(topdir)/rltypedefs.h +undo.so: $(topdir)/tilde.h $(topdir)/history.h +util.so: $(topdir)/posixjmp.h $(topdir)/ansi_stdlib.h +util.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +util.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +util.so: $(topdir)/rltypedefs.h $(topdir)/tilde.h +vi_mode.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +vi_mode.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +vi_mode.so: $(topdir)/history.h $(topdir)/ansi_stdlib.h $(topdir)/tilde.h +vi_mode.so: $(topdir)/rltypedefs.h +xmalloc.so: ${BUILD_DIR}/config.h +xmalloc.so: $(topdir)/ansi_stdlib.h + +bind.so: $(topdir)/rlshell.h +histfile.so: $(topdir)/rlshell.h +nls.so: $(topdir)/rlshell.h +readline.so: $(topdir)/rlshell.h +shell.so: $(topdir)/rlshell.h +terminal.so: $(topdir)/rlshell.h +histexpand.so: $(topdir)/rlshell.h + +bind.so: $(topdir)/rlprivate.h +callback.so: $(topdir)/rlprivate.h +complete.so: $(topdir)/rlprivate.h +display.so: $(topdir)/rlprivate.h +input.so: $(topdir)/rlprivate.h +isearch.so: $(topdir)/rlprivate.h +kill.so: $(topdir)/rlprivate.h +macro.so: $(topdir)/rlprivate.h +mbutil.so: $(topdir)/rlprivate.h +misc.so: $(topdir)/rlprivate.h +nls.so: $(topdir)/rlprivate.h +parens.so: $(topdir)/rlprivate.h +readline.so: $(topdir)/rlprivate.h +rltty.so: $(topdir)/rlprivate.h +search.so: $(topdir)/rlprivate.h +signals.so: $(topdir)/rlprivate.h +terminal.so: $(topdir)/rlprivate.h +text.so: $(topdir)/rlprivate.h +undo.so: $(topdir)/rlprivate.h +util.so: $(topdir)/rlprivate.h +vi_mode.so: $(topdir)/rlprivate.h + +bind.so: $(topdir)/xmalloc.h +complete.so: $(topdir)/xmalloc.h +display.so: $(topdir)/xmalloc.h +funmap.so: $(topdir)/xmalloc.h +histexpand.so: $(topdir)/xmalloc.h +histfile.so: $(topdir)/xmalloc.h +history.so: $(topdir)/xmalloc.h +input.so: $(topdir)/xmalloc.h +isearch.so: $(topdir)/xmalloc.h +keymaps.so: $(topdir)/xmalloc.h +kill.so: $(topdir)/xmalloc.h +macro.so: $(topdir)/xmalloc.h +mbutil.so: $(topdir)/xmalloc.h +misc.so: $(topdir)/xmalloc.h +readline.so: $(topdir)/xmalloc.h +savestring.so: $(topdir)/xmalloc.h +search.so: $(topdir)/xmalloc.h +shell.so: $(topdir)/xmalloc.h +terminal.so: $(topdir)/xmalloc.h +text.so: $(topdir)/xmalloc.h +tilde.so: $(topdir)/xmalloc.h +undo.so: $(topdir)/xmalloc.h +util.so: $(topdir)/xmalloc.h +vi_mode.so: $(topdir)/xmalloc.h +xmalloc.so: $(topdir)/xmalloc.h + +complete.o: $(topdir)/rlmbutil.h +display.o: $(topdir)/rlmbutil.h +histexpand.o: $(topdir)/rlmbutil.h +input.o: $(topdir)/rlmbutil.h +isearch.o: $(topdir)/rlmbutil.h +mbutil.o: $(topdir)/rlmbutil.h +misc.o: $(topdir)/rlmbutil.h +readline.o: $(topdir)/rlmbutil.h +search.o: $(topdir)/rlmbutil.h +text.o: $(topdir)/rlmbutil.h +vi_mode.o: $(topdir)/rlmbutil.h + +bind.so: $(topdir)/bind.c +callback.so: $(topdir)/callback.c +compat.so: $(topdir)/compat.c +complete.so: $(topdir)/complete.c +display.so: $(topdir)/display.c +funmap.so: $(topdir)/funmap.c +input.so: $(topdir)/input.c +isearch.so: $(topdir)/isearch.c +keymaps.so: $(topdir)/keymaps.c $(topdir)/emacs_keymap.c $(topdir)/vi_keymap.c +kill.so: $(topdir)/kill.c +macro.so: $(topdir)/macro.c +mbutil.so: $(topdir)/mbutil.c +misc.so: $(topdir)/mbutil.c +nls.so: $(topdir)/nls.c +parens.so: $(topdir)/parens.c +readline.so: $(topdir)/readline.c +rltty.so: $(topdir)/rltty.c +savestring.so: $(topdir)/savestring.c +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 +tilde.so: $(topdir)/tilde.c +undo.so: $(topdir)/undo.c +util.so: $(topdir)/util.c +vi_mode.so: $(topdir)/vi_mode.c +xmalloc.so: $(topdir)/xmalloc.c + +histexpand.so: $(topdir)/histexpand.c +histfile.so: $(topdir)/histfile.c +history.so: $(topdir)/history.c +histsearch.so: $(topdir)/histsearch.c + +bind.so: bind.c +callback.so: callback.c +comapt.so: compat.c +complete.so: complete.c +display.so: display.c +funmap.so: funmap.c +input.so: input.c +isearch.so: isearch.c +keymaps.so: keymaps.c emacs_keymap.c vi_keymap.c +kill.so: kill.c +macro.so: macro.c +mbutil.so: mbutil.c +misc.so: misc.c +nls.so: nls.c +parens.so: parens.c +readline.so: readline.c +rltty.so: rltty.c +savestring.so: savestring.c +search.so: search.c +signals.so: signals.c +shell.so: shell.c +terminal.so: terminal.c +text.so: terminal.c +tilde.so: tilde.c +undo.so: undo.c +util.so: util.c +vi_mode.so: vi_mode.c +xmalloc.so: xmalloc.c + +histexpand.so: histexpand.c +histfile.so: histfile.c +history.so: history.c +histsearch.so: histsearch.c diff --git a/readline-4.3.orig/signals.c b/readline-4.3.orig/signals.c new file mode 100644 index 0000000..0a1468b --- /dev/null +++ b/readline-4.3.orig/signals.c @@ -0,0 +1,398 @@ +/* signals.c -- signal handling support for readline. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include /* Just for NULL. Yuck. */ +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include +#endif /* GWINSZ_IN_SYS_IOCTL */ + +#if defined (HANDLE_SIGNALS) +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" + +#if !defined (RETSIGTYPE) +# if defined (VOID_SIGHANDLER) +# define RETSIGTYPE void +# else +# define RETSIGTYPE int +# endif /* !VOID_SIGHANDLER */ +#endif /* !RETSIGTYPE */ + +#if defined (VOID_SIGHANDLER) +# define SIGHANDLER_RETURN return +#else +# define SIGHANDLER_RETURN return (0) +#endif + +/* This typedef is equivalent to the one for Function; it allows us + to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */ +typedef RETSIGTYPE SigHandler (); + +#if defined (HAVE_POSIX_SIGNALS) +typedef struct sigaction sighandler_cxt; +# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh) +#else +typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt; +# define sigemptyset(m) +#endif /* !HAVE_POSIX_SIGNALS */ + +static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); +static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); + +/* Exported variables for use by applications. */ + +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +int rl_catch_signals = 1; + +/* If non-zero, readline will install a signal handler for SIGWINCH. */ +#ifdef SIGWINCH +int rl_catch_sigwinch = 1; +#endif + +static int signals_set_flag; +static int sigwinch_set_flag; + +/* **************************************************************** */ +/* */ +/* Signal Handling */ +/* */ +/* **************************************************************** */ + +static sighandler_cxt old_int, old_term, old_alrm, old_quit; +#if defined (SIGTSTP) +static sighandler_cxt old_tstp, old_ttou, old_ttin; +#endif +#if defined (SIGWINCH) +static sighandler_cxt old_winch; +#endif + +/* Readline signal handler functions. */ + +static RETSIGTYPE +rl_signal_handler (sig) + int sig; +{ +#if defined (HAVE_POSIX_SIGNALS) + sigset_t set; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + long omask; +# else /* !HAVE_BSD_SIGNALS */ + sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + RL_SETSTATE(RL_STATE_SIGHANDLER); + +#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 || sig == SIGALRM) + rl_set_sighandler (sig, SIG_IGN, &dummy_cxt); +#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ + + switch (sig) + { + case SIGINT: + rl_free_line_state (); + /* FALLTHROUGH */ + +#if defined (SIGTSTP) + case SIGTSTP: + case SIGTTOU: + case SIGTTIN: +#endif /* SIGTSTP */ + case SIGALRM: + case SIGTERM: + case SIGQUIT: + rl_cleanup_after_signal (); + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); + sigdelset (&set, sig); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + omask = sigblock (0); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +#if defined (__EMX__) + signal (sig, SIG_ACK); +#endif + + kill (getpid (), sig); + + /* Let the signal that we just sent through. */ +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (omask & ~(sigmask (sig))); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + rl_reset_after_signal (); + } + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} + +#if defined (SIGWINCH) +static RETSIGTYPE +rl_sigwinch_handler (sig) + int sig; +{ + SigHandler *oh; + +#if defined (MUST_REINSTALL_SIGHANDLERS) + sighandler_cxt dummy_winch; + + /* We don't want to change old_winch -- it holds the state of SIGWINCH + disposition set by the calling application. We need this state + because we call the application's SIGWINCH handler after updating + our own idea of the screen size. */ + rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch); +#endif + + RL_SETSTATE(RL_STATE_SIGHANDLER); + rl_resize_terminal (); + + /* If another sigwinch handler has been installed, call it. */ + oh = (SigHandler *)old_winch.sa_handler; + if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL) + (*oh) (sig); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} +#endif /* SIGWINCH */ + +/* Functions to manage signal handling. */ + +#if !defined (HAVE_POSIX_SIGNALS) +static int +rl_sigaction (sig, nh, oh) + int sig; + sighandler_cxt *nh, *oh; +{ + oh->sa_handler = signal (sig, nh->sa_handler); + return 0; +} +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Set up a readline-specific signal handler, saving the old signal + information in OHANDLER. Return the old signal handler, like + signal(). */ +static SigHandler * +rl_set_sighandler (sig, handler, ohandler) + int sig; + SigHandler *handler; + sighandler_cxt *ohandler; +{ + sighandler_cxt old_handler; +#if defined (HAVE_POSIX_SIGNALS) + struct sigaction act; + + act.sa_handler = handler; + act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */ + sigemptyset (&act.sa_mask); + sigemptyset (&ohandler->sa_mask); + sigaction (sig, &act, &old_handler); +#else + old_handler.sa_handler = (SigHandler *)signal (sig, handler); +#endif /* !HAVE_POSIX_SIGNALS */ + + /* XXX -- assume we have memcpy */ + /* If rl_set_signals is called twice in a row, don't set the old handler to + rl_signal_handler, because that would cause infinite recursion. */ + if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler) + memcpy (ohandler, &old_handler, sizeof (sighandler_cxt)); + + return (ohandler->sa_handler); +} + +static void +rl_maybe_set_sighandler (sig, handler, ohandler) + int sig; + SigHandler *handler; + sighandler_cxt *ohandler; +{ + sighandler_cxt dummy; + SigHandler *oh; + + sigemptyset (&dummy.sa_mask); + oh = rl_set_sighandler (sig, handler, ohandler); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (sig, ohandler, &dummy); +} + +int +rl_set_signals () +{ + sighandler_cxt dummy; + SigHandler *oh; + + if (rl_catch_signals && signals_set_flag == 0) + { + rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); + rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); + rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); + + oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART) + /* If the application using readline has already installed a signal + handler with SA_RESTART, SIGALRM will cause reads to be restarted + automatically, so readline should just get out of the way. Since + we tested for SIG_IGN above, we can just test for SIG_DFL here. */ + if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART)) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#endif /* HAVE_POSIX_SIGNALS */ + +#if defined (SIGTSTP) + rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin); +#endif /* SIGTTIN */ + + signals_set_flag = 1; + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 0) + { + rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch); + sigwinch_set_flag = 1; + } +#endif /* SIGWINCH */ + + return 0; +} + +int +rl_clear_signals () +{ + sighandler_cxt dummy; + + if (rl_catch_signals && signals_set_flag == 1) + { + sigemptyset (&dummy.sa_mask); + + rl_sigaction (SIGINT, &old_int, &dummy); + rl_sigaction (SIGTERM, &old_term, &dummy); + rl_sigaction (SIGQUIT, &old_quit, &dummy); + rl_sigaction (SIGALRM, &old_alrm, &dummy); + +#if defined (SIGTSTP) + rl_sigaction (SIGTSTP, &old_tstp, &dummy); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_sigaction (SIGTTOU, &old_ttou, &dummy); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_sigaction (SIGTTIN, &old_ttin, &dummy); +#endif /* SIGTTIN */ + + signals_set_flag = 0; + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 1) + { + sigemptyset (&dummy.sa_mask); + rl_sigaction (SIGWINCH, &old_winch, &dummy); + sigwinch_set_flag = 0; + } +#endif + + return 0; +} + +/* Clean up the terminal and readline state after catching a signal, before + resending it to the calling application. */ +void +rl_cleanup_after_signal () +{ + _rl_clean_up_for_exit (); + (*rl_deprep_term_function) (); + rl_clear_signals (); + rl_clear_pending_input (); +} + +/* Reset the terminal and readline state after a signal handler returns. */ +void +rl_reset_after_signal () +{ + (*rl_prep_term_function) (_rl_meta_flag); + rl_set_signals (); +} + +/* Free up the readline variable line state for the current line (undo list, + any partial history entry, any keyboard macros in progress, and any + numeric arguments in process) after catching a signal, before calling + rl_cleanup_after_signal(). */ +void +rl_free_line_state () +{ + register HIST_ENTRY *entry; + + rl_free_undo_list (); + + entry = current_history (); + if (entry) + entry->data = (char *)NULL; + + _rl_kill_kbd_macro (); + rl_clear_message (); + _rl_init_argument (); +} + +#endif /* HANDLE_SIGNALS */ diff --git a/readline-4.3.orig/support/config.guess b/readline-4.3.orig/support/config.guess new file mode 100755 index 0000000..5668108 --- /dev/null +++ b/readline-4.3.orig/support/config.guess @@ -0,0 +1,1393 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# 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 +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +elif (test -f /usr/5bin/uname) >/dev/null 2>&1 ; then # bash + PATH=$PATH:/usr/5bin +fi + +UNAME=`(uname) 2>/dev/null` || UNAME=unknown # bash +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + # NOTE -- begin cases added for bash (mostly legacy) -- NOTE + mac68k:machten:*:*) + echo mac68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + concurrent*:*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo concurrent-concurrent-sysv3 + else + echo concurrent-concurrent-bsd + fi + exit 0 ;; + ppc*:SunOS:5.*:*) + echo ppc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sparc:UNIX_SV:4.*:*) + echo sparc-unknown-sysv${UNAME_RELEASE} + exit 0 ;; + mips:UNIX_SV:4.*:*) + echo mips-mips-sysv${UNAME_RELEASE} + exit 0 ;; + mips:OSF*1:*:*) + echo mips-mips-osf1 + exit 0 ;; + mips:4.4BSD:*:*) + echo mips-mips-bsd4.4 + exit 0 ;; + MIS*:SMP_DC.OSx:*:dcosx) # not the same as below + echo pyramid-pyramid-sysv4 + exit 0 ;; + news*:NEWS*:*:*) + echo mips-sony-newsos${UNAME_RELEASE} + exit 0 ;; + *370:AIX:*:*) + echo ibm370-ibm-aix${UNAME_RELEASE} + exit 0 ;; + ksr1:OSF*1:*:*) + echo ksr1-ksr-osf1 + exit 0 ;; + esa:OSF*1:*:* | ESA:OSF*:*:*) + echo esa-ibm-osf1 + exit 0 ;; + DNP*:DNIX:*:*) + echo m68k-dnix-sysv + exit 0 ;; + *3b2*:*:*:*) + echo we32k-att-sysv3 + exit 0 ;; + Alpha*:Windows_NT:*:SP*) + echo alpha-pc-opennt + exit 0 ;; + *:Windows_NT:*:SP*) + echo i386-pc-opennt + exit 0 ;; + + # NOTE -- end legacy cases added for bash -- NOTE + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + vax:OpenBSD:*:*) # bash + echo vax-dec-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +# NOTE -- Begin fallback cases added for bash -- NOTE +case "$UNAME" in +uts) echo uts-amdahl-sysv${UNAME_RELEASE}; exit 0 ;; +esac + +if [ -f /bin/fxc.info ]; then + echo fxc-alliant-concentrix + exit 0 +fi +# NOTE -- End fallback cases added for bash -- NOTE + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/readline-4.3.orig/support/config.sub b/readline-4.3.orig/support/config.sub new file mode 100644 index 0000000..538dc09 --- /dev/null +++ b/readline-4.3.orig/support/config.sub @@ -0,0 +1,1497 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + + # NOTE -- BEGIN cases added for Bash -- NOTE + butterfly-bbn* | cadmus-* | ews*-nec | masscomp-masscomp \ + | tandem-* | symmetric-* | drs6000-icl | *-*ardent | concurrent-* \ + | ksr1-* | esa-ibm | fxc-alliant | *370-amdahl | sx[45]*-nec ) + ;; + # NOTE -- END cases added for Bash -- NOTE + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax | multimax) # bash + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hbullx20-bull) + basic_machine=m68k-bull # bash + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + ibm032-*) + basic_machine=ibmrt-ibm # bash + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386-go32) + basic_machine=i386-pc # bash + os=-go32 + ;; + i386-mingw32) + basic_machine=i386-pc # bash + os=-mingw32 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + luna88k-omron* | m88k-omron*) # bash + basic_machine=m88k-omron + ;; + magicstation*) + basic_machine=magicstation-unknown # bash + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + odt | odt3 | odt4) # SCO Open Desktop + basic_machine=i386-pc # bash + os=-sco3.2v4 + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + osr5 | sco5) # SCO Open Server + basic_machine=i386-pc # bash + os=-sco3.2v5 + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + uw2 | unixware | unixware2) # bash + basic_machine=i386-pc + os=-sysv4.2uw2.1 + ;; + uw7 | unixware7) # bash + basic_machine=i386-pc + os=-sysv5uw7 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware7*) # bash + os=-sysv5uw7 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + # NOTE -- BEGIN CASES ADDED FOR Bash -- NOTE + -powerux* | -superux*) + ;; + # NOTE -- END CASES ADDED FOR Bash -- NOTE + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + -sysvr5) # bash + os=-sysv5 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) # bash + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/readline-4.3.orig/support/install.sh b/readline-4.3.orig/support/install.sh new file mode 100755 index 0000000..0cac004 --- /dev/null +++ b/readline-4.3.orig/support/install.sh @@ -0,0 +1,247 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/readline-4.3.orig/support/mkdirs b/readline-4.3.orig/support/mkdirs new file mode 100755 index 0000000..ce4fb23 --- /dev/null +++ b/readline-4.3.orig/support/mkdirs @@ -0,0 +1,48 @@ +#! /bin/sh +# +# mkdirs - a work-alike for `mkdir -p' +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +for dir +do + + test -d "$dir" && continue + + tomake=$dir + while test -n "$dir" ; do + # dir=${dir%/*} + # dir=`expr "$dir" ':' '\(/.*\)/[^/]*'` + if dir=`expr "$dir" ':' '\(.*\)/[^/]*'`; then + tomake="$dir $tomake" + else + dir= + fi + done + + for d in $tomake + do + test -d "$d" && continue + echo mkdir "$d" + mkdir "$d" + done +done + +exit 0 diff --git a/readline-4.3.orig/support/mkdist b/readline-4.3.orig/support/mkdist new file mode 100755 index 0000000..06e6155 --- /dev/null +++ b/readline-4.3.orig/support/mkdist @@ -0,0 +1,120 @@ +#! /bin/bash - +# +# mkdist - make a distribution directory from a master manifest file +# +# usage: mkdist [-m manifest] [-s srcdir] [-r rootname] [-v] version +# +# SRCDIR defaults to src +# MANIFEST defaults to $SRCDIR/MANIFEST +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +SRCDIR=src +ROOTNAME=bash + +usage() +{ + echo usage: mkdist [-m manifest] [-s srcdir] [-r rootname] [-v] version 1>&2 + exit 2 +} + +vmsg() +{ + if [ -n "$verbose" ]; then + echo mkdist: "$@" + fi +} + +while getopts m:s:r:v name +do + case $name in + m) MANIFEST=$OPTARG ;; + s) SRCDIR=$OPTARG ;; + r) ROOTNAME=$OPTARG ;; + v) verbose=yes ;; + ?) usage ;; + esac +done + +: ${MANIFEST:=$SRCDIR/MANIFEST} + +vmsg using $MANIFEST + +shift $(( $OPTIND - 1 )) + +if [ $# -lt 1 ]; then + usage +fi + +version=$1 +newdir=${ROOTNAME}-$version + +vmsg creating distribution for $ROOTNAME version $version in $newdir + +if [ ! -d $newdir ]; then + mkdir $newdir || { echo $0: cannot make directory $newdir 1>&2 ; exit 1; } +fi + +dirmode=755 +filmode=644 + +while read fname type mode +do + [ -z "$fname" ] && continue + + case "$fname" in + \#*) continue ;; + esac + + case "$type" in + d) mkdir $newdir/$fname ;; + f) cp -p $SRCDIR/$fname $newdir/$fname ;; + s) ln -s $mode $newdir/$fname ; mode= ;; # symlink + l) ln $mode $newdir/$fname ; mode= ;; # hard link + *) echo "unknown file type $type" 1>&2 ;; + esac + + if [ -n "$mode" ]; then + chmod $mode $newdir/$fname + fi + +done < $MANIFEST + +# cut off the `-alpha' in something like `2.0-alpha', leaving just the +# numeric version +#version=${version%%-*} + +#case "$version" in +#*.*.*) vers=${version%.*} ;; +#*.*) vers=${version} ;; +#esac + +#echo $vers > $newdir/.distribution + +#case "$version" in +#*.*.*) plevel=${version##*.} ;; +#*) plevel=0 ;; +#esac +#[ -z "$plevel" ] && plevel=0 +#echo ${plevel} > $newdir/.patchlevel + +vmsg $newdir created + +exit 0 diff --git a/readline-4.3.orig/support/shlib-install b/readline-4.3.orig/support/shlib-install new file mode 100755 index 0000000..654cfa9 --- /dev/null +++ b/readline-4.3.orig/support/shlib-install @@ -0,0 +1,156 @@ +#! /bin/sh +# +# 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 +# +# Chet Ramey +# chet@po.cwru.edu + +# +# defaults +# +INSTALLDIR=/usr/local/lib +LDCONFIG=ldconfig + +PROGNAME=`basename $0` +USAGE="$PROGNAME [-D] -O host_os -d installation-dir -i install-prog [-U] library" + +# process options + +while [ $# -gt 0 ]; do + case "$1" in + -O) shift; host_os="$1"; shift ;; + -d) shift; INSTALLDIR="$1"; shift ;; + -i) shift; INSTALLPROG="$1" ; shift ;; + -D) echo=echo ; shift ;; + -U) uninstall=true ; shift ;; + -*) echo "$USAGE" >&2 ; exit 2;; + *) break ;; + esac +done + +# set install target name +LIBNAME="$1" + +if [ -z "$LIBNAME" ]; then + echo "$USAGE" >&2 + exit 2 +fi + +OLDSUFF=old +MV=mv +RM="rm -f" +LN="ln -s" + +# pre-install + +if [ -z "$uninstall" ]; then + ${echo} $RM ${INSTALLDIR}/${LIBNAME}.${OLDSUFF} + if [ -f "$INSTALLDIR/$LIBNAME" ]; then + ${echo} $MV $INSTALLDIR/$LIBNAME ${INSTALLDIR}/${LIBNAME}.${OLDSUFF} + fi +fi + +# install/uninstall + +if [ -z "$uninstall" ] ; then + ${echo} eval ${INSTALLPROG} $LIBNAME ${INSTALLDIR}/${LIBNAME} +else + ${echo} ${RM} ${INSTALLDIR}/${LIBNAME} +fi + +# post-install/uninstall + +# HP-UX and Darwin/MacOS X require that a shared library have execute permission +case "$host_os" in +hpux*|darwin*|macosx*) + if [ -z "$uninstall" ]; then + chmod 555 ${INSTALLDIR}/${LIBNAME} + fi ;; +*) ;; +esac + +case "$LIBNAME" in +*.*.[0-9].[0-9]) # libname.so.M.N + LINK2=`echo $LIBNAME | sed 's:\(.*\..*\.[0-9]\)\.[0-9]:\1:'` # libname.so.M + LINK1=`echo $LIBNAME | sed 's:\(.*\..*\)\.[0-9]\.[0-9]:\1:'` # libname.so + ;; +*.*.[0-9]) # libname.so.M + LINK1=`echo $LIBNAME | sed 's:\(.*\..*\)\.[0-9]:\1:'` # libname.so + ;; +*.[0-9]) # libname.M + LINK1=`echo $LIBNAME | sed 's:\(.*\)\.[0-9]:\1:'` # libname + ;; +*.[0-9].[0-9].dylib) # libname.M.N.dylib + LINK2=`echo $LIBNAME | sed 's:\(.*\.[0-9]\)\.[0-9]:\1:'` # libname.M.dylib + 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' + +# +# Create symlinks to the installed library. This section is incomplete. +# +case "$host_os" in +*linux*|bsdi4*|*gnu*|darwin*|macosx*) + # libname.so.M -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK2 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + fi + + # libname.so -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + ;; + +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 + fi + ;; + + +# FreeBSD 3.x and above can have either a.out or ELF shared libraries +freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) + if [ -x /usr/bin/objformat ] && [ "`/usr/bin/objformat`" = "elf" ]; then + # libname.so -> libname.so.M + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + else + # libname.so.M -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK2 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + fi + + # libname.so -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + fi + ;; + +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} + fi + ;; + +*) ;; +esac + +exit 0 diff --git a/readline-4.3.orig/support/shobj-conf b/readline-4.3.orig/support/shobj-conf new file mode 100755 index 0000000..6bd7fb1 --- /dev/null +++ b/readline-4.3.orig/support/shobj-conf @@ -0,0 +1,458 @@ +#! /bin/sh +# +# shobj-conf -- output a series of variable assignments to be substituted +# into a Makefile by configure which specify system-dependent +# information for creating shared objects that may be loaded +# into bash with `enable -f' +# +# usage: shobj-conf [-C compiler] -c host_cpu -o host_os -v host_vendor +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +# +# defaults +# +SHOBJ_STATUS=supported +SHLIB_STATUS=supported + +SHOBJ_CC=cc +SHOBJ_CFLAGS= +SHOBJ_LD= +SHOBJ_LDFLAGS= +SHOBJ_XLDFLAGS= +SHOBJ_LIBS= + +SHLIB_XLDFLAGS= +SHLIB_LIBS= +SHLIB_LIBSUFF='so' + +SHLIB_LIBVERSION='$(SHLIB_LIBSUFF)' + +PROGNAME=`basename $0` +USAGE="$PROGNAME [-C compiler] -c host_cpu -o host_os -v host_vendor" + +while [ $# -gt 0 ]; do + case "$1" in + -C) shift; SHOBJ_CC="$1"; shift ;; + -c) shift; host_cpu="$1"; shift ;; + -o) shift; host_os="$1"; shift ;; + -v) shift; host_vendor="$1"; shift ;; + *) echo "$USAGE" >&2 ; exit 2;; + esac +done + +case "${host_os}-${SHOBJ_CC}" in +sunos4*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD=/usr/bin/ld + SHOBJ_LDFLAGS='-assert pure-text' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +sunos4*) + SHOBJ_CFLAGS=-pic + SHOBJ_LD=/usr/bin/ld + SHOBJ_LDFLAGS='-assert pure-text' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +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,$@' + +# SHLIB_XLDFLAGS='-R $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sunos5*|solaris2*) + SHOBJ_CFLAGS='-K pic' + SHOBJ_LD=/usr/ccs/bin/ld + SHOBJ_LDFLAGS='-G -dy -z text -i -h $@' + +# SHLIB_XLDFLAGS='-R $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +# All versions of Linux or the semi-mythical GNU Hurd. +linux*|gnu*) + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir) -Wl,-soname,`basename $@ $(SHLIB_MINOR)`' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +freebsd2* | netbsd*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-x -Bshareable' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +# FreeBSD-3.x ELF +freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + + if [ -x /usr/bin/objformat ] && [ "`/usr/bin/objformat`" = "elf" ]; then + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + else + SHOBJ_LDFLAGS='-shared' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + fi + ;; + +# Darwin/MacOS X +darwin*|macosx*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=supported + + SHOBJ_CFLAGS='-dynamic -fno-common' + + SHOBJ_LD=/usr/bin/libtool + + 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' + + SHLIB_LIBS='-lSystem' + ;; + +openbsd*) + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +bsdi2*) + SHOBJ_CC=shlicc2 + SHOBJ_CFLAGS= + SHOBJ_LD=ld + SHOBJ_LDFLAGS=-r + SHOBJ_LIBS=-lc_s.2.1.0 + + # BSD/OS 2.x and 3.x `shared libraries' are too much of a pain in + # the ass -- they require changing {/usr/lib,etc}/shlib.map on + # each system, and the library creation process is byzantine + SHLIB_STATUS=unsupported + ;; + +bsdi3*) + SHOBJ_CC=shlicc2 + SHOBJ_CFLAGS= + SHOBJ_LD=ld + SHOBJ_LDFLAGS=-r + SHOBJ_LIBS=-lc_s.3.0.0 + + # BSD/OS 2.x and 3.x `shared libraries' are too much of a pain in + # the ass -- they require changing {/usr/lib,etc}/shlib.map on + # each system, and the library creation process is byzantine + SHLIB_STATUS=unsupported + ;; + +bsdi4*) + # BSD/OS 4.x now supports ELF and SunOS-style dynamically-linked + # shared libraries. gcc 2.x is the standard compiler, and the + # `normal' gcc options should work as they do in Linux. + + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-soname,`basename $@ $(SHLIB_MINOR)`' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +osf*-*gcc*) + # Fix to use gcc linker driver from bfischer@TechFak.Uni-Bielefeld.DE + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +osf*) + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-shared -soname $@ -expect_unresolved "*"' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +aix4.[2-9]*-*gcc*) # lightly tested by jik@cisco.com + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='ld' + SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall' + SHOBJ_XLDFLAGS='-G' + + SHLIB_XLDFLAGS='-bM:SRE' + SHLIB_LIBS='-lcurses -lc' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +aix4.[2-9]*) + SHOBJ_CFLAGS=-K + SHOBJ_LD='ld' + SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall' + SHOBJ_XLDFLAGS='-G' + + SHLIB_XLDFLAGS='-bM:SRE' + SHLIB_LIBS='-lcurses -lc' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +# +# THE FOLLOWING ARE UNTESTED -- and some may not support the dlopen interface +# +irix[56]*-*gcc*) + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +irix[56]*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld +# SHOBJ_LDFLAGS='-call_shared -hidden_symbol -no_unresolved -soname $@' +# Change from David Kaelbling . If you have problems, +# remove the `-no_unresolved' + SHOBJ_LDFLAGS='-shared -no_unresolved -soname $@' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux9*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s' + + SHLIB_XLDFLAGS='-Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux9*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +hpux10*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s' + + SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux10*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s +h $@' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +hpux11*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' +# SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,-B,symbolic -Wl,+s -Wl,+std -Wl,+h,$@' + SHOBJ_LDFLAGS='-shared -fpic -Wl,-b -Wl,+s -Wl,+h,$@' + + SHLIB_XLDFLAGS='-Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux11*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s +h $@' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +sysv4*-*gcc*) + SHOBJ_CFLAGS=-shared + SHOBJ_LDFLAGS='-shared -h $@' + SHOBJ_LD='${CC}' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv4*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-dy -z text -G -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sco3.2v5*-*gcc*) + SHOBJ_CFLAGS='-fpic' # DEFAULTS TO ELF + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sco3.2v5*) + SHOBJ_CFLAGS='-K pic -b elf' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -b elf -dy -z text -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5uw7*-*gcc*) + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5uw7*) + 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}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +dgux*) + SHOBJ_CFLAGS='-K pic' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -dy -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +msdos*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + ;; + +# +# Rely on correct gcc configuration for everything else +# +*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + ;; + +esac + +echo SHOBJ_CC=\'"$SHOBJ_CC"\' +echo SHOBJ_CFLAGS=\'"$SHOBJ_CFLAGS"\' +echo SHOBJ_LD=\'"$SHOBJ_LD"\' +echo SHOBJ_LDFLAGS=\'"$SHOBJ_LDFLAGS"\' +echo SHOBJ_XLDFLAGS=\'"$SHOBJ_XLDFLAGS"\' +echo SHOBJ_LIBS=\'"$SHOBJ_LIBS"\' + +echo SHLIB_XLDFLAGS=\'"$SHLIB_XLDFLAGS"\' +echo SHLIB_LIBS=\'"$SHLIB_LIBS"\' +echo SHLIB_LIBSUFF=\'"$SHLIB_LIBSUFF"\' +echo SHLIB_LIBVERSION=\'"$SHLIB_LIBVERSION"\' + +echo SHOBJ_STATUS=\'"$SHOBJ_STATUS"\' +echo SHLIB_STATUS=\'"$SHLIB_STATUS"\' + +exit 0 diff --git a/readline-4.3.orig/support/wcwidth.c b/readline-4.3.orig/support/wcwidth.c new file mode 100644 index 0000000..ace9a3a --- /dev/null +++ b/readline-4.3.orig/support/wcwidth.c @@ -0,0 +1,236 @@ +/* + * This is an implementation of wcwidth() and wcswidth() as defined in + * "The Single UNIX Specification, Version 2, The Open Group, 1997" + * + * + * Markus Kuhn -- 2001-09-08 -- public domain + */ + +#include + +struct interval { + unsigned short first; + unsigned short last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * FullWidth (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +int wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + static const struct interval combining[] = { + { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 }, + { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, + { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, + { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, + { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, + { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, + { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, + { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, + { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, + { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, + { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, + { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F }, + { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A }, + { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2ffff))); +} + + +int wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following function is the same as wcwidth(), except that + * spacing characters in the East Asian Ambiguous (A) category as + * defined in Unicode Technical Report #11 have a column width of 2. + * This experimental variant might be useful for users of CJK legacy + * encodings who want to migrate to UCS. It is not otherwise + * recommended for general use. + */ +static int wcwidth_cjk(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AD, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0300, 0x034E }, + { 0x0360, 0x0362 }, { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, + { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, + { 0x0410, 0x044F }, { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, + { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, { 0x201C, 0x201D }, + { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, { 0x2030, 0x2030 }, + { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, { 0x203B, 0x203B }, + { 0x203E, 0x203E }, { 0x2074, 0x2074 }, { 0x207F, 0x207F }, + { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, { 0x2103, 0x2103 }, + { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, { 0x2113, 0x2113 }, + { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 }, + { 0x212B, 0x212B }, { 0x2153, 0x2155 }, { 0x215B, 0x215E }, + { 0x2160, 0x216B }, { 0x2170, 0x2179 }, { 0x2190, 0x2199 }, + { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 }, + { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, + { 0x2207, 0x2208 }, { 0x220B, 0x220B }, { 0x220F, 0x220F }, + { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, { 0x221A, 0x221A }, + { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, + { 0x2227, 0x222C }, { 0x222E, 0x222E }, { 0x2234, 0x2237 }, + { 0x223C, 0x223D }, { 0x2248, 0x2248 }, { 0x224C, 0x224C }, + { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, + { 0x226A, 0x226B }, { 0x226E, 0x226F }, { 0x2282, 0x2283 }, + { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, + { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, + { 0x2329, 0x232A }, { 0x2460, 0x24BF }, { 0x24D0, 0x24E9 }, + { 0x2500, 0x254B }, { 0x2550, 0x2574 }, { 0x2580, 0x258F }, + { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, + { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, + { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, + { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, + { 0x2605, 0x2606 }, { 0x2609, 0x2609 }, { 0x260E, 0x260F }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x3008, 0x300B }, { 0x3014, 0x3015 }, + { 0x3018, 0x301B }, { 0xFFFD, 0xFFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return wcwidth(ucs); +} + + +int wcswidth_cjk(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} diff --git a/readline-4.3.orig/tcap.h b/readline-4.3.orig/tcap.h new file mode 100644 index 0000000..58ab894 --- /dev/null +++ b/readline-4.3.orig/tcap.h @@ -0,0 +1,60 @@ +/* tcap.h -- termcap library functions and variables. */ + +/* Copyright (C) 1996 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLTCAP_H_) +#define _RLTCAP_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#if defined (HAVE_TERMCAP_H) +# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES) +# include "rltty.h" +# endif +# include +#else + +/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. + Unfortunately, PC is a global variable used by the termcap library. */ +#ifdef PC +# undef PC +#endif + +extern char PC; +extern char *UP, *BC; + +extern short ospeed; + +extern int tgetent (); +extern int tgetflag (); +extern int tgetnum (); +extern char *tgetstr (); + +extern int tputs (); + +extern char *tgoto (); + +#endif /* HAVE_TERMCAP_H */ + +#endif /* !_RLTCAP_H_ */ diff --git a/readline-4.3.orig/terminal.c b/readline-4.3.orig/terminal.c new file mode 100644 index 0000000..f3f5b6c --- /dev/null +++ b/readline-4.3.orig/terminal.c @@ -0,0 +1,662 @@ +/* terminal.c -- controlling the terminal with termcap. */ + +/* Copyright (C) 1996 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ + +#include "rltty.h" +#include "tcap.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) +#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) + +/* **************************************************************** */ +/* */ +/* Terminal and Termcap */ +/* */ +/* **************************************************************** */ + +static char *term_buffer = (char *)NULL; +static char *term_string_buffer = (char *)NULL; + +static int tcap_initialized; + +#if !defined (__linux__) +# if defined (__EMX__) || defined (NEED_EXTERN_PC) +extern +# endif /* __EMX__ || NEED_EXTERN_PC */ +char PC, *BC, *UP; +#endif /* __linux__ */ + +/* Some strings to control terminal actions. These are output by tputs (). */ +char *_rl_term_clreol; +char *_rl_term_clrpag; +char *_rl_term_cr; +char *_rl_term_backspace; +char *_rl_term_goto; +char *_rl_term_pc; + +/* Non-zero if we determine that the terminal can do character insertion. */ +int _rl_terminal_can_insert = 0; + +/* How to insert characters. */ +char *_rl_term_im; +char *_rl_term_ei; +char *_rl_term_ic; +char *_rl_term_ip; +char *_rl_term_IC; + +/* How to delete characters. */ +char *_rl_term_dc; +char *_rl_term_DC; + +#if defined (HACK_TERMCAP_MOTION) +char *_rl_term_forward_char; +#endif /* HACK_TERMCAP_MOTION */ + +/* How to go up a line. */ +char *_rl_term_up; + +/* A visible bell; char if the terminal can be made to flash the screen. */ +static char *_rl_visible_bell; + +/* Non-zero means the terminal can auto-wrap lines. */ +int _rl_term_autowrap; + +/* Non-zero means that this terminal has a meta key. */ +static int term_has_meta; + +/* The sequences to write to turn on and off the meta key, if this + terminal has one. */ +static char *_rl_term_mm; +static char *_rl_term_mo; + +/* The key sequences output by the arrow keys, if this terminal has any. */ +static char *_rl_term_ku; +static char *_rl_term_kd; +static char *_rl_term_kr; +static char *_rl_term_kl; + +/* How to initialize and reset the arrow keys, if this terminal has any. */ +static char *_rl_term_ks; +static char *_rl_term_ke; + +/* The key sequences sent by the Home and End keys, if any. */ +static char *_rl_term_kh; +static char *_rl_term_kH; +static char *_rl_term_at7; /* @7 */ + +/* Insert key */ +static char *_rl_term_kI; + +/* Cursor control */ +static char *_rl_term_vs; /* very visible */ +static char *_rl_term_ve; /* normal */ + +static void bind_termcap_arrow_keys PARAMS((Keymap)); + +/* Variables that hold the screen dimensions, used by the display code. */ +int _rl_screenwidth, _rl_screenheight, _rl_screenchars; + +/* Non-zero means the user wants to enable the keypad. */ +int _rl_enable_keypad; + +/* Non-zero means the user wants to enable a meta key. */ +int _rl_enable_meta = 1; + +#if defined (__EMX__) +static void +_emx_get_screensize (swp, shp) + int *swp, *shp; +{ + int sz[2]; + + _scrsize (sz); + + if (swp) + *swp = sz[0]; + if (shp) + *shp = sz[1]; +} +#endif + +/* Get readline's idea of the screen size. TTY is a file descriptor open + to the terminal. If IGNORE_ENV is true, we do not pay attention to the + values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being + non-null serve to check whether or not we have initialized termcap. */ +void +_rl_get_screen_size (tty, ignore_env) + int tty, ignore_env; +{ + char *ss; +#if defined (TIOCGWINSZ) + struct winsize window_size; +#endif /* TIOCGWINSZ */ + +#if defined (TIOCGWINSZ) + if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) + { + _rl_screenwidth = (int) window_size.ws_col; + _rl_screenheight = (int) window_size.ws_row; + } +#endif /* TIOCGWINSZ */ + +#if defined (__EMX__) + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); +#endif + + /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV + is unset. */ + if (_rl_screenwidth <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) + _rl_screenwidth = atoi (ss); + +#if !defined (__DJGPP__) + if (_rl_screenwidth <= 0 && term_string_buffer) + _rl_screenwidth = tgetnum ("co"); +#endif + } + + /* Environment variable LINES overrides setting of "li" if IGNORE_ENV + is unset. */ + if (_rl_screenheight <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) + _rl_screenheight = atoi (ss); + +#if !defined (__DJGPP__) + if (_rl_screenheight <= 0 && term_string_buffer) + _rl_screenheight = tgetnum ("li"); +#endif + } + + /* If all else fails, default to 80x24 terminal. */ + if (_rl_screenwidth <= 1) + _rl_screenwidth = 80; + + if (_rl_screenheight <= 0) + _rl_screenheight = 24; + + /* If we're being compiled as part of bash, set the environment + variables $LINES and $COLUMNS to new values. Otherwise, just + do a pair of putenv () or setenv () calls. */ + sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); + + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +_rl_set_screen_size (rows, cols) + int rows, cols; +{ + if (rows == 0 || cols == 0) + return; + + _rl_screenheight = rows; + _rl_screenwidth = cols; + + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +rl_set_screen_size (rows, cols) + int rows, cols; +{ + _rl_set_screen_size (rows, cols); +} + +void +rl_get_screen_size (rows, cols) + int *rows, *cols; +{ + if (rows) + *rows = _rl_screenheight; + if (cols) + *cols = _rl_screenwidth; +} + +void +rl_resize_terminal () +{ + if (readline_echoing_p) + { + _rl_get_screen_size (fileno (rl_instream), 1); + if (CUSTOM_REDISPLAY_FUNC ()) + rl_forced_update_display (); + else + _rl_redisplay_after_sigwinch (); + } +} + +struct _tc_string { + const char *tc_var; + char **tc_value; +}; + +/* This should be kept sorted, just in case we decide to change the + search algorithm to something smarter. */ +static struct _tc_string tc_strings[] = +{ + { "@7", &_rl_term_at7 }, + { "DC", &_rl_term_DC }, + { "IC", &_rl_term_IC }, + { "ce", &_rl_term_clreol }, + { "cl", &_rl_term_clrpag }, + { "cr", &_rl_term_cr }, + { "dc", &_rl_term_dc }, + { "ei", &_rl_term_ei }, + { "ic", &_rl_term_ic }, + { "im", &_rl_term_im }, + { "kH", &_rl_term_kH }, /* home down ?? */ + { "kI", &_rl_term_kI }, /* insert */ + { "kd", &_rl_term_kd }, + { "ke", &_rl_term_ke }, /* end keypad mode */ + { "kh", &_rl_term_kh }, /* home */ + { "kl", &_rl_term_kl }, + { "kr", &_rl_term_kr }, + { "ks", &_rl_term_ks }, /* start keypad mode */ + { "ku", &_rl_term_ku }, + { "le", &_rl_term_backspace }, + { "mm", &_rl_term_mm }, + { "mo", &_rl_term_mo }, +#if defined (HACK_TERMCAP_MOTION) + { "nd", &_rl_term_forward_char }, +#endif + { "pc", &_rl_term_pc }, + { "up", &_rl_term_up }, + { "vb", &_rl_visible_bell }, + { "vs", &_rl_term_vs }, + { "ve", &_rl_term_ve }, +}; + +#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) + +/* Read the desired terminal capability strings into BP. The capabilities + are described in the TC_STRINGS table. */ +static void +get_term_capabilities (bp) + char **bp; +{ +#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ + 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; +} + +int +_rl_init_terminal_io (terminal_name) + const char *terminal_name; +{ + const char *term; + char *buffer; + int tty, tgetent_ret; + + 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"; + + /* I've separated this out for later work on not calling tgetent at all + if the calling application has supplied a custom redisplay function, + (and possibly if the application has supplied a custom input function). */ + if (CUSTOM_REDISPLAY_FUNC()) + { + tgetent_ret = -1; + } + else + { + if (term_string_buffer == 0) + term_string_buffer = (char *)xmalloc(2032); + + if (term_buffer == 0) + term_buffer = (char *)xmalloc(4080); + + buffer = term_string_buffer; + + tgetent_ret = tgetent (term_buffer, term); + } + + if (tgetent_ret <= 0) + { + FREE (term_string_buffer); + FREE (term_buffer); + buffer = term_buffer = term_string_buffer = (char *)NULL; + + _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ + +#if defined (__EMX__) + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); + _rl_screenwidth--; +#else /* !__EMX__ */ + _rl_get_screen_size (tty, 0); +#endif /* !__EMX__ */ + + /* Defaults. */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + { + _rl_screenwidth = 79; + _rl_screenheight = 24; + } + + /* Everything below here is used by the redisplay code (tputs). */ + _rl_screenchars = _rl_screenwidth * _rl_screenheight; + _rl_term_cr = "\r"; + _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_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; +#if defined (HACK_TERMCAP_MOTION) + term_forward_char = (char *)NULL; +#endif + _rl_terminal_can_insert = term_has_meta = 0; + + /* Reasonable defaults for tgoto(). Readline currently only uses + tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we + change that later... */ + PC = '\0'; + BC = _rl_term_backspace = "\b"; + UP = _rl_term_up; + + return 0; + } + + get_term_capabilities (&buffer); + + /* Set up the variables that the termcap library expects the application + to provide. */ + PC = _rl_term_pc ? *_rl_term_pc : 0; + BC = _rl_term_backspace; + UP = _rl_term_up; + + if (!_rl_term_cr) + _rl_term_cr = "\r"; + + _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); + + _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', + `im', `ic' or `ip' is provided." But we can't do anything if + only `ip' is provided, so... */ + _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic); + + /* Check to see if this terminal has a meta key and clear the capability + variables if there is none. */ + term_has_meta = (tgetflag ("km") || tgetflag ("MT")); + if (!term_has_meta) + _rl_term_mm = _rl_term_mo = (char *)NULL; + + /* Attempt to find and bind the arrow keys. Do not override already + bound keys in an overzealous attempt, however. */ + + bind_termcap_arrow_keys (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_termcap_arrow_keys (vi_movement_keymap); + bind_termcap_arrow_keys (vi_insertion_keymap); +#endif /* VI_MODE */ + + return 0; +} + +/* Bind the arrow key sequences from the termcap description in MAP. */ +static void +bind_termcap_arrow_keys (map) + Keymap map; +{ + Keymap xkeymap; + + 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_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ + _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ + + _rl_keymap = xkeymap; +} + +char * +rl_get_termcap (cap) + const char *cap; +{ + register int i; + + if (tcap_initialized == 0) + return ((char *)NULL); + for (i = 0; i < NUM_TC_STRINGS; i++) + { + if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) + return *(tc_strings[i].tc_value); + } + return ((char *)NULL); +} + +/* Re-initialize the terminal considering that the TERM/TERMCAP variable + has changed. */ +int +rl_reset_terminal (terminal_name) + const char *terminal_name; +{ + _rl_init_terminal_io (terminal_name); + return 0; +} + +/* A function for the use of tputs () */ +#ifdef _MINIX +void +_rl_output_character_function (c) + int c; +{ + putc (c, _rl_out_stream); +} +#else /* !_MINIX */ +int +_rl_output_character_function (c) + int c; +{ + return putc (c, _rl_out_stream); +} +#endif /* !_MINIX */ + +/* Write COUNT characters from STRING to the output stream. */ +void +_rl_output_some_chars (string, count) + const char *string; + int count; +{ + fwrite (string, 1, count, _rl_out_stream); +} + +/* Move the cursor back. */ +int +_rl_backspace (count) + int count; +{ + register int i; + + if (_rl_term_backspace) + for (i = 0; i < count; i++) + tputs (_rl_term_backspace, 1, _rl_output_character_function); + else + for (i = 0; i < count; i++) + putc ('\b', _rl_out_stream); + return 0; +} + +/* Move to the start of the next line. */ +int +rl_crlf () +{ +#if defined (NEW_TTY_DRIVER) + if (_rl_term_cr) + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif /* NEW_TTY_DRIVER */ + putc ('\n', _rl_out_stream); + return 0; +} + +/* Ring the terminal bell. */ +int +rl_ding () +{ + if (readline_echoing_p) + { + switch (_rl_bell_preference) + { + case NO_BELL: + default: + break; + case VISIBLE_BELL: + if (_rl_visible_bell) + { + tputs (_rl_visible_bell, 1, _rl_output_character_function); + break; + } + /* FALLTHROUGH */ + case AUDIBLE_BELL: + fprintf (stderr, "\007"); + fflush (stderr); + break; + } + return (0); + } + return (-1); +} + +/* **************************************************************** */ +/* */ +/* Controlling the Meta Key and Keypad */ +/* */ +/* **************************************************************** */ + +void +_rl_enable_meta_key () +{ +#if !defined (__DJGPP__) + if (term_has_meta && _rl_term_mm) + tputs (_rl_term_mm, 1, _rl_output_character_function); +#endif +} + +void +_rl_control_keypad (on) + int on; +{ +#if !defined (__DJGPP__) + if (on && _rl_term_ks) + tputs (_rl_term_ks, 1, _rl_output_character_function); + else if (!on && _rl_term_ke) + tputs (_rl_term_ke, 1, _rl_output_character_function); +#endif +} + +/* **************************************************************** */ +/* */ +/* Controlling the Cursor */ +/* */ +/* **************************************************************** */ + +/* Set the cursor appropriately depending on IM, which is one of the + insert modes (insert or overwrite). Insert mode gets the normal + cursor. Overwrite mode gets a very visible cursor. Only does + anything if we have both capabilities. */ +void +_rl_set_cursor (im, force) + int im, force; +{ + if (_rl_term_ve && _rl_term_vs) + { + if (force || im != rl_insert_mode) + { + if (im == RL_IM_OVERWRITE) + tputs (_rl_term_vs, 1, _rl_output_character_function); + else + tputs (_rl_term_ve, 1, _rl_output_character_function); + } + } +} diff --git a/readline-4.3.orig/text.c b/readline-4.3.orig/text.c new file mode 100644 index 0000000..2a7b724 --- /dev/null +++ b/readline-4.3.orig/text.c @@ -0,0 +1,1540 @@ +/* text.c -- text handling commands for readline. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* Forward declarations. */ +static int rl_change_case PARAMS((int, int)); +static int _rl_char_search PARAMS((int, int, int)); + +/* **************************************************************** */ +/* */ +/* Insert and Delete */ +/* */ +/* **************************************************************** */ + +/* Insert a string of text into the line at point. This is the only + way that you should do insertion. _rl_insert_char () calls this + function. Returns the number of characters inserted. */ +int +rl_insert_text (string) + const char *string; +{ + register int i, l; + + l = (string && *string) ? strlen (string) : 0; + if (l == 0) + return 0; + + if (rl_end + l >= rl_line_buffer_len) + rl_extend_line_buffer (rl_end + l); + + for (i = rl_end; i >= rl_point; i--) + rl_line_buffer[i + l] = rl_line_buffer[i]; + strncpy (rl_line_buffer + rl_point, string, l); + + /* Remember how to undo this if we aren't undoing something. */ + if (_rl_doing_an_undo == 0) + { + /* If possible and desirable, concatenate the undos. */ + if ((l == 1) && + rl_undo_list && + (rl_undo_list->what == UNDO_INSERT) && + (rl_undo_list->end == rl_point) && + (rl_undo_list->end - rl_undo_list->start < 20)) + rl_undo_list->end++; + else + rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL); + } + rl_point += l; + rl_end += l; + rl_line_buffer[rl_end] = '\0'; + return l; +} + +/* Delete the string between FROM and TO. FROM is inclusive, TO is not. + Returns the number of characters deleted. */ +int +rl_delete_text (from, to) + int from, to; +{ + register char *text; + register int diff, i; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + /* fix boundaries */ + if (to > rl_end) + { + to = rl_end; + if (from > to) + from = to; + } + if (from < 0) + from = 0; + + text = rl_copy_text (from, to); + + /* Some versions of strncpy() can't handle overlapping arguments. */ + diff = to - from; + for (i = from; i < rl_end - diff; i++) + rl_line_buffer[i] = rl_line_buffer[i + diff]; + + /* Remember how to undo this delete. */ + if (_rl_doing_an_undo == 0) + rl_add_undo (UNDO_DELETE, from, to, text); + else + free (text); + + rl_end -= diff; + rl_line_buffer[rl_end] = '\0'; + return (diff); +} + +/* Fix up point so that it is within the line boundaries after killing + text. If FIX_MARK_TOO is non-zero, the mark is forced within line + boundaries also. */ + +#define _RL_FIX_POINT(x) \ + do { \ + if (x > rl_end) \ + x = rl_end; \ + else if (x < 0) \ + x = 0; \ + } while (0) + +void +_rl_fix_point (fix_mark_too) + int fix_mark_too; +{ + _RL_FIX_POINT (rl_point); + if (fix_mark_too) + _RL_FIX_POINT (rl_mark); +} +#undef _RL_FIX_POINT + +int +_rl_replace_text (text, start, end) + const char *text; + int start, end; +{ + int n; + + rl_begin_undo_group (); + rl_delete_text (start, end + 1); + rl_point = start; + n = rl_insert_text (text); + rl_end_undo_group (); + + return n; +} + +/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is + non-zero, we free the current undo list. */ +void +rl_replace_line (text, clear_undo) + const char *text; + int clear_undo; +{ + int len; + + len = strlen (text); + if (len >= rl_line_buffer_len) + rl_extend_line_buffer (len); + strcpy (rl_line_buffer, text); + rl_end = len; + + if (clear_undo) + rl_free_undo_list (); + + _rl_fix_point (1); +} + +/* **************************************************************** */ +/* */ +/* Readline character functions */ +/* */ +/* **************************************************************** */ + +/* This is not a gap editor, just a stupid line input routine. No hair + is involved in writing any of the functions, and none should be. */ + +/* Note that: + + rl_end is the place in the string that we would place '\0'; + i.e., it is always safe to place '\0' there. + + rl_point is the place in the string where the cursor is. Sometimes + this is the same as rl_end. + + Any command that is called interactively receives two arguments. + The first is a count: the numeric arg pased to this command. + The second is the key which invoked this command. +*/ + +/* **************************************************************** */ +/* */ +/* Movement Commands */ +/* */ +/* **************************************************************** */ + +/* Note that if you `optimize' the display for these functions, you cannot + use said functions in other functions which do not do optimizing display. + I.e., you will have to update the data base for rl_redisplay, and you + might as well let rl_redisplay do that job. */ + +/* Move forward COUNT bytes. */ +int +rl_forward_byte (count, key) + int count, key; +{ + if (count < 0) + return (rl_backward_byte (-count, key)); + + if (count > 0) + { + int end = rl_point + count; +#if defined (VI_MODE) + int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end; +#else + int lend = rl_end; +#endif + + if (end > lend) + { + rl_point = lend; + rl_ding (); + } + else + rl_point = end; + } + + if (rl_end < 0) + rl_end = 0; + + return 0; +} + +#if defined (HANDLE_MULTIBYTE) +/* Move forward COUNT characters. */ +int +rl_forward_char (count, key) + int count, key; +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_forward_byte (count, key)); + + if (count < 0) + return (rl_backward_char (-count, key)); + + if (count > 0) + { + point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + +#if defined (VI_MODE) + if (rl_end <= point && rl_editing_mode == vi_mode) + point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO); +#endif + + if (rl_point == point) + rl_ding (); + + rl_point = point; + + if (rl_end < 0) + rl_end = 0; + } + + return 0; +} +#else /* !HANDLE_MULTIBYTE */ +int +rl_forward_char (count, key) + int count, key; +{ + return (rl_forward_byte (count, key)); +} +#endif /* !HANDLE_MULTIBYTE */ + +/* Backwards compatibility. */ +int +rl_forward (count, key) + int count, key; +{ + return (rl_forward_char (count, key)); +} + +/* Move backward COUNT bytes. */ +int +rl_backward_byte (count, key) + int count, key; +{ + if (count < 0) + return (rl_forward_byte (-count, key)); + + if (count > 0) + { + if (rl_point < count) + { + rl_point = 0; + rl_ding (); + } + else + rl_point -= count; + } + + if (rl_point < 0) + rl_point = 0; + + return 0; +} + +#if defined (HANDLE_MULTIBYTE) +/* Move backward COUNT characters. */ +int +rl_backward_char (count, key) + int count, key; +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_backward_byte (count, key)); + + if (count < 0) + return (rl_forward_char (-count, key)); + + if (count > 0) + { + point = rl_point; + + while (count > 0 && point > 0) + { + point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); + count--; + } + if (count > 0) + { + rl_point = 0; + rl_ding (); + } + else + rl_point = point; + } + + return 0; +} +#else +int +rl_backward_char (count, key) + int count, key; +{ + return (rl_backward_byte (count, key)); +} +#endif + +/* Backwards compatibility. */ +int +rl_backward (count, key) + int count, key; +{ + return (rl_backward_char (count, key)); +} + +/* Move to the beginning of the line. */ +int +rl_beg_of_line (count, key) + int count, key; +{ + rl_point = 0; + return 0; +} + +/* Move to the end of the line. */ +int +rl_end_of_line (count, key) + int count, key; +{ + rl_point = rl_end; + return 0; +} + +/* XXX - these might need changes for multibyte characters */ +/* Move forward a word. We do what Emacs does. */ +int +rl_forward_word (count, key) + int count, key; +{ + int c; + + if (count < 0) + return (rl_backward_word (-count, key)); + + while (count) + { + if (rl_point == rl_end) + return 0; + + /* 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) + { + while (++rl_point < rl_end) + { + c = rl_line_buffer[rl_point]; + if (rl_alphabetic (c)) + break; + } + } + + if (rl_point == rl_end) + return 0; + + while (++rl_point < rl_end) + { + c = rl_line_buffer[rl_point]; + if (rl_alphabetic (c) == 0) + break; + } + --count; + } + + return 0; +} + +/* Move backward a word. We do what Emacs does. */ +int +rl_backward_word (count, key) + int count, key; +{ + int c; + + if (count < 0) + return (rl_forward_word (-count, key)); + + while (count) + { + if (!rl_point) + 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) + { + while (--rl_point) + { + c = rl_line_buffer[rl_point - 1]; + if (rl_alphabetic (c)) + break; + } + } + + while (rl_point) + { + c = rl_line_buffer[rl_point - 1]; + if (rl_alphabetic (c) == 0) + break; + else + --rl_point; + } + + --count; + } + + return 0; +} + +/* Clear the current line. Numeric argument to C-l does this. */ +int +rl_refresh_line (ignore1, ignore2) + int ignore1, ignore2; +{ + int curr_line; + + curr_line = _rl_current_display_line (); + + _rl_move_vert (curr_line); + _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */ + + _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */ + + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +/* C-l typed to a line without quoting clears the screen, and then reprints + the prompt and the current input line. Given a numeric arg, redraw only + the current line. */ +int +rl_clear_screen (count, key) + int count, key; +{ + if (rl_explicit_arg) + { + rl_refresh_line (count, key); + return 0; + } + + _rl_clear_screen (); /* calls termcap function to clear screen */ + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +int +rl_arrow_keys (count, c) + int count, c; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + switch (_rl_to_upper (ch)) + { + case 'A': + rl_get_previous_history (count, ch); + break; + + case 'B': + rl_get_next_history (count, ch); + break; + + case 'C': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_forward_char (count, ch); + else + rl_forward_byte (count, ch); + break; + + case 'D': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_backward_char (count, ch); + else + rl_backward_byte (count, ch); + break; + + default: + rl_ding (); + } + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Text commands */ +/* */ +/* **************************************************************** */ + +#ifdef HANDLE_MULTIBYTE +static char pending_bytes[MB_LEN_MAX]; +static int pending_bytes_length = 0; +static mbstate_t ps = {0}; +#endif + +/* Insert the character C at the current location, moving point forward. + If C introduces a multibyte sequence, we read the whole sequence and + then insert the multibyte char into the line buffer. */ +int +_rl_insert_char (count, c) + int count, c; +{ + register int i; + char *string; +#ifdef HANDLE_MULTIBYTE + int string_size; + char incoming[MB_LEN_MAX + 1]; + int incoming_length = 0; + mbstate_t ps_back; + static int stored_count = 0; +#endif + + if (count <= 0) + return 0; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + incoming[0] = c; + incoming[1] = '\0'; + incoming_length = 1; + } + else + { + wchar_t wc; + size_t ret; + + if (stored_count <= 0) + stored_count = count; + else + count = stored_count; + + ps_back = ps; + pending_bytes[pending_bytes_length++] = c; + ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps); + + if (ret == (size_t)-2) + { + /* Bytes too short to compose character, try to wait for next byte. + Restore the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + ps = ps_back; + return 1; + } + else if (ret == (size_t)-1) + { + /* Invalid byte sequence for the current locale. Treat first byte + as a single character. */ + incoming[0] = pending_bytes[0]; + incoming[1] = '\0'; + incoming_length = 1; + pending_bytes_length--; + memmove (pending_bytes, pending_bytes + 1, pending_bytes_length); + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (ret == (size_t)0) + { + incoming[0] = '\0'; + incoming_length = 0; + pending_bytes_length--; + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else + { + /* We successfully read a single multibyte character. */ + memcpy (incoming, pending_bytes, pending_bytes_length); + incoming[pending_bytes_length] = '\0'; + incoming_length = pending_bytes_length; + pending_bytes_length = 0; + } + } +#endif /* HANDLE_MULTIBYTE */ + + /* If we can optimize, then do it. But don't let people crash + readline because of extra large arguments. */ + if (count > 1 && count <= 1024) + { +#if defined (HANDLE_MULTIBYTE) + string_size = count * incoming_length; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + string = (char *)xmalloc (1 + count); + + for (i = 0; i < count; i++) + string[i] = c; +#endif /* !HANDLE_MULTIBYTE */ + + string[i] = '\0'; + rl_insert_text (string); + free (string); + + return 0; + } + + if (count > 1024) + { + int decreaser; +#if defined (HANDLE_MULTIBYTE) + string_size = incoming_length * 1024; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + + while (count) + { + decreaser = (count > 1024) ? 1024 : count; + string[decreaser*incoming_length] = '\0'; + rl_insert_text (string); + count -= decreaser; + } + + free (string); + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + char str[1024+1]; + + for (i = 0; i < 1024; i++) + str[i] = c; + + while (count) + { + decreaser = (count > 1024 ? 1024 : count); + str[decreaser] = '\0'; + rl_insert_text (str); + count -= decreaser; + } +#endif /* !HANDLE_MULTIBYTE */ + + 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 + them all. */ + if (_rl_any_typein ()) + _rl_insert_typein (c); + else + { + /* Inserting a single character. */ + char str[2]; + + str[1] = '\0'; + str[0] = c; + rl_insert_text (str); + } +#if defined (HANDLE_MULTIBYTE) + } + else + { + rl_insert_text (incoming); + stored_count = 0; + } +#endif + + return 0; +} + +/* Overwrite the character at point (or next COUNT characters) with C. + If C introduces a multibyte character sequence, read the entire sequence + before starting the overwrite loop. */ +int +_rl_overwrite_char (count, c) + int count, c; +{ + int i; +#if defined (HANDLE_MULTIBYTE) + char mbkey[MB_LEN_MAX]; + int k; + + /* Read an entire multibyte character sequence to insert COUNT times. */ + if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) + k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); +#endif + + 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); + else +#endif + _rl_insert_char (1, c); + + rl_end_undo_group (); + } + + return 0; +} + +int +rl_insert (count, c) + int count, c; +{ + return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c) + : _rl_overwrite_char (count, c)); +} + +/* Insert the next typed character verbatim. */ +int +rl_quoted_insert (count, key) + int count, key; +{ + 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 (); +#endif + + return (_rl_insert_char (count, c)); +} + +/* Insert a tab character. */ +int +rl_tab_insert (count, key) + int count, key; +{ + return (_rl_insert_char (count, '\t')); +} + +/* What to do when a NEWLINE is pressed. We accept the whole line. + KEY is the key that invoked this command. I guess it could have + meaning in the future. */ +int +rl_newline (count, key) + int count, key; +{ + rl_done = 1; + + if (_rl_history_preserve_point) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + RL_SETSTATE(RL_STATE_DONE); + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + _rl_vi_done_inserting (); + _rl_vi_reset_last (); + } +#endif /* VI_MODE */ + + /* If we've been asked to erase empty lines, suppress the final update, + since _rl_update_final calls rl_crlf(). */ + if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) + return 0; + + if (readline_echoing_p) + _rl_update_final (); + return 0; +} + +/* What to do for some uppercase characters, like meta characters, + and some characters appearing in emacs_ctlx_keymap. This function + is just a stub, you bind keys to it and the code in _rl_dispatch () + is special cased. */ +int +rl_do_lowercase_version (ignore1, ignore2) + int ignore1, ignore2; +{ + return 0; +} + +/* This is different from what vi does, so the code's not shared. Emacs + rubout in overwrite mode has one oddity: it replaces a control + character that's displayed as two characters (^X) with two spaces. */ +int +_rl_overwrite_rubout (count, key) + int count, key; +{ + int opoint; + int i, l; + + if (rl_point == 0) + { + rl_ding (); + return 1; + } + + opoint = rl_point; + + /* L == number of spaces to insert */ + for (i = l = 0; i < count; i++) + { + rl_backward_char (1, key); + l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ + } + + rl_begin_undo_group (); + + if (count > 1 || rl_explicit_arg) + rl_kill_text (opoint, rl_point); + else + 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; + + rl_end_undo_group (); + + return 0; +} + +/* Rubout the character behind point. */ +int +rl_rubout (count, key) + int count, key; +{ + if (count < 0) + return (rl_delete (-count, key)); + + if (!rl_point) + { + rl_ding (); + return -1; + } + + if (rl_insert_mode == RL_IM_OVERWRITE) + return (_rl_overwrite_rubout (count, key)); + + return (_rl_rubout_char (count, key)); +} + +int +_rl_rubout_char (count, key) + int count, key; +{ + int orig_point; + unsigned char c; + + /* Duplicated code because this is called from other parts of the library. */ + if (count < 0) + return (rl_delete (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return -1; + } + + 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_kill_text (orig_point, rl_point); + } + else + { +#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 + if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) + { + int l; + l = rl_character_len (c, rl_point); + _rl_erase_at_end_of_line (l); + } + } + + return 0; +} + +/* Delete the character under the cursor. Given a numeric argument, + kill that many characters instead. */ +int +rl_delete (count, key) + int count, key; +{ + int r; + + if (count < 0) + return (_rl_rubout_char (-count, key)); + + if (rl_point == rl_end) + { + rl_ding (); + return -1; + } + + 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_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)); + } +} + +/* Delete the character under the cursor, unless the insertion + point is at the end of the line, in which case the character + behind the cursor is deleted. COUNT is obeyed and may be used + to delete forward or backward that many characters. */ +int +rl_rubout_or_delete (count, key) + int count, key; +{ + if (rl_end != 0 && rl_point == rl_end) + return (_rl_rubout_char (count, key)); + else + return (rl_delete (count, key)); +} + +/* Delete all spaces and tabs around point. */ +int +rl_delete_horizontal_space (count, ignore) + int count, ignore; +{ + int start = rl_point; + + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + start = rl_point; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + if (start != rl_point) + { + rl_delete_text (start, rl_point); + rl_point = start; + } + return 0; +} + +/* Like the tcsh editing function delete-char-or-list. The eof character + is caught before this is invoked, so this really does the same thing as + delete-char-or-list-or-eof, as long as it's bound to the eof character. */ +int +rl_delete_or_show_completions (count, key) + int count, key; +{ + if (rl_end != 0 && rl_point == rl_end) + return (rl_possible_completions (count, key)); + else + return (rl_delete (count, key)); +} + +#ifndef RL_COMMENT_BEGIN_DEFAULT +#define RL_COMMENT_BEGIN_DEFAULT "#" +#endif + +/* Turn the current line into a comment in shell history. + A K*rn shell style function. */ +int +rl_insert_comment (count, key) + int count, key; +{ + char *rl_comment_text; + int rl_comment_len; + + rl_beg_of_line (1, key); + rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT; + + if (rl_explicit_arg == 0) + rl_insert_text (rl_comment_text); + else + { + rl_comment_len = strlen (rl_comment_text); + if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) + rl_delete_text (rl_point, rl_point + rl_comment_len); + else + rl_insert_text (rl_comment_text); + } + + (*rl_redisplay_function) (); + rl_newline (1, '\n'); + + return (0); +} + +/* **************************************************************** */ +/* */ +/* Changing Case */ +/* */ +/* **************************************************************** */ + +/* The three kinds of things that we know how to do. */ +#define UpCase 1 +#define DownCase 2 +#define CapCase 3 + +/* Uppercase the word at point. */ +int +rl_upcase_word (count, key) + int count, key; +{ + return (rl_change_case (count, UpCase)); +} + +/* Lowercase the word at point. */ +int +rl_downcase_word (count, key) + int count, key; +{ + return (rl_change_case (count, DownCase)); +} + +/* Upcase the first letter, downcase the rest. */ +int +rl_capitalize_word (count, key) + int count, key; +{ + return (rl_change_case (count, CapCase)); +} + +/* The meaty function. + Change the case of COUNT words, performing OP on them. + OP is one of UpCase, DownCase, or CapCase. + If a negative argument is given, leave point where it started, + otherwise, leave it where it moves to. */ +static int +rl_change_case (count, op) + int count, op; +{ + register int start, end; + int inword, c; + + start = rl_point; + rl_forward_word (count, 0); + end = rl_point; + + if (count < 0) + SWAP (start, end); + + /* We are going to modify some text, so let's prepare to undo it. */ + rl_modifying (start, end); + + for (inword = 0; start < end; start++) + { + c = rl_line_buffer[start]; + switch (op) + { + case UpCase: + rl_line_buffer[start] = _rl_to_upper (c); + break; + + 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; + + default: + rl_ding (); + return -1; + } + } + rl_point = end; + return 0; +} + +/* **************************************************************** */ +/* */ +/* Transposition */ +/* */ +/* **************************************************************** */ + +/* Transpose the words at point. If point is at the end of the line, + transpose the two words before point. */ +int +rl_transpose_words (count, key) + int count, key; +{ + char *word1, *word2; + int w1_beg, w1_end, w2_beg, w2_end; + int orig_point = rl_point; + + if (!count) + return 0; + + /* Find the two words. */ + rl_forward_word (count, key); + w2_end = rl_point; + rl_backward_word (1, key); + w2_beg = rl_point; + rl_backward_word (count, key); + w1_beg = rl_point; + rl_forward_word (1, key); + w1_end = rl_point; + + /* Do some check to make sure that there really are two words. */ + if ((w1_beg == w2_beg) || (w2_beg < w1_end)) + { + rl_ding (); + rl_point = orig_point; + return -1; + } + + /* Get the text of the words. */ + word1 = rl_copy_text (w1_beg, w1_end); + word2 = rl_copy_text (w2_beg, w2_end); + + /* We are about to do many insertions and deletions. Remember them + as one operation. */ + rl_begin_undo_group (); + + /* Do the stuff at word2 first, so that we don't have to worry + about word1 moving. */ + rl_point = w2_beg; + rl_delete_text (w2_beg, w2_end); + rl_insert_text (word1); + + rl_point = w1_beg; + rl_delete_text (w1_beg, w1_end); + rl_insert_text (word2); + + /* This is exactly correct since the text before this point has not + changed in length. */ + rl_point = w2_end; + + /* I think that does it. */ + rl_end_undo_group (); + free (word1); + free (word2); + + return 0; +} + +/* Transpose the characters at point. If point is at the end of the line, + then transpose the characters before point. */ +int +rl_transpose_chars (count, key) + int count, key; +{ +#if defined (HANDLE_MULTIBYTE) + char *dummy; + int i, prev_point; +#else + char dummy[2]; +#endif + int char_length; + + if (count == 0) + return 0; + + if (!rl_point || rl_end < 2) + { + rl_ding (); + return -1; + } + + rl_begin_undo_group (); + + 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; + 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--; + +#if defined (HANDLE_MULTIBYTE) + char_length = prev_point - rl_point; + dummy = (char *)xmalloc (char_length + 1); + for (i = 0; i < char_length; i++) + dummy[i] = rl_line_buffer[rl_point + i]; + dummy[i] = '\0'; +#else + dummy[0] = rl_line_buffer[rl_point]; + dummy[char_length = 1] = '\0'; +#endif + + rl_delete_text (rl_point, rl_point + char_length); + + rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + + _rl_fix_point (0); + rl_insert_text (dummy); + rl_end_undo_group (); + +#if defined (HANDLE_MULTIBYTE) + free (dummy); +#endif + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Searching */ +/* */ +/* **************************************************************** */ + +int +#if defined (HANDLE_MULTIBYTE) +_rl_char_search_internal (count, dir, smbchar, len) + int count, dir; + char *smbchar; + int len; +#else +_rl_char_search_internal (count, dir, schar) + int count, dir, schar; +#endif +{ + int pos, inc; +#if defined (HANDLE_MULTIBYTE) + int prepos; +#endif + + pos = rl_point; + inc = (dir < 0) ? -1 : 1; + while (count) + { + if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) + { + rl_ding (); + return -1; + } + +#if defined (HANDLE_MULTIBYTE) + pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); +#else + pos += inc; +#endif + do + { +#if defined (HANDLE_MULTIBYTE) + if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) +#else + if (rl_line_buffer[pos] == schar) +#endif + { + count--; + if (dir < 0) + rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : pos; + else + rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) + : pos; + break; + } +#if defined (HANDLE_MULTIBYTE) + prepos = pos; +#endif + } +#if defined (HANDLE_MULTIBYTE) + while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos + : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); +#else + while ((dir < 0) ? pos-- : ++pos < rl_end); +#endif + } + return (0); +} + +/* Search COUNT times for a character read from the current input stream. + FDIR is the direction to search if COUNT is non-negative; otherwise + the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE + that there are two separate versions of this function. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_char_search (count, fdir, bdir) + int count, fdir, bdir; +{ + char mbchar[MB_LEN_MAX]; + int mb_len; + + mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); + else + return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); +} +#else /* !HANDLE_MULTIBYTE */ +static int +_rl_char_search (count, fdir, bdir) + int count, fdir, bdir; +{ + int c; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, c)); + else + return (_rl_char_search_internal (count, fdir, c)); +} +#endif /* !HANDLE_MULTIBYTE */ + +int +rl_char_search (count, key) + int count, key; +{ + return (_rl_char_search (count, FFIND, BFIND)); +} + +int +rl_backward_char_search (count, key) + int count, key; +{ + return (_rl_char_search (count, BFIND, FFIND)); +} + +/* **************************************************************** */ +/* */ +/* The Mark and the Region. */ +/* */ +/* **************************************************************** */ + +/* Set the mark at POSITION. */ +int +_rl_set_mark_at_pos (position) + int position; +{ + if (position > rl_end) + return -1; + + rl_mark = position; + return 0; +} + +/* A bindable command to set the mark. */ +int +rl_set_mark (count, key) + int count, key; +{ + return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); +} + +/* Exchange the position of mark and point. */ +int +rl_exchange_point_and_mark (count, key) + int count, key; +{ + if (rl_mark > rl_end) + rl_mark = -1; + + if (rl_mark == -1) + { + rl_ding (); + return -1; + } + else + SWAP (rl_point, rl_mark); + + return 0; +} diff --git a/readline-4.3.orig/tilde.c b/readline-4.3.orig/tilde.c new file mode 100644 index 0000000..154f7f8 --- /dev/null +++ b/readline-4.3.orig/tilde.c @@ -0,0 +1,458 @@ +/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ + +/* Copyright (C) 1988,1989 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +#include "tilde.h" + +#if defined (TEST) || defined (STATIC_MALLOC) +static void *xmalloc (), *xrealloc (); +#else +# include "xmalloc.h" +#endif /* TEST || STATIC_MALLOC */ + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid PARAMS((uid_t)); +extern struct passwd *getpwnam PARAMS((const char *)); +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (savestring) +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif /* !savestring */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* If being compiled as part of bash, these will be satisfied from + variables.o. If being compiled as part of readline, they will + be satisfied from shell.o. */ +extern char *sh_get_home_dir PARAMS((void)); +extern char *sh_get_env_value PARAMS((const char *)); + +/* The default value of tilde_additional_prefixes. This is set to + whitespace preceding a tilde so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_prefixes[] = + { " ~", "\t~", (const char *)NULL }; + +/* The default value of tilde_additional_suffixes. This is set to + whitespace or newline so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_suffixes[] = + { " ", "\n", (const char *)NULL }; + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +char **tilde_additional_prefixes = (char **)default_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +char **tilde_additional_suffixes = (char **)default_suffixes; + +static int tilde_find_prefix PARAMS((const char *, int *)); +static int tilde_find_suffix PARAMS((const char *)); +static char *isolate_tilde_prefix PARAMS((const char *, int *)); +static char *glue_prefix_and_suffix PARAMS((char *, const char *, int)); + +/* Find the start of a tilde expansion in STRING, and return the index of + the tilde which starts the expansion. Place the length of the text + which identified this tilde starter in LEN, excluding the tilde itself. */ +static int +tilde_find_prefix (string, len) + const char *string; + int *len; +{ + register int i, j, string_len; + register char **prefixes; + + prefixes = tilde_additional_prefixes; + + string_len = strlen (string); + *len = 0; + + if (*string == '\0' || *string == '~') + return (0); + + if (prefixes) + { + for (i = 0; i < string_len; i++) + { + for (j = 0; prefixes[j]; j++) + { + if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) + { + *len = strlen (prefixes[j]) - 1; + return (i + *len); + } + } + } + } + return (string_len); +} + +/* Find the end of a tilde expansion in STRING, and return the index of + the character which ends the tilde definition. */ +static int +tilde_find_suffix (string) + const char *string; +{ + register int i, j, string_len; + register char **suffixes; + + suffixes = tilde_additional_suffixes; + string_len = strlen (string); + + for (i = 0; i < string_len; i++) + { +#if defined (__MSDOS__) + if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) +#else + if (string[i] == '/' /* || !string[i] */) +#endif + break; + + for (j = 0; suffixes && suffixes[j]; j++) + { + if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) + return (i); + } + } + return (i); +} + +/* Return a new string which is the result of tilde expanding STRING. */ +char * +tilde_expand (string) + const char *string; +{ + char *result; + int result_size, result_index; + + result_index = result_size = 0; + if (result = strchr (string, '~')) + result = (char *)xmalloc (result_size = (strlen (string) + 16)); + else + result = (char *)xmalloc (result_size = (strlen (string) + 1)); + + /* Scan through STRING expanding tildes as we come to them. */ + while (1) + { + register int start, end; + char *tilde_word, *expansion; + int len; + + /* Make START point to the tilde which starts the expansion. */ + start = tilde_find_prefix (string, &len); + + /* Copy the skipped text into the result. */ + if ((result_index + start + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + + strncpy (result + result_index, string, start); + result_index += start; + + /* Advance STRING to the starting tilde. */ + string += start; + + /* Make END be the index of one after the last character of the + username. */ + end = tilde_find_suffix (string); + + /* If both START and END are zero, we are all done. */ + if (!start && !end) + break; + + /* Expand the entire tilde word, and copy it into RESULT. */ + tilde_word = (char *)xmalloc (1 + end); + strncpy (tilde_word, string, end); + tilde_word[end] = '\0'; + string += end; + + expansion = tilde_expand_word (tilde_word); + free (tilde_word); + + len = strlen (expansion); +#ifdef __CYGWIN__ + /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when + $HOME for `user' is /. On cygwin, // denotes a network drive. */ + if (len > 1 || *expansion != '/' || *string != '/') +#endif + { + if ((result_index + len + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + + strcpy (result + result_index, expansion); + result_index += len; + } + free (expansion); + } + + result[result_index] = '\0'; + + return (result); +} + +/* Take FNAME and return the tilde prefix we want expanded. If LENP is + non-null, the index of the end of the prefix into FNAME is returned in + the location it points to. */ +static char * +isolate_tilde_prefix (fname, lenp) + const char *fname; + int *lenp; +{ + char *ret; + int i; + + ret = (char *)xmalloc (strlen (fname)); +#if defined (__MSDOS__) + for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) +#else + for (i = 1; fname[i] && fname[i] != '/'; i++) +#endif + ret[i - 1] = fname[i]; + ret[i - 1] = '\0'; + if (lenp) + *lenp = i; + return ret; +} + +/* Return a string that is PREFIX concatenated with SUFFIX starting at + SUFFIND. */ +static char * +glue_prefix_and_suffix (prefix, suffix, suffind) + char *prefix; + const char *suffix; + int suffind; +{ + char *ret; + int plen, slen; + + plen = (prefix && *prefix) ? strlen (prefix) : 0; + slen = strlen (suffix + suffind); + ret = (char *)xmalloc (plen + slen + 1); + if (plen) + strcpy (ret, prefix); + strcpy (ret + plen, suffix + suffind); + return ret; +} + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. + This always returns a newly-allocated string, never static storage. */ +char * +tilde_expand_word (filename) + const char *filename; +{ + char *dirname, *expansion, *username; + int user_len; + struct passwd *user_entry; + + if (filename == 0) + return ((char *)NULL); + + if (*filename != '~') + return (savestring (filename)); + + /* A leading `~/' or a bare `~' is *always* translated to the value of + $HOME or the home directory of the current user, regardless of any + preexpansion hook. */ + if (filename[1] == '\0' || filename[1] == '/') + { + /* Prefix $HOME to the rest of the string. */ + expansion = sh_get_env_value ("HOME"); + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (expansion == 0) + expansion = sh_get_home_dir (); + + return (glue_prefix_and_suffix (expansion, filename, 1)); + } + + username = isolate_tilde_prefix (filename, &user_len); + + if (tilde_expansion_preexpansion_hook) + { + expansion = (*tilde_expansion_preexpansion_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + free (username); + free (expansion); + return (dirname); + } + } + + /* No preexpansion hook, or the preexpansion hook failed. Look in the + password database. */ + dirname = (char *)NULL; + user_entry = getpwnam (username); + if (user_entry == 0) + { + /* If the calling program has a special syntax for expanding tildes, + and we couldn't find a standard expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + expansion = (*tilde_expansion_failure_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + free (expansion); + } + } + free (username); + /* If we don't have a failure hook, or if the failure hook did not + expand the tilde, return a copy of what we were passed. */ + if (dirname == 0) + dirname = savestring (filename); + } + else + { + free (username); + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); + } + + endpwent (); + return (dirname); +} + + +#if defined (TEST) +#undef NULL +#include + +main (argc, argv) + int argc; + char **argv; +{ + char *result, line[512]; + int done = 0; + + while (!done) + { + printf ("~expand: "); + fflush (stdout); + + if (!gets (line)) + strcpy (line, "done"); + + if ((strcmp (line, "done") == 0) || + (strcmp (line, "quit") == 0) || + (strcmp (line, "exit") == 0)) + { + done = 1; + break; + } + + result = tilde_expand (line); + printf (" --> %s\n", result); + free (result); + } + exit (0); +} + +static void memory_error_and_abort (); + +static void * +xmalloc (bytes) + size_t bytes; +{ + void *temp = (char *)malloc (bytes); + + if (!temp) + memory_error_and_abort (); + return (temp); +} + +static void * +xrealloc (pointer, bytes) + void *pointer; + int bytes; +{ + void *temp; + + if (!pointer) + temp = malloc (bytes); + else + temp = realloc (pointer, bytes); + + if (!temp) + memory_error_and_abort (); + + return (temp); +} + +static void +memory_error_and_abort () +{ + fprintf (stderr, "readline: out of virtual memory\n"); + abort (); +} + +/* + * Local variables: + * compile-command: "gcc -g -DTEST -o tilde tilde.c" + * end: + */ +#endif /* TEST */ diff --git a/readline-4.3.orig/tilde.h b/readline-4.3.orig/tilde.h new file mode 100644 index 0000000..f8182c9 --- /dev/null +++ b/readline-4.3.orig/tilde.h @@ -0,0 +1,78 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/readline-4.3.orig/undo.c b/readline-4.3.orig/undo.c new file mode 100644 index 0000000..25c287b --- /dev/null +++ b/readline-4.3.orig/undo.c @@ -0,0 +1,263 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Non-zero tells rl_delete_text and rl_insert_text to not add to + the undo list. */ +int _rl_doing_an_undo = 0; + +/* How many unclosed undo groups we currently have. */ +int _rl_undo_group_level = 0; + +/* The current undo list for THE_LINE. */ +UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; + +/* **************************************************************** */ +/* */ +/* Undo, and Undoing */ +/* */ +/* **************************************************************** */ + +/* Remember how to undo something. Concatenate some undos if that + seems right. */ +void +rl_add_undo (what, start, end, text) + enum undo_code what; + int start, end; + char *text; +{ + UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); + temp->what = what; + temp->start = start; + temp->end = end; + temp->text = text; + temp->next = rl_undo_list; + rl_undo_list = temp; +} + +/* Free the existing undo list. */ +void +rl_free_undo_list () +{ + while (rl_undo_list) + { + UNDO_LIST *release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + + if (release->what == UNDO_DELETE) + free (release->text); + + free (release); + } + rl_undo_list = (UNDO_LIST *)NULL; +} + +/* Undo the next thing in the list. Return 0 if there + is nothing to undo, or non-zero if there was. */ +int +rl_do_undo () +{ + UNDO_LIST *release; + int waiting_for_begin, start, end; + +#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) + + start = end = waiting_for_begin = 0; + do + { + if (!rl_undo_list) + return (0); + + _rl_doing_an_undo = 1; + RL_SETSTATE(RL_STATE_UNDOING); + + /* To better support vi-mode, a start or end value of -1 means + rl_point, and a value of -2 means rl_end. */ + if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT) + { + start = TRANS (rl_undo_list->start); + end = TRANS (rl_undo_list->end); + } + + switch (rl_undo_list->what) + { + /* Undoing deletes means inserting some text. */ + case UNDO_DELETE: + rl_point = start; + rl_insert_text (rl_undo_list->text); + free (rl_undo_list->text); + break; + + /* Undoing inserts means deleting some text. */ + case UNDO_INSERT: + rl_delete_text (start, end); + rl_point = start; + break; + + /* Undoing an END means undoing everything 'til we get to a BEGIN. */ + case UNDO_END: + waiting_for_begin++; + break; + + /* Undoing a BEGIN means that we are done with this group. */ + case UNDO_BEGIN: + if (waiting_for_begin) + waiting_for_begin--; + else + rl_ding (); + break; + } + + _rl_doing_an_undo = 0; + RL_UNSETSTATE(RL_STATE_UNDOING); + + release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + free (release); + } + while (waiting_for_begin); + + return (1); +} +#undef TRANS + +int +_rl_fix_last_undo_of_type (type, start, end) + int type, start, end; +{ + UNDO_LIST *rl; + + for (rl = rl_undo_list; rl; rl = rl->next) + { + if (rl->what == type) + { + rl->start = start; + rl->end = end; + return 0; + } + } + return 1; +} + +/* Begin a group. Subsequent undos are undone as an atomic operation. */ +int +rl_begin_undo_group () +{ + rl_add_undo (UNDO_BEGIN, 0, 0, 0); + _rl_undo_group_level++; + return 0; +} + +/* End an undo group started with rl_begin_undo_group (). */ +int +rl_end_undo_group () +{ + rl_add_undo (UNDO_END, 0, 0, 0); + _rl_undo_group_level--; + return 0; +} + +/* Save an undo entry for the text from START to END. */ +int +rl_modifying (start, end) + int start, end; +{ + if (start > end) + { + SWAP (start, end); + } + + if (start != end) + { + char *temp = rl_copy_text (start, end); + rl_begin_undo_group (); + rl_add_undo (UNDO_DELETE, start, end, temp); + rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); + rl_end_undo_group (); + } + return 0; +} + +/* Revert the current line to its previous state. */ +int +rl_revert_line (count, key) + int count, key; +{ + if (!rl_undo_list) + rl_ding (); + else + { + while (rl_undo_list) + rl_do_undo (); + } + return 0; +} + +/* Do some undoing of things that were done. */ +int +rl_undo_command (count, key) + int count, key; +{ + if (count < 0) + return 0; /* Nothing to do. */ + + while (count) + { + if (rl_do_undo ()) + count--; + else + { + rl_ding (); + break; + } + } + return 0; +} diff --git a/readline-4.3.orig/util.c b/readline-4.3.orig/util.c new file mode 100644 index 0000000..c7bd360 --- /dev/null +++ b/readline-4.3.orig/util.c @@ -0,0 +1,338 @@ +/* util.c -- readline utility functions */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return 0 if C is not a member of the class of characters that belong + in words, or 1 if it is. */ + +int _rl_allow_pathname_alphabetic_chars = 0; +static const char *pathname_alphabetic_chars = "/-_=~.#$"; + +int +rl_alphabetic (c) + int c; +{ + if (ALPHABETIC (c)) + return (1); + + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} + +/* How to abort things. */ +int +_rl_abort_internal () +{ + rl_ding (); + rl_clear_message (); + _rl_init_argument (); + rl_clear_pending_input (); + + RL_UNSETSTATE (RL_STATE_MACRODEF); + while (rl_executing_macro) + _rl_pop_executing_macro (); + + rl_last_func = (rl_command_func_t *)NULL; + longjmp (readline_top_level, 1); + return (0); +} + +int +rl_abort (count, key) + int count, key; +{ + return (_rl_abort_internal ()); +} + +int +rl_tty_status (count, key) + int count, key; +{ +#if defined (TIOCSTAT) + ioctl (1, TIOCSTAT, (char *)0); + rl_refresh_line (count, key); +#else + rl_ding (); +#endif + return 0; +} + +/* Return a copy of the string between FROM and TO. + FROM is inclusive, TO is not. */ +char * +rl_copy_text (from, to) + int from, to; +{ + register int length; + char *copy; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + length = to - from; + copy = (char *)xmalloc (1 + length); + strncpy (copy, rl_line_buffer + from, length); + copy[length] = '\0'; + return (copy); +} + +/* Increase the size of RL_LINE_BUFFER until it has enough space to hold + LEN characters. */ +void +rl_extend_line_buffer (len) + int len; +{ + while (len >= rl_line_buffer_len) + { + rl_line_buffer_len += DEFAULT_BUFFER_SIZE; + rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); + } + + _rl_set_the_line (); +} + + +/* A function for simple tilde expansion. */ +int +rl_tilde_expand (ignore, key) + int ignore, key; +{ + register int start, end; + char *homedir, *temp; + int len; + + end = rl_point; + start = end - 1; + + if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') + { + homedir = tilde_expand ("~"); + _rl_replace_text (homedir, start, end); + return (0); + } + else if (rl_line_buffer[start] != '~') + { + for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) + ; + start++; + } + + end = start; + do + end++; + while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); + + if (whitespace (rl_line_buffer[end]) || end >= rl_end) + end--; + + /* If the first character of the current word is a tilde, perform + tilde expansion and insert the result. If not a tilde, do + nothing. */ + if (rl_line_buffer[start] == '~') + { + len = end - start + 1; + temp = (char *)xmalloc (len + 1); + strncpy (temp, rl_line_buffer + start, len); + temp[len] = '\0'; + homedir = tilde_expand (temp); + free (temp); + + _rl_replace_text (homedir, start, end); + } + + return (0); +} + +/* **************************************************************** */ +/* */ +/* String Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Determine if s2 occurs in s1. If so, return a pointer to the + match in s1. The compare is case insensitive. */ +char * +_rl_strindex (s1, s2) + register const char *s1, *s2; +{ + register int i, l, len; + + for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) + if (_rl_strnicmp (s1 + i, s2, l) == 0) + return ((char *) (s1 + i)); + return ((char *)NULL); +} + +#ifndef HAVE_STRPBRK +/* Find the first occurrence in STRING1 of any character from STRING2. + Return a pointer to the character in STRING1. */ +char * +_rl_strpbrk (string1, string2) + const char *string1, *string2; +{ + register const char *scan; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + register int i, v; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + for (; *string1; string1++) + { + for (scan = string2; *scan; scan++) + { + if (*string1 == *scan) + return ((char *)string1); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + v = _rl_get_char_len (string1, &ps); + if (v > 1) + string += v - 1; /* -1 to account for auto-increment in loop */ + } +#endif + } + return ((char *)NULL); +} +#endif + +#if !defined (HAVE_STRCASECMP) +/* Compare at most COUNT characters from string1 to string2. Case + doesn't matter. */ +int +_rl_strnicmp (string1, string2, count) + char *string1, *string2; + int count; +{ + register char ch1, ch2; + + while (count) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) + count--; + else + break; + } + return (count); +} + +/* strcmp (), but caseless. */ +int +_rl_stricmp (string1, string2) + char *string1, *string2; +{ + register char ch1, ch2; + + while (*string1 && *string2) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) + return (1); + } + return (*string1 - *string2); +} +#endif /* !HAVE_STRCASECMP */ + +/* Stupid comparison routine for qsort () ing strings. */ +int +_rl_qsort_string_compare (s1, s2) + char **s1, **s2; +{ +#if defined (HAVE_STRCOLL) + return (strcoll (*s1, *s2)); +#else + int result; + + result = **s1 - **s2; + if (result == 0) + result = strcmp (*s1, *s2); + + return result; +#endif +} + +/* Function equivalents for the macros defined in chardefs.h. */ +#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } + +FUNCTION_FOR_MACRO (_rl_digit_p) +FUNCTION_FOR_MACRO (_rl_digit_value) +FUNCTION_FOR_MACRO (_rl_lowercase_p) +FUNCTION_FOR_MACRO (_rl_pure_alphabetic) +FUNCTION_FOR_MACRO (_rl_to_lower) +FUNCTION_FOR_MACRO (_rl_to_upper) +FUNCTION_FOR_MACRO (_rl_uppercase_p) + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +#undef _rl_savestring +char * +_rl_savestring (s) + const char *s; +{ + return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); +} diff --git a/readline-4.3.orig/vi_keymap.c b/readline-4.3.orig/vi_keymap.c new file mode 100644 index 0000000..53a67c6 --- /dev/null +++ b/readline-4.3.orig/vi_keymap.c @@ -0,0 +1,877 @@ +/* vi_keymap.c -- the keymap for vi_mode in readline (). */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +#if 0 +extern KEYMAP_ENTRY_ARRAY vi_escape_keymap; +#endif + +/* The keymap arrays for handling vi mode. */ +KEYMAP_ENTRY_ARRAY vi_movement_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_emacs_editing_mode }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_backward_char }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_forward_char }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, rl_insert_comment }, /* # */ + { ISFUNC, rl_end_of_line }, /* $ */ + { ISFUNC, rl_vi_match }, /* % */ + { ISFUNC, rl_vi_tilde_expand }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, rl_vi_complete }, /* * */ + { ISFUNC, rl_get_next_history}, /* + */ + { ISFUNC, rl_vi_char_search }, /* , */ + { ISFUNC, rl_get_previous_history }, /* - */ + { ISFUNC, rl_vi_redo }, /* . */ + { ISFUNC, rl_vi_search }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_beg_of_line }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, rl_vi_char_search }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, rl_vi_complete }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, rl_vi_search }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_vi_append_eol }, /* A */ + { ISFUNC, rl_vi_prev_word}, /* B */ + { ISFUNC, rl_vi_change_to }, /* C */ + { ISFUNC, rl_vi_delete_to }, /* D */ + { ISFUNC, rl_vi_end_word }, /* E */ + { ISFUNC, rl_vi_char_search }, /* F */ + { ISFUNC, rl_vi_fetch_history }, /* G */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* H */ + { ISFUNC, rl_vi_insert_beg }, /* I */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* J */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* K */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* L */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* M */ + { ISFUNC, rl_vi_search_again }, /* N */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* O */ + { ISFUNC, rl_vi_put }, /* P */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Q */ + { ISFUNC, rl_vi_replace }, /* R */ + { ISFUNC, rl_vi_subst }, /* S */ + { ISFUNC, rl_vi_char_search }, /* T */ + { 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_yank_to }, /* Y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, rl_vi_complete }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, rl_vi_first_print }, /* ^ */ + { ISFUNC, rl_vi_yank_arg }, /* _ */ + { ISFUNC, rl_vi_goto_mark }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_vi_append_mode }, /* a */ + { ISFUNC, rl_vi_prev_word }, /* b */ + { ISFUNC, rl_vi_change_to }, /* c */ + { ISFUNC, rl_vi_delete_to }, /* d */ + { ISFUNC, rl_vi_end_word }, /* e */ + { ISFUNC, rl_vi_char_search }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, rl_backward_char }, /* h */ + { ISFUNC, rl_vi_insertion_mode }, /* i */ + { ISFUNC, rl_get_next_history }, /* j */ + { ISFUNC, rl_get_previous_history }, /* k */ + { ISFUNC, rl_forward_char }, /* l */ + { ISFUNC, rl_vi_set_mark }, /* m */ + { ISFUNC, rl_vi_search_again }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, rl_vi_put }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, rl_vi_change_char }, /* r */ + { ISFUNC, rl_vi_subst }, /* s */ + { ISFUNC, rl_vi_char_search }, /* t */ + { ISFUNC, rl_vi_undo }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, rl_vi_next_word }, /* w */ + { ISFUNC, rl_vi_delete }, /* x */ + { ISFUNC, rl_vi_yank_to }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, rl_vi_column }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, rl_vi_change_case }, /* ~ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + + +KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, rl_insert }, /* Control-a */ + { ISFUNC, rl_insert }, /* Control-b */ + { ISFUNC, rl_insert }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_insert }, /* Control-e */ + { ISFUNC, rl_insert }, /* Control-f */ + { ISFUNC, rl_insert }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_insert }, /* Control-k */ + { ISFUNC, rl_insert }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_insert }, /* Control-n */ + { ISFUNC, rl_insert }, /* Control-o */ + { ISFUNC, rl_insert }, /* Control-p */ + { ISFUNC, rl_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISFUNC, rl_insert }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, rl_insert }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, rl_insert }, /* Control-\ */ + { ISFUNC, rl_insert }, /* Control-] */ + { ISFUNC, rl_insert }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { 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) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { 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 */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +/* Unused for the time being. */ +#if 0 +KEYMAP_ENTRY_ARRAY vi_escape_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, rl_tab_insert}, /* Control-i */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_vi_arg_digit }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_arrow_keys }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, rl_arrow_keys }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_word }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; +#endif diff --git a/readline-4.3.orig/vi_mode.c b/readline-4.3.orig/vi_mode.c new file mode 100644 index 0000000..5d146b3 --- /dev/null +++ b/readline-4.3.orig/vi_mode.c @@ -0,0 +1,1485 @@ +/* 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. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 + +/* **************************************************************** */ +/* */ +/* VI Emulation Mode */ +/* */ +/* **************************************************************** */ +#include "rlconf.h" + +#if defined (VI_MODE) + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +/* Some standard library routines. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifndef member +#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) +#endif + +/* Non-zero means enter insertion mode. */ +static int _rl_vi_doing_insert; + +/* Command keys which do movement for xxx_to commands. */ +static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|"; + +/* Keymap used for vi replace characters. Created dynamically since + rarely used. */ +static Keymap vi_replace_map; + +/* The number of characters inserted in the last replace operation. */ +static int vi_replace_count; + +/* If non-zero, we have text inserted after a c[motion] command that put + us implicitly into insert mode. Some people want this text to be + attached to the command so that it is `redoable' with `.'. */ +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]; +#else +static int _rl_vi_last_search_char; +#endif +static int _rl_vi_last_replacement; + +static int _rl_vi_last_key_before_insert; + +static int vi_redoing; + +/* Text modification commands. These are the `redoable' commands. */ +static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; + +/* Arrays for the saved marks. */ +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_digit_loop1 PARAMS((void)); + +void +_rl_vi_initialize_line () +{ + register int i; + + for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) + vi_mark_chars[i] = -1; +} + +void +_rl_vi_reset_last () +{ + _rl_vi_last_command = 'i'; + _rl_vi_last_repeat = 1; + _rl_vi_last_arg_sign = 1; + _rl_vi_last_motion = 0; +} + +void +_rl_vi_set_last (key, repeat, sign) + int key, repeat, sign; +{ + _rl_vi_last_command = key; + _rl_vi_last_repeat = repeat; + _rl_vi_last_arg_sign = sign; +} + +/* Is the command C a VI mode text modification command? */ +int +_rl_vi_textmod_command (c) + int c; +{ + return (member (c, vi_textmod)); +} + +static void +_rl_vi_stuff_insert (count) + int count; +{ + rl_begin_undo_group (); + while (count--) + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); +} + +/* Bound to `.'. Called from command mode, so we know that we have to + redo a text modification command. The default for _rl_vi_last_command + puts you back into insert mode. */ +int +rl_vi_redo (count, c) + int count, c; +{ + int r; + + if (!rl_explicit_arg) + { + rl_numeric_arg = _rl_vi_last_repeat; + rl_arg_sign = _rl_vi_last_arg_sign; + } + + r = 0; + vi_redoing = 1; + /* If we're redoing an insert with `i', stuff in the inserted text + and do not go into insertion mode. */ + if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_stuff_insert (count); + /* And back up point over the last character inserted. */ + if (rl_point > 0) + rl_point--; + } + else + r = _rl_dispatch (_rl_vi_last_command, _rl_keymap); + vi_redoing = 0; + + return (r); +} + +/* A placeholder for further expansion. */ +int +rl_vi_undo (count, key) + int count, key; +{ + return (rl_undo_command (count, key)); +} + +/* Yank the nth arg from the previous line into this line at point. */ +int +rl_vi_yank_arg (count, key) + int count, key; +{ + /* Readline thinks that the first word on a line is the 0th, while vi + thinks the first word on a line is the 1st. Compensate. */ + if (rl_explicit_arg) + rl_yank_nth_arg (count - 1, 0); + else + rl_yank_nth_arg ('$', 0); + + return (0); +} + +/* With an argument, move back that many history lines, else move to the + beginning of history. */ +int +rl_vi_fetch_history (count, c) + int count, c; +{ + int wanted; + + /* Giving an argument of n means we want the nth command in the history + file. The command number is interpreted the same way that the bash + `history' command does it -- that is, giving an argument count of 450 + to this command would get the command listed as number 450 in the + output of `history'. */ + if (rl_explicit_arg) + { + wanted = history_base + where_history () - count; + if (wanted <= 0) + rl_beginning_of_history (0, 0); + else + rl_get_previous_history (wanted, c); + } + else + rl_beginning_of_history (count, 0); + return (0); +} + +/* Search again for the last thing searched for. */ +int +rl_vi_search_again (count, key) + int count, key; +{ + switch (key) + { + case 'n': + rl_noninc_reverse_search_again (count, key); + break; + + case 'N': + rl_noninc_forward_search_again (count, key); + break; + } + return (0); +} + +/* Do a vi style search. */ +int +rl_vi_search (count, key) + int count, key; +{ + switch (key) + { + case '?': + rl_noninc_forward_search (count, key); + break; + + case '/': + rl_noninc_reverse_search (count, key); + break; + + default: + rl_ding (); + break; + } + return (0); +} + +/* Completion, from vi's point of view. */ +int +rl_vi_complete (ignore, key) + int ignore, key; +{ + if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) + { + if (!whitespace (rl_line_buffer[rl_point + 1])) + rl_vi_end_word (1, 'E'); + rl_point++; + } + + if (key == '*') + rl_complete_internal ('*'); /* Expansion and replacement. */ + else if (key == '=') + rl_complete_internal ('?'); /* List possible completions. */ + else if (key == '\\') + rl_complete_internal (TAB); /* Standard Readline completion. */ + else + rl_complete (0, key); + + if (key == '*' || key == '\\') + { + _rl_vi_set_last (key, 1, rl_arg_sign); + rl_vi_insertion_mode (1, key); + } + return (0); +} + +/* Tilde expansion for vi mode. */ +int +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); + return (0); +} + +/* Previous word in vi mode. */ +int +rl_vi_prev_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_vi_next_word (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_bWord (count, key); + else + rl_vi_bword (count, key); + + return (0); +} + +/* Next word in vi mode. */ +int +rl_vi_next_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_vi_prev_word (-count, key)); + + if (rl_point >= (rl_end - 1)) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_fWord (count, key); + else + rl_vi_fword (count, key); + return (0); +} + +/* Move to the end of the ?next? word. */ +int +rl_vi_end_word (count, key) + int count, key; +{ + if (count < 0) + { + rl_ding (); + return -1; + } + + if (_rl_uppercase_p (key)) + rl_vi_eWord (count, key); + else + rl_vi_eword (count, key); + return (0); +} + +/* Move forward a word the way that 'W' does. */ +int +rl_vi_fWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + /* Skip until whitespace. */ + while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + + /* Now skip whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + return (0); +} + +int +rl_vi_bWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point > 0) + { + /* If we are at the start of a word, move back to whitespace so + we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + if (rl_point > 0) + { + while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point])); + rl_point++; + } + } + return (0); +} + +int +rl_vi_eWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* 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])); + + if (rl_point && rl_point < rl_end) + { + /* Skip whitespace. */ + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Skip until whitespace. */ + while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Move back to the last character of the word. */ + rl_point--; + } + } + return (0); +} + +int +rl_vi_fword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + /* Move to white space (really non-identifer). */ + if (_rl_isident (rl_line_buffer[rl_point])) + { + while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + else /* if (!whitespace (rl_line_buffer[rl_point])) */ + { + while (!_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + + /* Move past whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + return (0); +} + +int +rl_vi_bword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point > 0) + { + int last_is_ident; + + /* If we are at the start of a word, move back to whitespace + so we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + /* If this character and the previous character are `opposite', move + back so we don't get messed up by the rl_point++ down there in + the while loop. Without this code, words like `l;' screw up the + function. */ + last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]); + if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) || + (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident)) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + if (rl_point > 0) + { + if (_rl_isident (rl_line_buffer[rl_point])) + while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point])); + else + while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point])); + rl_point++; + } + } + return (0); +} + +int +rl_vi_eword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < rl_end - 1) + { + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + if (rl_point < rl_end) + { + if (_rl_isident (rl_line_buffer[rl_point])) + while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); + else + while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) + && !whitespace (rl_line_buffer[rl_point])); + } + rl_point--; + } + return (0); +} + +int +rl_vi_insert_beg (count, key) + int count, key; +{ + rl_beg_of_line (1, key); + rl_vi_insertion_mode (1, key); + return (0); +} + +int +rl_vi_append_mode (count, key) + int count, key; +{ + if (rl_point < rl_end) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point++; + else + { + int point = rl_point; + rl_forward_char (1, key); + if (point == rl_point) + rl_point = rl_end; + } + } + rl_vi_insertion_mode (1, key); + return (0); +} + +int +rl_vi_append_eol (count, key) + int count, key; +{ + rl_end_of_line (1, key); + rl_vi_append_mode (1, key); + return (0); +} + +/* What to do in the case of C-d. */ +int +rl_vi_eof_maybe (count, c) + int count, c; +{ + return (rl_newline (1, '\n')); +} + +/* Insertion mode stuff. */ + +/* Switching from one mode to the other really just involves + switching keymaps. */ +int +rl_vi_insertion_mode (count, key) + int count, key; +{ + _rl_keymap = vi_insertion_keymap; + _rl_vi_last_key_before_insert = key; + return (0); +} + +static void +_rl_vi_save_insert (up) + UNDO_LIST *up; +{ + int len, start, end; + + if (up == 0) + { + if (vi_insert_buffer_size >= 1) + vi_insert_buffer[0] = '\0'; + return; + } + + start = up->start; + end = up->end; + len = end - start + 1; + if (len >= vi_insert_buffer_size) + { + vi_insert_buffer_size += (len + 32) - (len % 32); + vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); + } + strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); + vi_insert_buffer[len-1] = '\0'; +} + +void +_rl_vi_done_inserting () +{ + if (_rl_vi_doing_insert) + { + /* The `C', `s', and `S' commands set this. */ + rl_end_undo_group (); + /* Now, the text between rl_undo_list->next->start and + rl_undo_list->next->end is what was inserted while in insert + mode. It gets copied to VI_INSERT_BUFFER because it depends + on absolute indices into the line which may change (though they + probably will not). */ + _rl_vi_doing_insert = 0; + _rl_vi_save_insert (rl_undo_list->next); + vi_continued_command = 1; + } + else + { + if (_rl_vi_last_key_before_insert == 'i' && 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') + rl_end_undo_group (); + while (_rl_undo_group_level > 0) + rl_end_undo_group (); + vi_continued_command = 0; + } +} + +int +rl_vi_movement_mode (count, key) + int count, key; +{ + if (rl_point > 0) + rl_backward_char (1, key); + + _rl_keymap = vi_movement_keymap; + _rl_vi_done_inserting (); + return (0); +} + +int +rl_vi_arg_digit (count, c) + int count, c; +{ + if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) + return (rl_beg_of_line (1, c)); + else + return (rl_digit_argument (count, c)); +} + +/* Change the case of the next COUNT characters. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_vi_change_mbchar_case (count) + int count; +{ + wchar_t wc; + char mb[MB_LEN_MAX]; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0) + count--; + while (count-- && rl_point < rl_end) + { + mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); + if (iswupper (wc)) + wc = towlower (wc); + else if (iswlower (wc)) + wc = towupper (wc); + else + { + /* Just skip over chars neither upper nor lower case */ + rl_forward_char (1, 0); + continue; + } + + /* Vi is kind of strange here. */ + if (wc) + { + wctomb (mb, wc); + rl_begin_undo_group (); + rl_delete (1, 0); + rl_insert_text (mb); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, 0); + } + + return 0; +} +#endif + +int +rl_vi_change_case (count, ignore) + int count, ignore; +{ + char c = 0; + + /* Don't try this on an empty line. */ + if (rl_point >= rl_end) + return (0); + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + return (_rl_vi_change_mbchar_case (count)); +#endif + + while (count-- && rl_point < rl_end) + { + if (_rl_uppercase_p (rl_line_buffer[rl_point])) + c = _rl_to_lower (rl_line_buffer[rl_point]); + else if (_rl_lowercase_p (rl_line_buffer[rl_point])) + c = _rl_to_upper (rl_line_buffer[rl_point]); + else + { + /* Just skip over characters neither upper nor lower case. */ + rl_forward_char (1, c); + continue; + } + + /* Vi is kind of strange here. */ + if (c) + { + rl_begin_undo_group (); + rl_delete (1, c); + _rl_insert_char (1, c); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, c); + } + return (0); +} + +int +rl_vi_put (count, key) + int 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); + rl_backward_char (1, key); + return (0); +} + +int +rl_vi_check () +{ + if (rl_point && 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--; + } + return (0); +} + +int +rl_vi_column (count, key) + int count, key; +{ + if (count > rl_end) + rl_end_of_line (1, key); + else + rl_point = count - 1; + return (0); +} + +int +rl_vi_domove (key, nextkey) + int key, *nextkey; +{ + int c, save; + int old_end; + + rl_mark = rl_point; + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + *nextkey = c; + + if (!member (c, vi_motion)) + { + if (_rl_digit_p (c)) + { + save = rl_numeric_arg; + rl_numeric_arg = _rl_digit_value (c); + rl_digit_loop1 (); + rl_numeric_arg *= save; + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); /* real command */ + RL_UNSETSTATE(RL_STATE_MOREINPUT); + *nextkey = c; + } + else if (key == c && (key == 'd' || key == 'y' || key == 'c')) + { + rl_mark = rl_end; + rl_beg_of_line (1, c); + _rl_vi_last_motion = c; + return (0); + } + else + return (-1); + } + + _rl_vi_last_motion = c; + + /* Append a blank character temporarily so that the motion routines + work right at the end of the line. */ + old_end = rl_end; + rl_line_buffer[rl_end++] = ' '; + rl_line_buffer[rl_end] = '\0'; + + _rl_dispatch (c, _rl_keymap); + + /* Remove the blank that we added. */ + rl_end = old_end; + rl_line_buffer[rl_end] = '\0'; + if (rl_point > rl_end) + rl_point = rl_end; + + /* No change in position means the command failed. */ + if (rl_mark == rl_point) + return (-1); + + /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next + word. If we are not at the end of the line, and we are on a + non-whitespace character, move back one (presumably to whitespace). */ + if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && + !whitespace (rl_line_buffer[rl_point])) + rl_point--; + + /* If cw or cW, back up to the end of a word, so the behaviour of ce + or cE is the actual result. Brute-force, no subtlety. */ + if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W')) + { + /* Don't move farther back than where we started. */ + while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + /* Posix.2 says that if cw or cW moves the cursor towards the end of + the line, the character under the cursor should be deleted. */ + if (rl_point == rl_mark) + rl_point++; + else + { + /* Move past the end of the word so that the kill doesn't + remove the last letter of the previous word. Only do this + if we are not at the end of the line. */ + if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point])) + rl_point++; + } + } + + if (rl_mark < rl_point) + SWAP (rl_point, rl_mark); + + 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; + + 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 (c >= 0 && _rl_keymap[c].type == ISFUNC && + _rl_keymap[c].function == rl_universal_argument) + { + rl_numeric_arg *= 4; + continue; + } + + 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; + } + } + + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return (0); +} + +int +rl_vi_delete_to (count, key) + int count, key; +{ + int c; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + else if (vi_redoing) + rl_stuff_char (_rl_vi_last_motion); + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. */ + if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + rl_kill_text (rl_point, rl_mark); + return (0); +} + +int +rl_vi_change_to (count, key) + int count, key; +{ + int c, start_pos; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + else if (vi_redoing) + rl_stuff_char (_rl_vi_last_motion); + + start_pos = rl_point; + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. c[wW] are handled by special-case code in rl_vi_domove(), + and already leave the mark at the correct location. */ + if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + /* The cursor never moves with c[wW]. */ + if ((_rl_to_upper (c) == 'W') && rl_point < start_pos) + rl_point = start_pos; + + if (vi_redoing) + { + if (vi_insert_buffer && *vi_insert_buffer) + rl_begin_undo_group (); + rl_delete_text (rl_point, rl_mark); + if (vi_insert_buffer && *vi_insert_buffer) + { + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); + } + } + else + { + rl_begin_undo_group (); /* to make the `u' command work */ + rl_kill_text (rl_point, rl_mark); + /* `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); + } + + return (0); +} + +int +rl_vi_yank_to (count, key) + int count, key; +{ + int c, save = rl_point; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. */ + if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + rl_begin_undo_group (); + rl_kill_text (rl_point, rl_mark); + rl_end_undo_group (); + rl_do_undo (); + rl_point = save; + + return (0); +} + +int +rl_vi_delete (count, key) + int count, key; +{ + int end; + + if (rl_end == 0) + { + rl_ding (); + return -1; + } + + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + else + end = rl_point + count; + + if (end >= rl_end) + end = rl_end; + + rl_kill_text (rl_point, end); + + if (rl_point > 0 && rl_point == rl_end) + rl_backward_char (1, key); + return (0); +} + +int +rl_vi_back_to_indent (count, key) + int count, key; +{ + rl_beg_of_line (1, key); + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + return (0); +} + +int +rl_vi_first_print (count, key) + int count, key; +{ + return (rl_vi_back_to_indent (1, key)); +} + +int +rl_vi_char_search (count, key) + int count, key; +{ +#if defined (HANDLE_MULTIBYTE) + static char *target; + static int mb_len; +#else + static char target; +#endif + static int orig_dir, dir; + + if (key == ';' || key == ',') + dir = key == ';' ? orig_dir : -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; + break; + + case 'T': + orig_dir = dir = BTO; + break; + + case 'f': + orig_dir = dir = FFIND; + break; + + case 'F': + orig_dir = dir = BFIND; + break; + } + } + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (count, dir, target, mb_len)); +#else + return (_rl_char_search_internal (count, dir, target)); +#endif +} + +/* Match brackets */ +int +rl_vi_match (ignore, key) + int ignore, key; +{ + int count = 1, brack, pos, tmp, pre; + + pos = rl_point; + if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + pre = rl_point; + rl_forward_char (1, key); + if (pre == rl_point) + break; + } + } + else + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && + rl_point < rl_end - 1) + rl_forward_char (1, key); + + if (brack <= 0) + { + rl_point = pos; + rl_ding (); + return -1; + } + } + + pos = rl_point; + + if (brack < 0) + { + while (count) + { + tmp = pos; + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos--; + else + { + pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); + if (tmp == pos) + pos--; + } + if (pos >= 0) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return -1; + } + } + } + else + { /* brack > 0 */ + while (count) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos++; + else + pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY); + + if (pos < rl_end) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return -1; + } + } + } + rl_point = pos; + return (0); +} + +int +rl_vi_bracktype (c) + int c; +{ + switch (c) + { + case '(': return 1; + case ')': return -1; + case '[': return 2; + case ']': return -2; + case '{': return 3; + case '}': return -3; + default: return 0; + } +} + +/* 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; +{ + 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); + } + + if (c == '\033' || c == CTRL ('C')) + return -1; + + while (count-- && rl_point < rl_end) + { + rl_begin_undo_group (); + + rl_delete (1, c); +#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); + } + else +#endif + _rl_insert_char (1, c); + if (count == 0) + rl_backward_char (1, c); + + rl_end_undo_group (); + } + return (0); +} + +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 ' */ + + return (rl_vi_change_to (count, 'c')); +} + +int +rl_vi_overstrike (count, key) + int count, key; +{ + if (_rl_vi_doing_insert == 0) + { + _rl_vi_doing_insert = 1; + rl_begin_undo_group (); + } + + if (count > 0) + { + _rl_overwrite_char (count, key); + vi_replace_count += count; + } + + return (0); +} + +int +rl_vi_overstrike_delete (count, key) + int count, key; +{ + int i, s; + + for (i = 0; i < count; i++) + { + if (vi_replace_count == 0) + { + rl_ding (); + break; + } + s = rl_point; + + if (rl_do_undo ()) + vi_replace_count--; + + if (rl_point == s) + rl_backward_char (1, key); + } + + if (vi_replace_count == 0 && _rl_vi_doing_insert) + { + rl_end_undo_group (); + rl_do_undo (); + _rl_vi_doing_insert = 0; + } + return (0); +} + +int +rl_vi_replace (count, key) + int count, key; +{ + int i; + + vi_replace_count = 0; + + if (!vi_replace_map) + { + vi_replace_map = rl_make_bare_keymap (); + + for (i = ' '; i < KEYMAP_SIZE; i++) + vi_replace_map[i].function = rl_vi_overstrike; + + vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; + vi_replace_map[ESC].function = rl_vi_movement_mode; + vi_replace_map[RETURN].function = rl_newline; + vi_replace_map[NEWLINE].function = rl_newline; + + /* If the normal vi insertion keymap has ^H bound to erase, do the + same here. Probably should remove the assignment to RUBOUT up + there, but I don't think it will make a difference in real life. */ + if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC && + vi_insertion_keymap[CTRL ('H')].function == rl_rubout) + vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + + } + _rl_keymap = vi_replace_map; + return (0); +} + +#if 0 +/* Try to complete the word we are standing on or the word that ends with + the previous character. A space matches everything. Word delimiters are + space and ;. */ +int +rl_vi_possible_completions() +{ + int save_pos = rl_point; + + if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') + { + while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' && + rl_line_buffer[rl_point] != ';') + rl_point++; + } + else if (rl_line_buffer[rl_point - 1] == ';') + { + rl_ding (); + return (0); + } + + rl_possible_completions (); + rl_point = save_pos; + + return (0); +} +#endif + +/* Functions to save and restore marks. */ +int +rl_vi_set_mark (count, key) + int count, key; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch < 'a' || ch > 'z') + { + rl_ding (); + return -1; + } + ch -= 'a'; + vi_mark_chars[ch] = rl_point; + return 0; +} + +int +rl_vi_goto_mark (count, key) + int count, key; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch == '`') + { + rl_point = rl_mark; + return 0; + } + else if (ch < 'a' || ch > 'z') + { + rl_ding (); + return -1; + } + + ch -= 'a'; + if (vi_mark_chars[ch] == -1) + { + rl_ding (); + return -1; + } + rl_point = vi_mark_chars[ch]; + return 0; +} + +#endif /* VI_MODE */ diff --git a/readline-4.3.orig/xmalloc.c b/readline-4.3.orig/xmalloc.c new file mode 100644 index 0000000..8985d34 --- /dev/null +++ b/readline-4.3.orig/xmalloc.c @@ -0,0 +1,88 @@ +/* xmalloc.c -- safe versions of malloc and realloc */ + +/* Copyright (C) 1991 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Memory Allocation and Deallocation. */ +/* */ +/* **************************************************************** */ + +static void +memory_error_and_abort (fname) + char *fname; +{ + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Return a pointer to free()able block of memory large enough + to hold BYTES number of bytes. If the memory cannot be allocated, + print an error message and abort. */ +PTR_T +xmalloc (bytes) + size_t bytes; +{ + PTR_T temp; + + temp = malloc (bytes); + if (temp == 0) + memory_error_and_abort ("xmalloc"); + return (temp); +} + +PTR_T +xrealloc (pointer, bytes) + PTR_T pointer; + size_t bytes; +{ + PTR_T temp; + + temp = pointer ? realloc (pointer, bytes) : malloc (bytes); + + if (temp == 0) + memory_error_and_abort ("xrealloc"); + return (temp); +} + +/* Use this as the function to call when adding unwind protects so we + don't need to know what free() returns. */ +void +xfree (string) + PTR_T string; +{ + if (string) + free (string); +} diff --git a/readline-4.3.orig/xmalloc.h b/readline-4.3.orig/xmalloc.h new file mode 100644 index 0000000..9cb08ba --- /dev/null +++ b/readline-4.3.orig/xmalloc.h @@ -0,0 +1,46 @@ +/* xmalloc.h -- memory allocation that aborts on errors. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_XMALLOC_H_) +#define _XMALLOC_H_ + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +#else +# include +#endif + +#ifndef PTR_T + +#ifdef __STDC__ +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* !PTR_T */ + +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); + +#endif /* _XMALLOC_H_ */ diff --git a/readline-4.3/CHANGELOG-ReadLine b/readline-4.3/CHANGELOG-ReadLine new file mode 100644 index 0000000..350defa --- /dev/null +++ b/readline-4.3/CHANGELOG-ReadLine @@ -0,0 +1,699 @@ +[Readline-specific changelog. Descriptions of changes to the source are + found in the bash changelog.] + + 6/9 + --- +Makefile.in + - quote value of ${INSTALL_DATA} when passing it to makes in + subdirectories + + 7/1 + --- +Makefile.in + - don't pass INSTALL_DATA to a make in the `doc' subdirectory; let + autoconf set the value itself in the Makefile + - removed a stray `-' before $(RANLIB) in the `install' recipe + +doc/Makefile.in + - add a VPATH assignment so the documentation is not remade if it's + already up-to-date in the distribution + +configure.in + - call AC_SUBST(LOCAL_LDFLAGS), since Makefile.in contains + @LOCAL_LDFLAGS@ + + 7/9 + --- + +config.h.in + - add define lines for STRUCT_WINSIZE_IN_SYS_IOCTL and + STRUCT_WINSIZE_IN_TERMIOS + +configure.in + - call BASH_STRUCT_WINSIZE to look for the definition of + `struct winsize' + + 7/17 + ---- +configure.in + - call AC_MINIX + +config.h.in + - add define line for AC_MINIX + + 7/18 + ---- +Makefile.in + - add `install-shared' and `uninstall-shared' targets + + 8/4 + --- +Makefile.in + - install and uninstall libhistory.a in the `install' and + `uninstall' targets + + 9/4 + --- +configure.in + - bumped LIBVERSION up to 2.1.1, indicating that this is patch + level 1 to release 2.1 + + + 9/16 + ---- +Makefile.in + - `make distclean' now descends into the `examples' subdir + +doc/Makefile.in + - the `distclean' and `maintainer-clean' targets should remove + Makefile + +examples/Makefile.in + - added the various clean targets + + 4/2 + --- +configure.in + - bumped LIBVERSION up to 2.2 + + 4/18 + ---- +[readline-2.2 released] + + 4/20 + ---- +Makefile.in + - make `libhistory.a' a dependency of `install' + - fixed a typo in the recipe for `install' that copied libreadline.a + to libhistory.old right after installing it + + 4/27 + ---- +doc/Makefile.in + - install {readline,history}.info out of the source directory if + they are not found in the current (build) directory -- only an + issue if the libraries are built in a different directory than + the source directory + + 5/1 + --- +support/shobj-conf + - script from the bash distribution to do shared object and library + configuration + +shlib/Makefile.in + - new directory and makefile to handle building shared versions of + libreadline and libhistory, controlled by support/shobj-conf + + 5/7 + --- +doc/Makefile.in + - set SHELL to /bin/sh, rather than relying on make to be correct + + 5/14 + ---- +savestring.c + - new file, moved from shell.c, for backwards compatibility + +Makefile.in, shlib/Makefile.in + - make sure savestring.c is compiled and added to libreadline and + libhistory + +[THERE ARE NO MORE #ifdef SHELL LINES IN THE C SOURCE FILES.] + + 5/15 + ---- +README + - updated description of shared library creation for the new scheme + +[THERE ARE NO MORE #ifdef SHELL LINES IN ANY OF THE SOURCE FILES.] + +Makefile.in + - bumped SHLIB_MAJOR up to 4 since we've augmented the library + API + - rlconf.h is now one of the installed headers, so applications can + find out whether things like vi-mode are available in the installed + libreadline + + 5/20 + ---- +configure.in + - changed RL_LIBRARY_VERSION to 4.0 to match the version of the + installed shared libraries + + 6/5 + --- +rlstdc.h + - new file + +Makefile.in + - rlstdc.h is now one of the installed headers + + 8/3 + --- +shlib/Makefile.in + - made the suffix rule that creates xx.so from xx.c write the + compiler output to `a.o', which is then mv'd to xx.so, because + some compilers (Sun WSpro 4.2, for example) don't allow any + suffixes other than `.o' for `cc -c' (not even `a.out') + + 9/15 + ---- + +Makefile.in + - AR and ARFLAGS are now substituted by configure, used in recipes + that build the libraries + +configure.in + - use AC_CHECK_PROG to check for ar + - set ARFLAGS if it has not already been set in the environment + + 10/5 + ---- +Makefile.in + - removed savestring.o from object file list + + 10/28 + ----- +shlib/Makefile.in + - don't use a fixed filename in the .c.so suffix rule to avoid + problems with parallel makes + + 12/21 + ----- +support/shlib-install + - new script to install shared readline and history libraries + +shlib/Makefile.in + - changed to call shlib-install for install and uninstall targets + +[readline-4.0-beta1 frozen] + + 12/22 + ----- +configure.in + - call AC_SUBST for SHOBJ_XLDFLAGS and SHLIB_LIBS + +shlib/Makefile.in + - SHOBJ_XLDFLAGS and SHLIB_LIBS are now substituted by configure + - add $(SHLIB_LIBS) at end of command line that builds the shared + libraries (currently needed only by AIX 4.2) + + 12/31 + ----- +MANIFEST, MANIFEST.doc + - the TOC html files are no longer generated and no longer part of + the distribution + + 2/18/1999 + --------- +configure.in + - set MAKE_SHELL to /bin/sh and substitute into the Makefiles + +Makefile.in,{doc,examples,shlib}/Makefile.in + - set SHELL from @MAKE_SHELL@ + +[readline-4.0 released] + + 3/11 + ---- +doc/Makefile.in + - removed references to HTMLTOC, since separate HTML table-of-contents + files are no longer created + +examples/Makefile.in + - remove `*.exe' in clean target for MS-DOS + +Makefile.in + - make `readline' target depend on ./libreadline.a + - configure now substitutes TERMCAP_LIB into Makefile.in + - use ${TERMCAP_LIB} instead of -ltermcap in recipe for `readline' + - clean target now removes readline and readline.exe in case they + get built + +configure.in + - use `pwd.exe' to set BUILD_DIR on MS-DOS DJGPP + + 3/15 + ---- +support/shlib-install + - Irix 5.x and Irix 6.x should install shared libraries like Solaris 2 + - changes for installing on hp-ux 1[01].x + + 3/23 + ---- +configure.in + - make sure that the $CC argument to shobj-conf is quoted + + 4/8 + --- + +xmalloc.h, rlprivate.h, rlshell.h + - new files + +Makefile.in,shlib/Makefile.in + - add dependencies on xmalloc.h, rlshell.h + - add xmalloc.h, rlprivate.h, rlshell.h to list of header files + +MANIFEST + - add xmalloc.h, rlprivate.h, rlshell.h + + 4/9 + --- +Makefile.in,shlib/Makefile.in + - add dependencies on rlprivate.h + + 4/13 + ---- +doc/Makefile.in + - add variable, PSDVI, which is the desired resolution of the + generated postscript files. Set to 300 because I don't have + any 600-dpi printers + - set LANGUAGE= before calling makeinfo, so messages are in English + - add rluserman.{info,dvi,ps,html} to appropriate variables + - add rules to create rluserman.{info,dvi,ps,html} + - install and uninstall rluserman.info, but don't update the directory + file in $(infodir) yet + +MANIFEST + - add doc/rluserman.{texinfo,info,dvi,ps,html} + + 4/30 + ---- +configure.in + - updated library version to 4.1 + + 5/3 + --- +configure.in + - SHLIB_MAJOR and SHLIB_MINOR shared library version numbers are + constructed from $LIBRARY_VERSION and substituted into Makefiles + + 5/5 + --- +support/shlib-install + - OSF/1 installs shared libraries like Solaris + +Makefile.in + - broke the header file install and uninstall into two new targets: + install-headers and uninstall-headers + - install and uninstall depend on install-headers and uninstall-headers + respectively + - changed install-shared and uninstall-shared targets to depend on + install-headers and uninstall-headers, respectively, so users may + choose to install only the shared libraries. I'm not sure about + the uninstall one yet -- maybe it should check whether or not + the static libraries are installed and not remove the header files + if they are + + 9/3 + --- +configure.in, config.h.in + - added test for memmove (for later use) + - changed version to 4.1-beta1 + + 9/13 + ---- +examples/rlfe.c + - Per Bothner's `rlfe' readline front-end program + +examples/Makefile.in + - added rules to build rlfe + + 9/21 + ---- +support/shlib-install + - changes to handle FreeBSD-3.x elf or a.out shared libraries, which + have different semantics and need different naming conventions + + 1/24/2000 + --------- +doc/Makefile.in + - remove *.bt and *.bts on `make clean' + + 2/4 + --- + + +configure.in + - changed LIBVERSION to 4.1-beta5 + + 3/17/2000 + --------- +[readline-4.1 released] + + 3/23 + ---- +Makefile.in + - remove the `-t' argument to ranlib in the install recipe; some + ranlibs don't have it and attempt to create a file named `-t' + + 3/27 + ---- +support/shlib-install + - install shared libraries unwritable by anyone on HP-UX + - changed symlinks to relative pathnames on all platforms + +shlib/Makefile.in + - added missing `includedir' assignment, substituted by configure + +Makefile.in + - added missing @SET_MAKE@ so configure can set $MAKE appropriately + +configure.in + - add call to AC_PROG_MAKE_SET + + 8/30 + ---- +shlib/Makefile.in + - change the soname bound into the shared libraries, so it includes + only the major version number. If it includes the minor version, + programs depending on it must be rebuilt (which may or may not be + a bad thing) + + 9/6 + --- +examples/rlfe.c + - add -l option to log input and output (-a option appends to logfile) + - add -n option to set readline application name + - add -v, -h options for version and help information + - change a few things because getopt() is now used to parse arguments + + 9/12 + ---- +support/shlib-install + - fix up the libname on HPUX 11 + + 10/18 + ----- +configure.in + - changed library version to 4.2-alpha + + 10/30 + ----- +configure.in + - add -fsigned-char to LOCAL_CFLAGS for Linux running on the IBM + S/390 + +Makefile.in + - added new file, rltypedefs.h, installed by default with `make install' + + 11/2 + ---- +compat.c + - new file, with backwards-compatibility function definitions + +Makefile.in,shlib/Makefile.in + - make sure that compat.o/compat.so are built and linked apppropriately + +support/shobj-conf + - picked up bash version, which means that shared libs built on + linux and BSD/OS 4.x will have an soname that does not include + the minor version number + + 11/13 + ----- +examples/rlfe.c + - rlfe can perform filename completion for relative pathnames in the + inferior process's context if the OS supports /proc/PID/cwd (linux + does it OK, Solaris is slightly warped, none of the BSDs have it) + + 11/17/2000 + ---------- +[readline-4.2-alpha released] + + 11/27 + ----- +Makefile.in,shlib/Makefile.in + - added dependencies for rltypedefs.h + +shlib/Makefile.in + - changed dependencies on histlib.h to $(topdir)/histlib.h + + 1/22 + ---- +configure.in + - changed release version to 4.2-beta + + 2/2 + --- +examples/Makefile.in + - build histexamp as part of the examples + + 2/5 + --- +doc/Makefile.in + - don't remove the dvi, postscript, html, info, and text `objects' + on a `make distclean', only on a `make maintainer-clean' + + 3/6 + --- +doc/history.{0,3}, doc/history_3.ps + - new manual page for history library + +doc/Makefile.in + - rules to install and uninstall history.3 in ${man3dir} + - rules to build history.0 and history_3.ps + + 4/2 + --- +configure.in + - changed LIBVERSION to `4.2' + + 4/5 + --- +[readline-4.2 frozen] + + 4/9 + --- +[readline-4.2 released] + + 5/2 + --- +Makefile.in,{doc,examples,shlib}/Makefile.in + - added support for DESTDIR installation root prefix, to support + building packages + +doc/Makefile.in + - add an info `dir' file entry for rluserman.info on `make install' + - change man1ext to `.1' and man3ext to `.3' + - install man pages with a $(man3ext) extension in the target directory + - add support for installing html documentation if `htmldir' has a + value + +Makefile.in + - on `make install', install from the `shlib' directory, too + - on `make uninstall', uninstall in the `doc' and `shlib' + subdirectories, too + +support/shlib-install + - add `freebsdelf*', `freebsdaout*', Hurd, `sysv4*', `sysv5*', `dgux*' + targets for symlink creation + + 5/7 + --- +configure.in, config.h.in + - check for , define HAVE_LIMITS_H if found + + 5/8 + --- +aclocal.m4 + - pick up change to BASH_CHECK_LIB_TERMCAP that adds check for + libtinfo (termcap-specific portion of ncurses-5.2) + + 5/9 + --- +configure.in + - call AC_C_CONST to find out whether or not the compiler supports + `const' + +config.h.in + - placeholder for `const' define, if any + + 5/10 + ---- +configure.in + - fix AC_CHECK_PROG(ar, ...) test to specify right value for the + case where ar is not found; should produce a better error message + + 5/14 + ---- +configure.in,config.h.in + - check for vsnprintf, define HAVE_VSNPRINTF if found + + 5/21 + ---- +configure.in, config.h.in + - add checks for size_t, ssize_t + + 5/30 + ---- +configure.in + - update autoconf to version 2.50, use in AC_PREREQ + - changed AC_INIT to new flavor + - added AC_CONFIG_SRCDIR + - AC_CONFIG_HEADER -> AC_CONFIG_HEADERS + - call AC_C_PROTOTYPES + - AC_RETSIGTYPE -> AC_TYPE_SIGNAL + + 8/22 + ---- +configure.in + - updated the version number to 4.2a + +Makefile.in,shlib/Makefile.in + - make sure tilde.o is built -DREADLINE_LIBRARY when being built as + part of the standalone library, so it picks up the right include + files + + 8/23 + ---- +support/shlib-install + - support for Darwin/MacOS X shared library installation + + 9/24 + ---- +examples/readlinebuf.h + - a new file, a C++ streambuf interface that uses readline for I/O. + Donated by Dimitris Vyzovitis + + 10/9 + ---- +configure.in + - replaced call to BASH_HAVE_TIOCGWINSZ with AC_HEADER_TIOCGWINSZ + +[readline-4.2a-beta1 frozen] + + 10/15 + ----- +configure.in, config.h.in + - check for , define HAVE_MEMORY_H if found + - check for , define HAVE_STRINGS_H if found + + 10/18 + ----- +configure.in, config.h.in + - check for isascii, define HAVE_ISASCII if found + +configure.in + - changed the macro names from bash as appropriate: + BASH_SIGNAL_CHECK -> BASH_SYS_SIGNAL_VINTAGE + BASH_REINSTALL_SIGHANDLERS -> BASH_SYS_REINSTALL_SIGHANDLERS + BASH_MISC_SPEED_T -> BASH_CHECK_SPEED_T + + 10/22 + ----- +configure.in + - check for isxdigit with AC_CHECK_FUNCS + +config.h.in + - new define for HAVE_ISXDIGIT + + 10/29 + ----- +configure.in, config.h.in + - check for strpbrk with AC_CHECK_FUNCS, define HAVE_STRPBRK if found + + 11/1 + ---- +Makefile.in + - make sure DESTDIR is passed to install and uninstall makes in + subdirectories + - when saving old copies of installed libraries, make sure we use + DESTDIR for the old installation tree + +[readline-4.2a-rc1 frozen] + + 11/2 + ---- +Makefile.in, shlib/Makefile.in + - don't put -I$(includedir) into CFLAGS + + 11/15 + ----- +[readline-4.2a released] + + 11/20 + ----- +examples/rlcat.c + - new file + +examples/Makefile.in + - changes for rlcat + + 11/28 + ----- +configure.in + - default TERMCAP_LIB to -lcurses if $prefer_curses == yes (as when + --with-curses is supplied) + +examples/Makefile.in + - substitute @LDFLAGS@ in LDFLAGS assignment + + 11/29 + ----- +config.h.in + - add necessary defines for multibyte include files and functions + - add code to define HANDLE_MULTIBYTE if prerequisites are met + +configure.in + - call BASH_CHECK_MULTIBYTE + + 12/14 + ----- +config.h.in + - add #undef PROTOTYPES, filled in by AC_C_PROTOTYPES + + 12/17 + ----- +config.h.in + - moved HANDLE_MULTIBYTE code to rlmbutil.h + +rlmbutil.h, mbutil.c + - new files + +Makefile.in, shlib/Makefile.in + - added rules for mbutil.c + + 12/20 + ----- +configure.in + - added --enable-shared, --enable-static options to configure to + say which libraries are built by default (both default to yes) + - if SHLIB_STATUS == 'unsupported', turn off default shared library + building + - substitute new STATIC_TARGET, SHARED_TARGET, STATIC_INSTALL_TARGET, + and SHARED_INSTALL_TARGET + +Makefile.in + - `all' target now depends on (substituted) @STATIC_TARGET@ and + @SHARED_TARGET@ + - `install' target now depends on (substituted) @STATIC_INSTALL_TARGET@ + and @SHARED_INSTALL_TARGET@ + +INSTALL, README + - updated with new info about --enable-shared and --enable-static + + 1/10/2002 + --------- +configure.in + - bumped the library version number to 4.3 + + 1/24 + ---- +Makefile.in,shlib/Makefile.in + - changes for new file, text.c, with character and text handling + functions from readline.c + + 2/20 + ---- +{configure.config.h}.in + - call AC_C_CHAR_UNSIGNED, define __CHAR_UNSIGNED__ if chars are + unsigned by default + + 5/20 + ---- +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 diff --git a/readline-4.3/CHANGES b/readline-4.3/CHANGES new file mode 100644 index 0000000..bc9fe94 --- /dev/null +++ b/readline-4.3/CHANGES @@ -0,0 +1,612 @@ +This document details the changes between this version, readline-4.3, +and the previous version, readline-4.2a. + +1. Changes to Readline + +a. Fixed output of comment-begin character when listing variable values. + +b. Added some default key bindings for common escape sequences produced by + HOME and END keys. + +c. Fixed the mark handling code to be more emacs-compatible. + +d. A bug was fixed in the code that prints possible completions to keep it + from printing empty strings in certain circumstances. + +e. Change the key sequence printing code to print ESC as M\- if ESC is a + meta-prefix character -- it's easier for users to understand than \e. + +f. Fixed unstifle_history() to return values that match the documentation. + +g. Fixed the event loop (rl_event_hook) to handle the case where the input + file descriptor is invalidated. + +h. Fixed the prompt display code to work better when the application has a + custom redisplay function. + +i. Changes to make reading and writing the history file a little faster, and + to cope with huge history files without calling abort(3) from xmalloc. + +j. The vi-mode `S' and `s' commands are now undone correctly. + +k. Fixed a problem which caused the display to be messed up when the last + line of a multi-line prompt (possibly containing invisible characters) + was longer than the screen width. + +2. New Features in Readline + +a. Support for key `subsequences': allows, e.g., ESC and ESC-a to both + be bound to readline functions. Now the arrow keys may be used in vi + insert mode. + +b. When listing completions, and the number of lines displayed is more than + the screen length, readline uses an internal pager to display the results. + This is controlled by the `page-completions' variable (default on). + +c. New code to handle editing and displaying multibyte characters. + +d. The behavior introduced in bash-2.05a of deciding whether or not to + append a slash to a completed name that is a symlink to a directory has + been made optional, controlled by the `mark-symlinked-directories' + variable (default is the 2.05a behavior). + +e. The `insert-comment' command now acts as a toggle if given a numeric + argument: if the first characters on the line don't specify a + comment, insert one; if they do, delete the comment text + +f. New application-settable completion variable: + rl_completion_mark_symlink_dirs, allows an application's completion + function to temporarily override the user's preference for appending + slashes to names which are symlinks to directories. + +g. New function available to application completion functions: + rl_completion_mode, to tell how the completion function was invoked + and decide which argument to supply to rl_complete_internal (to list + completions, etc.). + +h. Readline now has an overwrite mode, toggled by the `overwrite-mode' + bindable command, which could be bound to `Insert'. + +i. New application-settable completion variable: + rl_completion_suppress_append, inhibits appending of + rl_completion_append_character to completed words. + +j. New key bindings when reading an incremental search string: ^W yanks + the currently-matched word out of the current line into the search + string; ^Y yanks the rest of the current line into the search string, + DEL or ^H deletes characters from the search string. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-4.2a, +and the previous version, readline-4.2. + +1. Changes to Readline + +a. More `const' and type casting fixes. + +b. Changed rl_message() to use vsnprintf(3) (if available) to fix buffer + overflow problems. + +c. The completion code no longer appends a `/' or ` ' to a match when + completing a symbolic link that resolves to a directory name, unless + the match does not add anything to the word being completed. This + means that a tab will complete the word up to the full name, but not + add anything, and a subsequent tab will add a slash. + +d. Fixed a trivial typo that made the vi-mode `dT' command not work. + +e. Fixed the tty code so that ^S and ^Q can be inserted with rl_quoted_insert. + +f. Fixed the tty code so that ^V works more than once. + +g. Changed the use of __P((...)) for function prototypes to PARAMS((...)) + because the use of __P in typedefs conflicted g++ and glibc. + +h. The completion code now attempts to do a better job of preserving the + case of the word the user typed if ignoring case in completions. + +i. Readline defaults to not echoing the input and lets the terminal + initialization code enable echoing if there is a controlling terminal. + +j. The key binding code now processes only two hex digits after a `\x' + escape sequence, and the documentation was changed to note that the + octal and hex escape sequences result in an eight-bit value rather + than strict ASCII. + +k. Fixed a few places where negative array subscripts could have occurred. + +l. Fixed the vi-mode code to use a better method to determine the bounds of + the array used to hold the marks, and to avoid out-of-bounds references. + +m. Fixed the defines in chardefs.h to work better when chars are signed. + +n. Fixed configure.in to use the new names for bash autoconf macros. + +o. Readline no longer attempts to define its own versions of some ctype + macros if they are implemented as functions in libc but not as macros in + . + +p. Fixed a problem where rl_backward could possibly set point to before + the beginning of the line. + +q. Fixed Makefile to not put -I/usr/include into CFLAGS, since it can cause + include file problems. + +2. New Features in Readline + +a. Added extern declaration for rl_get_termcap to readline.h, making it a + public function (it was always there, just not in readline.h). + +b. New #defines in readline.h: RL_READLINE_VERSION, currently 0x0402, + RL_VERSION_MAJOR, currently 4, and RL_VERSION_MINOR, currently 2. + +c. New readline variable: rl_readline_version, mirrors RL_READLINE_VERSION. + +d. New bindable boolean readline variable: match-hidden-files. Controls + completion of files beginning with a `.' (on Unix). Enabled by default. + +e. The history expansion code now allows any character to terminate a + `:first-' modifier, like csh. + +f. The incremental search code remembers the last search string and uses + it if ^R^R is typed without a search string. + +h. New bindable variable `history-preserve-point'. If set, the history + code attempts to place the user at the same location on each history + line retrived with previous-history or next-history. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-4.2, +and the previous version, readline-4.1. + +1. Changes to Readline + +a. When setting the terminal attributes on systems using `struct termio', + readline waits for output to drain before changing the attributes. + +b. A fix was made to the history word tokenization code to avoid attempts to + dereference a null pointer. + +c. Readline now defaults rl_terminal_name to $TERM if the calling application + has left it unset, and tries to initialize with the resultant value. + +d. Instead of calling (*rl_getc_function)() directly to get input in certain + places, readline now calls rl_read_key() consistently. + +e. Fixed a bug in the completion code that allowed a backslash to quote a + single quote inside a single-quoted string. + +f. rl_prompt is no longer assigned directly from the argument to readline(), + but uses memory allocated by readline. This allows constant strings to + be passed to readline without problems arising when the prompt processing + code wants to modify the string. + +g. Fixed a bug that caused non-interactive history searches to return the + wrong line when performing multiple searches backward for the same string. + +h. Many variables, function arguments, and function return values are now + declared `const' where appropriate, to improve behavior when linking with + C++ code. + +i. The control character detection code now works better on systems where + `char' is unsigned by default. + +j. The vi-mode numeric argument is now capped at 999999, just like emacs mode. + +k. The Function, CPFunction, CPPFunction, and VFunction typedefs have been + replaced with a set of specific prototyped typedefs, though they are + still in the readline header files for backwards compatibility. + +m. Nearly all of the (undocumented) internal global variables in the library + now have an _rl_ prefix -- there were a number that did not, like + screenheight, screenwidth, alphabetic, etc. + +n. The ding() convenience function has been renamed to rl_ding(), though the + old function is still defined for backwards compatibility. + +o. The completion convenience functions filename_completion_function, + username_completion_function, and completion_matches now have an rl_ + prefix, though the old names are still defined for backwards compatibility. + +p. The functions shared by readline and bash (linkage is satisfied from bash + when compiling with bash, and internally otherwise) now have an sh_ prefix. + +q. Changed the shared library creation procedure on Linux and BSD/OS 4.x so + that the `soname' contains only the major version number rather than the + major and minor numbers. + +r. Fixed a redisplay bug that occurred when the prompt spanned more than one + physical line and contained invisible characters. + +s. Added a missing `includedir' variable to the Makefile. + +t. When installing the shared libraries, make sure symbolic links are relative. + +u. Added configure test so that it can set `${MAKE}' appropriately. + +v. Fixed a bug in rl_forward that could cause the point to be set to before + the beginning of the line in vi mode. + +w. Fixed a bug in the callback read-char interface to make it work when a + readline function pushes some input onto the input stream with + rl_execute_next (like the incremental search functions). + +x. Fixed a file descriptor leak in the history file manipulation code that + was tripped when attempting to truncate a non-regular file (like + /dev/null). + +y. Changes to make all of the exported readline functions declared in + readline.h have an rl_ prefix (rltty_set_default_bindings is now + rl_tty_set_default_bindings, crlf is now rl_crlf, etc.) + +z. The formatted documentation included in the base readline distribution + is no longer removed on a `make distclean'. + +aa. Some changes were made to avoid gcc warnings with -Wall. + +bb. rl_get_keymap_by_name now finds keymaps case-insensitively, so + `set keymap EMACS' works. + +cc. The history file writing and truncation functions now return a useful + status on error. + +dd. Fixed a bug that could cause applications to dereference a NULL pointer + if a NULL second argument was passed to history_expand(). + +ee. If a hook function assigned to rl_event_hook sets rl_done to a non-zero + value, rl_read_key() now immediately returns '\n' (which is assumed to + be bound to accept-line). + +2. New Features in Readline + +a. The blink timeout for paren matching is now settable by applications, + via the rl_set_paren_blink_timeout() function. + +b. _rl_executing_macro has been renamed to rl_executing_macro, which means + it's now part of the public interface. + +c. Readline has a new variable, rl_readline_state, which is a bitmap that + encapsulates the current state of the library; intended for use by + callbacks and hook functions. + +d. rlfe has a new -l option to log input and output (-a appends to logfile), + a new -n option to set the readline application name, and -v and -h + options for version and help information. + +e. rlfe can now perform filename completion for the inferior process if the + OS has a /proc//cwd that can be read with readlink(2) to get the + inferior's current working directory. + +f. A new file, rltypedefs.h, contains the new typedefs for function pointers + and is installed by `make install'. + +g. New application-callable function rl_set_prompt(const char *prompt): + expands its prompt string argument and sets rl_prompt to the result. + +h. New application-callable function rl_set_screen_size(int rows, int cols): + public method for applications to set readline's idea of the screen + dimensions. + +i. The history example program (examples/histexamp.c) is now built as one + of the examples. + +j. The documentation has been updated to cover nearly all of the public + functions and variables declared in readline.h. + +k. New function, rl_get_screen_size (int *rows, int *columns), returns + readline's idea of the screen dimensions. + +l. The timeout in rl_gather_tyi (readline keyboard input polling function) + is now settable via a function (rl_set_keyboard_input_timeout()). + +m. Renamed the max_input_history variable to history_max_entries; the old + variable is maintained for backwards compatibility. + +n. The list of characters that separate words for the history tokenizer is + now settable with a variable: history_word_delimiters. The default + value is as before. + +o. There is a new history.3 manual page documenting the history library. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-4.1, +and the previous version, readline-4.0. + +1. Changes to Readline + +a. Changed the HTML documents so that the table-of-contents is no longer + a separate file. + +b. Changes to the shared object configuration for: Irix 5.x, Irix 6.x, + OSF/1. + +c. The shared library major and minor versions are now constructed + automatically by configure and substituted into the makefiles. + +d. It's now possible to install the shared libraries separately from the + static libraries. + +e. The history library tries to truncate the history file only if it is a + regular file. + +f. A bug that caused _rl_dispatch to address negative array indices on + systems with signed chars was fixed. + +g. rl-yank-nth-arg now leaves the history position the same as when it was + called. + +h. Changes to the completion code to handle MS-DOS drive-letter:pathname + filenames. + +i. Completion is now case-insensitive by default on MS-DOS. + +j. Fixes to the history file manipulation code for MS-DOS. + +k. Readline attempts to bind the arrow keys to appropriate defaults on MS-DOS. + +l. Some fixes were made to the redisplay code for better operation on MS-DOS. + +m. The quoted-insert code will now insert tty special chars like ^C. + +n. A bug was fixed that caused the display code to reference memory before + the start of the prompt string. + +o. More support for __EMX__ (OS/2). + +p. A bug was fixed in readline's signal handling that could cause infinite + recursion in signal handlers. + +q. A bug was fixed that caused the point to be less than zero when rl_forward + was given a very large numeric argument. + +r. The vi-mode code now gets characters via the application-settable value + of rl_getc_function rather than calling rl_getc directly. + +s. The history file code now uses O_BINARY mode when reading and writing + the history file on cygwin32. + +t. Fixed a bug in the redisplay code for lines with more than 256 line + breaks. + +u. A bug was fixed which caused invisible character markers to not be + stripped from the prompt string if the terminal was in no-echo mode. + +v. Readline no longer tries to get the variables it needs for redisplay + from the termcap entry if the calling application has specified its + own redisplay function. Readline treats the terminal as `dumb' in + this case. + +w. Fixes to the SIGWINCH code so that a multiple-line prompt with escape + sequences is redrawn correctly. + +x. Changes to the install and install-shared targets so that the libraries + and header files are installed separately. + +2. New Features in Readline + +a. A new Readline `user manual' is in doc/rluserman.texinfo. + +b. Parentheses matching is now always compiled into readline, and enabled + or disabled when the value of the `blink-matching-paren' variable is + changed. + +c. MS-DOS systems now use ~/_inputrc as the last-ditch inputrc filename. + +d. MS-DOS systems now use ~/_history as the default history file. + +e. history-search-{forward,backward} now leave the point at the end of the + line when the string to search for is empty, like + {reverse,forward}-search-history. + +f. history-search-{forward,backward} now leave the last history line found + in the readline buffer if the second or subsequent search fails. + +g. New function for use by applications: rl_on_new_line_with_prompt, used + when an application displays the prompt itself before calling readline(). + +h. New variable for use by applications: rl_already_prompted. An application + that displays the prompt itself before calling readline() must set this to + a non-zero value. + +i. A new variable, rl_gnu_readline_p, always 1. The intent is that an + application can verify whether or not it is linked with the `real' + readline library or some substitute. + +j. Per Bothner's `rlfe' (pronounced `Ralphie') readline front-end program + is included in the examples subdirectory, though it is not built + by default. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-4.0, +and the previous version, readline-2.2. + +1. Changes to Readline + +a. The version number is now 4.0, to match the major and minor version + numbers on the shared readline and history libraries. Future + releases will maintain the identical numbering. + +b. Fixed a typo in the `make install' recipe that copied libreadline.a + to libhistory.old right after installing it. + +c. The readline and history info files are now installed out of the source + directory if they are not found in the build directory. + +d. The library no longer exports a function named `savestring' -- backwards + compatibility be damned. + +e. There is no longer any #ifdef SHELL code in the source files. + +f. Some changes were made to the key binding code to fix memory leaks and + better support Win32 systems. + +g. Fixed a silly typo in the paren matching code -- it's microseconds, not + milliseconds. + +h. The readline library should be compilable by C++ compilers. + +i. The readline.h public header file now includes function prototypes for + all readline functions, and some changes were made to fix errors in the + source files uncovered by the use of prototypes. + +j. The maximum numeric argument is now clamped at 1000000. + +k. Fixes to rl_yank_last_arg to make it behave better. + +l. Fixed a bug in the display code that caused core dumps if the prompt + string length exceeded 1024 characters. + +m. The menu completion code was fixed to properly insert a single completion + if there is only one match. + +n. A bug was fixed that caused the display code to improperly display tabs + after newlines. + +o. A fix was made to the completion code in which a typo caused the wrong + value to be passed to the function that computed the longest common + prefix of the list of matches. + +p. The completion code now checks the value of rl_filename_completion_desired, + which is set by application-supplied completion functions to indicate + that filename completion is being performed, to decide whether or not to + call an application-supplied `ignore completions' function. + +q. Code was added to the history library to catch history substitutions + using `&' without a previous history substitution or search having been + performed. + + +2. New Features in Readline + +a. There is a new script, support/shobj-conf, to do system-specific shared + object and library configuration. It generates variables for configure + to substitute into makefiles. The README file provides a detailed + explanation of the shared library creation process. + +b. Shared libraries and objects are now built in the `shlib' subdirectory. + There is a shlib/Makefile.in to control the build process. `make shared' + from the top-level directory is still the right way to build shared + versions of the libraries. + +c. rlconf.h is now installed, so applications can find out which features + have been compiled into the installed readline and history libraries. + +d. rlstdc.h is now an installed header file. + +e. Many changes to the signal handling: + o Readline now catches SIGQUIT and cleans up the tty before returning; + o A new variable, rl_catch_signals, is available to application writers + to indicate to readline whether or not it should install its own + signal handlers for SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, + SIGTTIN, and SIGTTOU; + o A new variable, rl_catch_sigwinch, is available to application + writers to indicate to readline whether or not it should install its + own signal handler for SIGWINCH, which will chain to the calling + applications's SIGWINCH handler, if one is installed; + o There is a new function, rl_free_line_state, for application signal + handlers to call to free up the state associated with the current + line after receiving a signal; + o There is a new function, rl_cleanup_after_signal, to clean up the + display and terminal state after receiving a signal; + o There is a new function, rl_reset_after_signal, to reinitialize the + terminal and display state after an application signal handler + returns and readline continues + +f. There is a new function, rl_resize_terminal, to reset readline's idea of + the screen size after a SIGWINCH. + +g. New public functions: rl_save_prompt and rl_restore_prompt. These were + previously private functions with a `_' prefix. These functions are + used when an application wants to write a message to the `message area' + with rl_message and have the prompt restored correctly when the message + is erased. + +h. New function hook: rl_pre_input_hook, called just before readline starts + reading input, after initialization. + +i. New function hook: rl_display_matches_hook, called when readline would + display the list of completion matches. The new function + rl_display_match_list is what readline uses internally, and is available + for use by application functions called via this hook. + +j. New bindable function, delete-char-or-list, like tcsh. + +k. A new variable, rl_erase_empty_line, which, if set by an application using + readline, will cause readline to erase, prompt and all, lines on which the + only thing typed was a newline. + +l. There is a new script, support/shlib-install, to install and uninstall + the shared readline and history libraries. + +m. A new bindable variable, `isearch-terminators', which is a string + containing the set of characters that should terminate an incremental + search without being executed as a command. + +n. A new bindable function, forward-backward-delete-char. + +------------------------------------------------------------------------------- +This document details the changes between this version, readline-2.2, +and the previous version, readline-2.1. + +1. Changes to Readline + +a. Added a missing `extern' to a declaration in readline.h that kept + readline from compiling cleanly on some systems. + +b. The history file is now opened with mode 0600 when it is written for + better security. + +c. Changes were made to the SIGWINCH handling code so that prompt redisplay + is done better. + +d. ^G now interrupts incremental searches correctly. + +e. A bug that caused a core dump when the set of characters to be quoted + when completing words was empty was fixed. + +f. Fixed a problem in the readline test program rltest.c that caused a core + dump. + +g. The code that handles parser directives in inputrc files now displays + more error messages. + +h. The history expansion code was fixed so that the appearance of the + history comment character at the beginning of a word inhibits history + expansion for that word and the rest of the input line. + +i. The code that prints completion listings now behaves better if one or + more of the filenames contains non-printable characters. + +j. The time delay when showing matching parentheses is now 0.5 seconds. + + +2. New Features in Readline + +a. There is now an option for `iterative' yank-last-arg handline, so a user + can keep entering `M-.', yanking the last argument of successive history + lines. + +b. New variable, `print-completions-horizontally', which causes completion + matches to be displayed across the screen (like `ls -x') rather than up + and down the screen (like `ls'). + +c. New variable, `completion-ignore-case', which causes filename completion + and matching to be performed case-insensitively. + +d. There is a new bindable command, `magic-space', which causes history + expansion to be performed on the current readline buffer and a space to + be inserted into the result. + +e. There is a new bindable command, `menu-complete', which enables tcsh-like + menu completion (successive executions of menu-complete insert a single + completion match, cycling through the list of possible completions). + +f. There is a new bindable command, `paste-from-clipboard', for use on Win32 + systems, to insert the text from the Win32 clipboard into the editing + buffer. + +g. The key sequence translation code now understands printf-style backslash + escape sequences, including \NNN octal escapes. These escape sequences + may be used in key sequence definitions or macro values. + +h. An `$include' inputrc file parser directive has been added. diff --git a/readline-4.3/COPYING b/readline-4.3/COPYING new file mode 100644 index 0000000..1bf1526 --- /dev/null +++ b/readline-4.3/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/readline-4.3/INSTALL b/readline-4.3/INSTALL new file mode 100644 index 0000000..adb27a9 --- /dev/null +++ b/readline-4.3/INSTALL @@ -0,0 +1,273 @@ +Basic Installation +================== + +These are installation instructions for Readline-4.3. + +The simplest way to compile readline is: + + 1. `cd' to the directory containing the readline source code and type + `./configure' to configure readline for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes some time. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile readline and build the static readline + and history libraries. If supported, the shared readline and history + libraries will be built also. See below for instructions on compiling + the other parts of the distribution. Typing `make everything' will + cause the static and shared libraries (if supported) and the example + programs to be built. + + 3. Type `make install' to install the static readline and history + libraries, the readline include files, the documentation, and, if + supported, the shared readline and history libraries. + + 4. You can remove the created libraries and object files from the + build directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile readline for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the readline developers, and should be used with care. + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It +uses those values to create a `Makefile' in the build directory, +and Makefiles in the `doc', `shlib', and `examples' +subdirectories. It also creates a `config.h' file containing +system-dependent definitions. Finally, it creates a shell script +`config.status' that you can run in the future to recreate the +current configuration, a file `config.cache' that saves the +results of its tests to speed up reconfiguring, and a file +`config.log' containing compiler output (useful mainly for +debugging `configure'). + +If you need to do unusual things to compile readline, please try +to figure out how `configure' could check whether to do them, and +mail diffs or instructions to so they can +be considered for the next release. If at some point +`config.cache' contains results you don't want to keep, you may +remove or edit it. + +The file `configure.in' is used to create `configure' by a +program called `autoconf'. You only need `configure.in' if you +want to change it or regenerate `configure' using a newer version +of `autoconf'. The readline `configure.in' requires autoconf +version 2.50 or newer. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + +You can compile readline for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + +If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile readline for one architecture at a +time in the source code directory. After you have installed +readline for one architecture, use `make distclean' before +reconfiguring for another architecture. + +Installation Names +================== + +By default, `make install' will install the readline libraries in +`/usr/local/lib', the include files in +`/usr/local/include/readline', the man pages in `/usr/local/man', +and the info files in `/usr/local/info'. You can specify an +installation prefix other than `/usr/local' by giving `configure' +the option `--prefix=PATH' or by supplying a value for the +DESTDIR variable when running `make install'. + +You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. +If you give `configure' the option `--exec-prefix=PATH', the +readline Makefiles will use PATH as the prefix for installing the +libraries. Documentation and other data files will still use the +regular prefix. + +Specifying the System Type +========================== + +There may be some features `configure' can not figure out +automatically, but need to determine by the type of host readline +will run on. Usually `configure' can figure that out, but if it +prints a message saying it can not guess the host type, give it +the `--host=TYPE' option. TYPE can either be a short name for +the system type, such as `sun4', or a canonical name with three +fields: CPU-COMPANY-SYSTEM (e.g., i386-unknown-freebsd4.2). + +See the file `config.sub' for the possible values of each field. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: the readline `configure' looks for a site script, but not +all `configure' scripts do. + +Operation Controls +================== + +`configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + +Optional Features +================= + +The readline `configure' recognizes a single `--with-PACKAGE' option: + +`--with-curses' + This tells readline that it can find the termcap library functions + (tgetent, et al.) in the curses library, rather than a separate + termcap library. Readline uses the termcap functions, but does not + link with the termcap or curses library itself, allowing applications + which link with readline the to choose an appropriate library. + This option tells readline to link the example programs with the + curses library rather than libtermcap. + +`configure' also recognizes two `--enable-FEATURE' options: + +`--enable-shared' + Build the shared libraries by default on supported platforms. The + default is `yes'. + +`--enable-static' + Build the static libraries by default. The default is `yes'. + +Shared Libraries +================ + +There is support for building shared versions of the readline and +history libraries. The configure script creates a Makefile in +the `shlib' subdirectory, and typing `make shared' will cause +shared versions of the readline and history libraries to be built +on supported platforms. + +If `configure' is given the `--enable-shared' option, it will attempt +to build the shared libraries by default on supported platforms. + +Configure calls the script support/shobj-conf to test whether or +not shared library creation is supported and to generate the values +of variables that are substituted into shlib/Makefile. If you +try to build shared libraries on an unsupported platform, `make' +will display a message asking you to update support/shobj-conf for +your platform. + +If you need to update support/shobj-conf, you will need to create +a `stanza' for your operating system and compiler. The script uses +the value of host_os and ${CC} as determined by configure. For +instance, FreeBSD 4.2 with any version of gcc is identified as +`freebsd4.2-gcc*'. + +In the stanza for your operating system-compiler pair, you will need to +define several variables. They are: + +SHOBJ_CC The C compiler used to compile source files into shareable + object files. This is normally set to the value of ${CC} + by configure, and should not need to be changed. + +SHOBJ_CFLAGS Flags to pass to the C compiler ($SHOBJ_CC) to create + position-independent code. If you are using gcc, this + should probably be set to `-fpic'. + +SHOBJ_LD The link editor to be used to create the shared library from + the object files created by $SHOBJ_CC. If you are using + gcc, a value of `gcc' will probably work. + +SHOBJ_LDFLAGS Flags to pass to SHOBJ_LD to enable shared object creation. + If you are using gcc, `-shared' may be all that is necessary. + These should be the flags needed for generic shared object + creation. + +SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library + creation. Many systems use the -R option to the link + editor to embed a path within the library for run-time + library searches. A reasonable value for such systems would + be `-R$(libdir)'. + +SHLIB_LIBS Any additional libraries that shared libraries should be + linked against when they are created. + +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'. + +SHLIB_LIBVERSION The string to append to the filename to indicate the version + of the shared library. It should begin with $(SHLIB_LIBSUFF), + and possibly include version information that allows the + run-time loader to load the version of the shared library + appropriate for a particular program. Systems using shared + libraries similar to SunOS 4.x use major and minor library + version numbers; for those systems a value of + `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' is appropriate. + Systems based on System V Release 4 don't use minor version + numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems. + Other Unix versions use different schemes. + +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 + shared libraries are not supported, this will be set to + `unsupported'. + +You should look at the existing stanzas in support/shobj-conf for ideas. + +Once you have updated support/shobj-conf, re-run configure and type +`make shared' or `make'. The shared libraries will be created in the +shlib subdirectory. + +If shared libraries are created, `make install' will install them. +You may install only the shared libraries by running `make +install-shared' from the top-level build directory. Running `make +install' in the shlib subdirectory will also work. If you don't want +to install any created shared libraries, run `make install-static'. diff --git a/readline-4.3/MANIFEST b/readline-4.3/MANIFEST new file mode 100644 index 0000000..1507eda --- /dev/null +++ b/readline-4.3/MANIFEST @@ -0,0 +1,126 @@ +# +# Master distribution manifest for the standalone readline distribution +# +doc d +examples d +support d +shlib d +COPYING f +README f +MANIFEST f +INSTALL f +CHANGELOG f +CHANGES f +USAGE f +aclocal.m4 f +config.h.in f +configure f +configure.in f +Makefile.in f +ansi_stdlib.h f +chardefs.h f +history.h f +histlib.h f +keymaps.h f +posixdir.h f +posixjmp.h f +posixstat.h f +readline.h f +rlconf.h f +rldefs.h f +rlmbutil.h f +rlprivate.h f +rlshell.h f +rlstdc.h f +rltty.h f +rltypedefs.h f +rlwinsize.h f +tcap.h f +tilde.h f +xmalloc.h f +bind.c f +callback.c f +compat.c f +complete.c f +display.c f +emacs_keymap.c f +funmap.c f +input.c f +isearch.c f +keymaps.c f +kill.c f +macro.c f +mbutil.c f +misc.c f +nls.c f +parens.c f +readline.c f +rltty.c f +savestring.c f +search.c f +shell.c f +signals.c f +terminal.c f +text.c f +tilde.c f +undo.c f +util.c f +vi_keymap.c f +vi_mode.c f +xmalloc.c f +history.c f +histexpand.c f +histfile.c f +histsearch.c f +shlib/Makefile.in f +support/config.guess f +support/config.sub f +support/install.sh f +support/mkdirs f +support/mkdist 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/readline.3 f +doc/history.3 f +doc/texi2dvi f +doc/texi2html f +examples/Makefile.in f +examples/excallback.c f +examples/fileman.c f +examples/manexamp.c f +examples/readlinebuf.h f +examples/rlcat.c f +examples/rlfe.c f +examples/rltest.c f +examples/rl.c f +examples/rlversion.c f +examples/histexamp.c f +examples/Inputrc f +# formatted documentation, from MANIFEST.doc +doc/readline.ps f +doc/history.ps f +doc/rluserman.ps f +doc/readline.dvi f +doc/history.dvi f +doc/rluserman.dvi f +doc/readline.info f +doc/history.info f +doc/rluserman.info f +doc/readline.html f +doc/history.html f +doc/rluserman.html f +doc/readline.0 f +doc/history.0 f +doc/readline_3.ps f +doc/history_3.ps f diff --git a/readline-4.3/Makefile.in b/readline-4.3/Makefile.in new file mode 100644 index 0000000..0ff0c31 --- /dev/null +++ b/readline-4.3/Makefile.in @@ -0,0 +1,520 @@ +## -*- text -*- ## +# Master Makefile for the GNU readline library. +# Copyright (C) 1994 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 USA. +RL_LIBRARY_VERSION = @LIBVERSION@ +RL_LIBRARY_NAME = readline + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +top_srcdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv + +@SET_MAKE@ +SHELL = @MAKE_SHELL@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +libdir = @libdir@ +mandir = @mandir@ +includedir = @includedir@ + +infodir = @infodir@ + +man3dir = $(mandir)/man3 + +# Support an alternate destination root directory for package building +DESTDIR = + +# Programs to make tags files. +ETAGS = etags -tw +CTAGS = ctags -tw + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' +CPPFLAGS = @CPPFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +TERMCAP_LIB = @TERMCAP_LIB@ + +# For libraries which include headers from other libraries. +INCLUDES = -I. -I$(srcdir) + +XCCFLAGS = $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) $(INCLUDES) +CCFLAGS = $(XCCFLAGS) $(LOCAL_CFLAGS) $(CFLAGS) + +# could add -Werror here +GCC_LINT_FLAGS = -ansi -Wall -Wshadow -Wpointer-arith -Wcast-qual \ + -Wwrite-strings -Wstrict-prototypes \ + -Wmissing-prototypes -Wno-implicit -pedantic +GCC_LINT_CFLAGS = $(XCCFLAGS) $(GCC_LINT_FLAGS) @CFLAGS@ @LOCAL_CFLAGS@ + +.c.o: + ${RM} $@ + $(CC) -c $(CCFLAGS) $< + +# The name of the main library target. +LIBRARY_NAME = libreadline.a +STATIC_LIBS = libreadline.a libhistory.a + +# The C code source files for this library. +CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \ + $(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \ + $(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \ + $(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \ + $(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \ + $(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \ + $(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c \ + $(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \ + $(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \ + $(srcdir)/shell.c $(srcdir)/savestring.c $(srcdir)/tilde.c \ + $(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \ + $(srcdir)/mbutil.c + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \ + ansi_stdlib.h tcap.h rlstdc.h xmalloc.h rlprivate.h rlshell.h \ + rltypedefs.h rlmbutil.h + +HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o mbutil.o +TILDEOBJ = tilde.o +OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ + rltty.o complete.o bind.o isearch.o display.o signals.o \ + util.o kill.o undo.o macro.o input.o callback.o terminal.o \ + text.o nls.o misc.o compat.o xmalloc.o $(HISTOBJ) $(TILDEOBJ) + +# The texinfo files which document this library. +DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo +DOCOBJECT = doc/readline.dvi +DOCSUPPORT = doc/Makefile +DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT) + +CREATED_MAKEFILES = Makefile doc/Makefile examples/Makefile shlib/Makefile +CREATED_CONFIGURE = config.status config.h config.cache config.log \ + stamp-config stamp-h +CREATED_TAGS = TAGS tags + +INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h \ + rlstdc.h rlconf.h rltypedefs.h + +########################################################################## +TARGETS = @STATIC_TARGET@ @SHARED_TARGET@ +INSTALL_TARGETS = @STATIC_INSTALL_TARGET@ @SHARED_INSTALL_TARGET@ + +all: $(TARGETS) + +everything: all examples + +static: $(STATIC_LIBS) + +libreadline.a: $(OBJECTS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(OBJECTS) + -test -n "$(RANLIB)" && $(RANLIB) $@ + +libhistory.a: $(HISTOBJ) xmalloc.o + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o + -test -n "$(RANLIB)" && $(RANLIB) $@ + +# Since tilde.c is shared between readline and bash, make sure we compile +# it with the right flags when it's built as part of readline +tilde.o: tilde.c + rm -f $@ + $(CC) $(CCFLAGS) -DREADLINE_LIBRARY -c $(srcdir)/tilde.c + +readline: $(OBJECTS) readline.h rldefs.h chardefs.h ./libreadline.a + $(CC) $(CCFLAGS) -o $@ ./examples/rl.c ./libreadline.a ${TERMCAP_LIB} + +lint: force + $(MAKE) $(MFLAGS) CCFLAGS='$(GCC_LINT_CFLAGS)' static + +Makefile makefile: config.status $(srcdir)/Makefile.in + CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status + +Makefiles makefiles: config.status $(srcdir)/Makefile.in + @for mf in $(CREATED_MAKEFILES); do \ + CONFIG_FILES=$$mf CONFIG_HEADERS= $(SHELL) ./config.status ; \ + done + +config.status: configure + $(SHELL) ./config.status --recheck + +config.h: stamp-h + +stamp-h: config.status $(srcdir)/config.h.in + CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status + echo > $@ + +#$(srcdir)/configure: $(srcdir)/configure.in ## Comment-me-out in distribution +# cd $(srcdir) && autoconf ## Comment-me-out in distribution + + +shared: force + -test -d shlib || mkdir shlib + -( cd shlib ; ${MAKE} ${MFLAGS} all ) + +documentation: force + -test -d doc || mkdir doc + -( cd doc && $(MAKE) $(MFLAGS) ) + +examples: force + -test -d examples || mkdir examples + -(cd examples && ${MAKE} ${MFLAGS} all ) + +force: + +install-headers: installdirs ${INSTALLED_HEADERS} + for f in ${INSTALLED_HEADERS}; do \ + $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(includedir)/readline ; \ + done + +uninstall-headers: + -test -n "$(includedir)" && cd $(DESTDIR)$(includedir)/readline && \ + ${RM} ${INSTALLED_HEADERS} + +maybe-uninstall-headers: uninstall-headers + +install: $(INSTALL_TARGETS) + +install-static: installdirs $(STATIC_LIBS) install-headers + -$(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) \ + $(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \ + $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) + +uninstall: uninstall-headers + -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 + -( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install ) + +uninstall-shared: maybe-uninstall-headers + -( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall ) + +TAGS: force + $(ETAGS) $(CSOURCES) $(HSOURCES) + +tags: force + $(CTAGS) $(CSOURCES) $(HSOURCES) + +clean: force + $(RM) $(OBJECTS) $(STATIC_LIBS) + $(RM) readline readline.exe + -( cd shlib && $(MAKE) $(MFLAGS) $@ ) + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + -( cd examples && $(MAKE) $(MFLAGS) $@ ) + +mostlyclean: clean + -( cd shlib && $(MAKE) $(MFLAGS) $@ ) + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + -( cd examples && $(MAKE) $(MFLAGS) $@ ) + +distclean maintainer-clean: clean + -( cd shlib && $(MAKE) $(MFLAGS) $@ ) + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + -( cd examples && $(MAKE) $(MFLAGS) $@ ) + $(RM) Makefile + $(RM) $(CREATED_CONFIGURE) + $(RM) $(CREATED_TAGS) + +info dvi: + -( cd doc && $(MAKE) $(MFLAGS) $@ ) + +install-info: +check: +installcheck: + +dist: force + @echo Readline distributions are created using $(srcdir)/support/mkdist. + @echo Here is a sample of the necessary commands: + @echo bash $(srcdir)/support/mkdist -m $(srcdir)/MANIFEST -s $(srcdir) -r $(RL_LIBRARY_NAME) $(RL_LIBRARY_VERSION) + @echo tar cf $(RL_LIBRARY_NAME)-${RL_LIBRARY_VERSION}.tar ${RL_LIBRARY_NAME}-$(RL_LIBRARY_VERSION) + @echo gzip $(RL_LIBRARY_NAME)-$(RL_LIBRARY_VERSION).tar + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Dependencies +bind.o: ansi_stdlib.h posixstat.h +bind.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +bind.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +bind.o: history.h +callback.o: rlconf.h +callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +compat.o: rlstdc.h +complete.o: ansi_stdlib.h posixdir.h posixstat.h +complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +display.o: ansi_stdlib.h posixstat.h +display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +display.o: tcap.h +display.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +display.o: history.h rlstdc.h +funmap.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +funmap.o: rlconf.h ansi_stdlib.h rlstdc.h +funmap.o: ${BUILD_DIR}/config.h +histexpand.o: ansi_stdlib.h +histexpand.o: history.h histlib.h rlstdc.h rltypedefs.h +histexpand.o: ${BUILD_DIR}/config.h +histfile.o: ansi_stdlib.h +histfile.o: history.h histlib.h rlstdc.h rltypedefs.h +histfile.o: ${BUILD_DIR}/config.h +history.o: ansi_stdlib.h +history.o: history.h histlib.h rlstdc.h rltypedefs.h +history.o: ${BUILD_DIR}/config.h +histsearch.o: ansi_stdlib.h +histsearch.o: history.h histlib.h rlstdc.h rltypedefs.h +histsearch.o: ${BUILD_DIR}/config.h +input.o: ansi_stdlib.h +input.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +input.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +isearch.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +isearch.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +isearch.o: ansi_stdlib.h history.h rlstdc.h +keymaps.o: emacs_keymap.c vi_keymap.c +keymaps.o: keymaps.h rltypedefs.h chardefs.h rlconf.h ansi_stdlib.h +keymaps.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +keymaps.o: ${BUILD_DIR}/config.h rlstdc.h +kill.o: ansi_stdlib.h +kill.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +kill.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +kill.o: history.h rlstdc.h +macro.o: ansi_stdlib.h +macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +macro.o: history.h rlstdc.h +mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h +misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +misc.o: history.h rlstdc.h ansi_stdlib.h +nls.o: ansi_stdlib.h +nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +nls.o: history.h rlstdc.h +parens.o: rlconf.h +parens.o: ${BUILD_DIR}/config.h +parens.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +readline.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +readline.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +readline.o: history.h rlstdc.h +readline.o: posixstat.h ansi_stdlib.h posixjmp.h +rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +rltty.o: rltty.h +rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +search.o: ansi_stdlib.h history.h rlstdc.h +shell.o: ${BUILD_DIR}/config.h +shell.o: ansi_stdlib.h +signals.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +signals.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +signals.o: history.h rlstdc.h +terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +terminal.o: tcap.h +terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +terminal.o: history.h rlstdc.h +text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +text.o: history.h rlstdc.h ansi_stdlib.h +tilde.o: ansi_stdlib.h +tilde.o: ${BUILD_DIR}/config.h +tilde.o: tilde.h +undo.o: ansi_stdlib.h +undo.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +undo.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +undo.o: history.h rlstdc.h +util.o: posixjmp.h ansi_stdlib.h +util.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +util.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h +vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h +vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h +vi_mode.o: history.h ansi_stdlib.h rlstdc.h +xmalloc.o: ${BUILD_DIR}/config.h +xmalloc.o: ansi_stdlib.h + +bind.o: rlshell.h +histfile.o: rlshell.h +nls.o: rlshell.h +readline.o: rlshell.h +shell.o: rlshell.h +terminal.o: rlshell.h +histexpand.o: rlshell.h + +bind.o: rlprivate.h +callback.o: rlprivate.h +complete.o: rlprivate.h +display.o: rlprivate.h +input.o: rlprivate.h +isearch.o: rlprivate.h +kill.o: rlprivate.h +macro.o: rlprivate.h +mbutil.o: rlprivate.h +misc.o: rlprivate.h +nls.o: rlprivate.h +parens.o: rlprivate.h +readline.o: rlprivate.h +rltty.o: rlprivate.h +search.o: rlprivate.h +signals.o: rlprivate.h +terminal.o: rlprivate.h +text.o: rlprivate.h +undo.o: rlprivate.h +util.o: rlprivate.h +vi_mode.o: rlprivate.h + +bind.o: xmalloc.h +complete.o: xmalloc.h +display.o: xmalloc.h +funmap.o: xmalloc.h +histexpand.o: xmalloc.h +histfile.o: xmalloc.h +history.o: xmalloc.h +input.o: xmalloc.h +isearch.o: xmalloc.h +keymaps.o: xmalloc.h +kill.o: xmalloc.h +macro.o: xmalloc.h +mbutil.o: xmalloc.h +misc.o: xmalloc.h +readline.o: xmalloc.h +savestring.o: xmalloc.h +search.o: xmalloc.h +shell.o: xmalloc.h +terminal.o: xmalloc.h +text.o: xmalloc.h +tilde.o: xmalloc.h +undo.o: xmalloc.h +util.o: xmalloc.h +vi_mode.o: xmalloc.h +xmalloc.o: xmalloc.h + +complete.o: rlmbutil.h +display.o: rlmbutil.h +histexpand.o: rlmbutil.h +input.o: rlmbutil.h +isearch.o: rlmbutil.h +mbutil.o: rlmbutil.h +misc.o: rlmbutil.h +readline.o: rlmbutil.h +search.o: rlmbutil.h +text.o: rlmbutil.h +vi_mode.o: rlmbutil.h + +bind.o: $(srcdir)/bind.c +callback.o: $(srcdir)/callback.c +compat.o: $(srcdir)/compat.c +complete.o: $(srcdir)/complete.c +display.o: $(srcdir)/display.c +funmap.o: $(srcdir)/funmap.c +input.o: $(srcdir)/input.c +isearch.o: $(srcdir)/isearch.c +keymaps.o: $(srcdir)/keymaps.c $(srcdir)/emacs_keymap.c $(srcdir)/vi_keymap.c +kill.o: $(srcdir)/kill.c +macro.o: $(srcdir)/macro.c +mbutil.o: $(srcdir)/mbutil.c +misc.o: $(srcdir)/misc.c +nls.o: $(srcdir)/nls.c +parens.o: $(srcdir)/parens.c +readline.o: $(srcdir)/readline.c +rltty.o: $(srcdir)/rltty.c +savestring.o: $(srcdir)/savestring.c +search.o: $(srcdir)/search.c +shell.o: $(srcdir)/shell.c +signals.o: $(srcdir)/signals.c +terminal.o: $(srcdir)/terminal.c +text.o: $(srcdir)/text.c +tilde.o: $(srcdir)/tilde.c +undo.o: $(srcdir)/undo.c +util.o: $(srcdir)/util.c +vi_mode.o: $(srcdir)/vi_mode.c +xmalloc.o: $(srcdir)/xmalloc.c + +histexpand.o: $(srcdir)/histexpand.c +histfile.o: $(srcdir)/histfile.c +history.o: $(srcdir)/history.c +histsearch.o: $(srcdir)/histsearch.c + +bind.o: bind.c +callback.o: callback.c +compat.o: compat.c +complete.o: complete.c +display.o: display.c +funmap.o: funmap.c +input.o: input.c +isearch.o: isearch.c +keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c +kill.o: kill.c +macro.o: macro.c +mbutil.o: mbutil.c +misc.o: misc.c +nls.o: nls.c +parens.o: parens.c +readline.o: readline.c +rltty.o: rltty.c +savestring.o: savestring.c +search.o: search.c +shell.o: shell.c +signals.o: signals.c +terminal.o: terminal.c +text.o: text.c +tilde.o: tilde.c +undo.o: undo.c +util.o: util.c +vi_mode.o: vi_mode.c +xmalloc.o: xmalloc.c + +histexpand.o: histexpand.c +histfile.o: histfile.c +history.o: history.c +histsearch.o: histsearch.c diff --git a/readline-4.3/README b/readline-4.3/README new file mode 100644 index 0000000..7aa9394 --- /dev/null +++ b/readline-4.3/README @@ -0,0 +1,172 @@ +Introduction +============ + +This is the Gnu Readline library, version 4.3. + +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 +Emacs and vi editing modes are available. The Readline library includes +additional functions to maintain a list of previously-entered command +lines, to recall and perhaps reedit those lines, and perform csh-like +history expansion on previous commands. + +The history facilites are also placed into a separate library, the +History library, as part of the build process. The History library +may be used without Readline in applications which desire its +capabilities. + +The Readline library is free software, distributed under the terms of +the [GNU] General Public License, version 2. For more information, see +the file COPYING. + +To build the library, try typing `./configure', then `make'. The +configuration process is automated, so no further intervention should +be necessary. Readline builds with `gcc' by default if it is +available. If you want to use `cc' instead, type + + CC=cc ./configure + +if you are using a Bourne-style shell. If you are not, the following +may work: + + env CC=cc ./configure + +Read the file INSTALL in this directory for more information about how +to customize and control the build process. + +The file rlconf.h contains C preprocessor defines that enable and disable +certain Readline features. + +The special make target `everything' will build the static and shared +libraries (if the target platform supports them) and the examples. + +Examples +======== + +There are several example programs that use Readline features in the +examples directory. The `rl' program is of particular interest. It +is a command-line interface to Readline, suitable for use in shell +scripts in place of `read'. + +Shared Libraries +================ + +There is skeletal support for building shared versions of the +Readline and History libraries. The configure script creates +a Makefile in the `shlib' subdirectory, and typing `make shared' +will cause shared versions of the Readline and History libraries +to be built on supported platforms. + +If `configure' is given the `--enable-shared' option, it will attempt +to build the shared libraries by default on supported platforms. + +Configure calls the script support/shobj-conf to test whether or +not shared library creation is supported and to generate the values +of variables that are substituted into shlib/Makefile. If you +try to build shared libraries on an unsupported platform, `make' +will display a message asking you to update support/shobj-conf for +your platform. + +If you need to update support/shobj-conf, you will need to create +a `stanza' for your operating system and compiler. The script uses +the value of host_os and ${CC} as determined by configure. For +instance, FreeBSD 4.2 with any version of gcc is identified as +`freebsd4.2-gcc*'. + +In the stanza for your operating system-compiler pair, you will need to +define several variables. They are: + +SHOBJ_CC The C compiler used to compile source files into shareable + object files. This is normally set to the value of ${CC} + by configure, and should not need to be changed. + +SHOBJ_CFLAGS Flags to pass to the C compiler ($SHOBJ_CC) to create + position-independent code. If you are using gcc, this + should probably be set to `-fpic'. + +SHOBJ_LD The link editor to be used to create the shared library from + the object files created by $SHOBJ_CC. If you are using + gcc, a value of `gcc' will probably work. + +SHOBJ_LDFLAGS Flags to pass to SHOBJ_LD to enable shared object creation. + If you are using gcc, `-shared' may be all that is necessary. + These should be the flags needed for generic shared object + creation. + +SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library + creation. Many systems use the -R option to the link + editor to embed a path within the library for run-time + library searches. A reasonable value for such systems would + be `-R$(libdir)'. + +SHLIB_LIBS Any additional libraries that shared libraries should be + linked against when they are created. + +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'. + +SHLIB_LIBVERSION The string to append to the filename to indicate the version + of the shared library. It should begin with $(SHLIB_LIBSUFF), + and possibly include version information that allows the + run-time loader to load the version of the shared library + appropriate for a particular program. Systems using shared + libraries similar to SunOS 4.x use major and minor library + version numbers; for those systems a value of + `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' is appropriate. + Systems based on System V Release 4 don't use minor version + numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems. + Other Unix versions use different schemes. + +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. + +You should look at the existing stanzas in support/shobj-conf for ideas. + +Once you have updated support/shobj-conf, re-run configure and type +`make shared'. The shared libraries will be created in the shlib +subdirectory. + +If shared libraries are created, `make install' will install them. +You may install only the shared libraries by running `make +install-shared' from the top-level build directory. Running `make +install' in the shlib subdirectory will also work. If you don't want +to install any created shared libraries, run `make install-static'. + +Documentation +============= + +The documentation for the Readline and History libraries appears in +the `doc' subdirectory. There are three texinfo files and a +Unix-style manual page describing the facilities available in the +Readline library. The texinfo files include both user and +programmer's manuals. HTML versions of the manuals appear in the +`doc' subdirectory as well. + +Reporting Bugs +============== + +Bug reports for Readline should be sent to: + + bug-readline@gnu.org + +When reporting a bug, please include the following information: + + * the version number and release status of Readline (e.g., 4.2-release) + * the machine and OS that it is running on + * a list of the compilation flags or the contents of `config.h', if + appropriate + * a description of the bug + * a recipe for recreating the bug reliably + * a fix for the bug if you have one! + +If you would like to contact the Readline maintainer directly, send mail +to bash-maintainers@gnu.org. + +Since Readline is developed along with bash, the bug-bash@gnu.org mailing +list (mirrored to the Usenet newsgroup gnu.bash.bug) often contains +Readline bug reports and fixes. + +Chet Ramey +chet@po.cwru.edu diff --git a/readline-4.3/USAGE b/readline-4.3/USAGE new file mode 100644 index 0000000..edc9f54 --- /dev/null +++ b/readline-4.3/USAGE @@ -0,0 +1,37 @@ +From rms@gnu.org Thu Jul 22 20:37:55 1999 +Flags: 10 +Return-Path: rms@gnu.org +Received: from arthur.INS.CWRU.Edu (root@arthur.INS.CWRU.Edu [129.22.8.215]) by odin.INS.CWRU.Edu with ESMTP (8.8.6+cwru/CWRU-2.4-ins) + id UAA25349; Thu, 22 Jul 1999 20:37:54 -0400 (EDT) (from rms@gnu.org for ) +Received: from nike.ins.cwru.edu (root@nike.INS.CWRU.Edu [129.22.8.219]) by arthur.INS.CWRU.Edu with ESMTP (8.8.8+cwru/CWRU-3.6) + id UAA05311; Thu, 22 Jul 1999 20:37:51 -0400 (EDT) (from rms@gnu.org for ) +Received: from pele.santafe.edu (pele.santafe.edu [192.12.12.119]) by nike.ins.cwru.edu with ESMTP (8.8.7/CWRU-2.5-bsdi) + id UAA13350; Thu, 22 Jul 1999 20:37:50 -0400 (EDT) (from rms@gnu.org for ) +Received: from wijiji.santafe.edu (wijiji [192.12.12.5]) + by pele.santafe.edu (8.9.1/8.9.1) with ESMTP id SAA10831 + for ; Thu, 22 Jul 1999 18:37:47 -0600 (MDT) +Received: (from rms@localhost) + by wijiji.santafe.edu (8.9.1b+Sun/8.9.1) id SAA01089; + Thu, 22 Jul 1999 18:37:46 -0600 (MDT) +Date: Thu, 22 Jul 1999 18:37:46 -0600 (MDT) +Message-Id: <199907230037.SAA01089@wijiji.santafe.edu> +X-Authentication-Warning: wijiji.santafe.edu: rms set sender to rms@gnu.org using -f +From: Richard Stallman +To: chet@nike.ins.cwru.edu +Subject: Use of Readline +Reply-to: rms@gnu.org + +I think Allbery's suggestion is a good one. So please add this text +in a suitable place. Please don't put it in the GPL itself; that +should be the same as the GPL everywhere else. Putting it in the +README and/or the documentation would be a good idea. + + +====================================================================== +Our position on the use of Readline through a shared-library linking +mechanism is that there is no legal difference between shared-library +linking and static linking--either kind of linking combines various +modules into a single larger work. The conditions for using Readline +in a larger work are stated in section 3 of the GNU GPL. + + diff --git a/readline-4.3/aclocal.m4 b/readline-4.3/aclocal.m4 new file mode 100644 index 0000000..d1ad025 --- /dev/null +++ b/readline-4.3/aclocal.m4 @@ -0,0 +1,1792 @@ +dnl +dnl Bash specific tests +dnl +dnl Some derived from PDKSH 5.1.3 autoconf tests +dnl + +AC_DEFUN(BASH_C_LONG_LONG, +[AC_CACHE_CHECK(for long long, ac_cv_c_long_long, +[if test "$GCC" = yes; then + ac_cv_c_long_long=yes +else +AC_TRY_RUN([ +int +main() +{ +long long foo = 0; +exit(sizeof(long long) < sizeof(long)); +} +], ac_cv_c_long_long=yes, ac_cv_c_long_long=no) +fi]) +if test $ac_cv_c_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [Define if the `long long' type works.]) +fi +]) + +dnl +dnl This is very similar to AC_C_LONG_DOUBLE, with the fix for IRIX +dnl (< changed to <=) added. +dnl +AC_DEFUN(BASH_C_LONG_DOUBLE, +[AC_CACHE_CHECK(for long double, ac_cv_c_long_double, +[if test "$GCC" = yes; then + ac_cv_c_long_double=yes +else +AC_TRY_RUN([ +int +main() +{ + /* The Stardent Vistra knows sizeof(long double), but does not + support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + /* On IRIX 5.3, the compiler converts long double to double with a warning, + but compiles this successfully. */ + exit(sizeof(long double) <= sizeof(double)); +} +], ac_cv_c_long_double=yes, ac_cv_c_long_double=no) +fi]) +if test $ac_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if the `long double' type works.]) +fi +]) + +dnl +dnl Check for . This is separated out so that it can be +dnl AC_REQUIREd. +dnl +dnl BASH_HEADER_INTTYPES +AC_DEFUN(BASH_HEADER_INTTYPES, +[ + AC_CHECK_HEADERS(inttypes.h) +]) + +dnl +dnl check for typedef'd symbols in header files, but allow the caller to +dnl specify the include files to be checked in addition to the default +dnl +dnl BASH_CHECK_TYPE(TYPE, HEADERS, DEFAULT[, VALUE-IF-FOUND]) +AC_DEFUN(BASH_CHECK_TYPE, +[ +AC_REQUIRE([AC_HEADER_STDC])dnl +AC_REQUIRE([BASH_HEADER_INTTYPES]) +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL(bash_cv_type_$1, +[AC_EGREP_CPP($1, [#include +#if STDC_HEADERS +#include +#include +#endif +#if HAVE_INTTYPES_H +#include +#endif +$2 +], bash_cv_type_$1=yes, bash_cv_type_$1=no)]) +AC_MSG_RESULT($bash_cv_type_$1) +ifelse($#, 4, [if test $bash_cv_type_$1 = yes; then + AC_DEFINE($4) + fi]) +if test $bash_cv_type_$1 = no; then + AC_DEFINE_UNQUOTED($1, $3) +fi +]) + +dnl +dnl BASH_CHECK_DECL(FUNC) +dnl +dnl Check for a declaration of FUNC in stdlib.h and inttypes.h like +dnl AC_CHECK_DECL +dnl +AC_DEFUN(BASH_CHECK_DECL, +[ +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([BASH_HEADER_INTTYPES]) +AC_CACHE_CHECK([for declaration of $1], bash_cv_decl_$1, +[AC_TRY_LINK( +[ +#if STDC_HEADERS +# include +#endif +#if HAVE_INTTYPES_H +# include +#endif +], +[return !$1;], +bash_cv_decl_$1=yes, bash_cv_decl_$1=no)]) +bash_tr_func=HAVE_DECL_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` +if test $bash_cv_decl_$1 = yes; then + AC_DEFINE_UNQUOTED($bash_tr_func, 1) +else + AC_DEFINE_UNQUOTED($bash_tr_func, 0) +fi +]) + +AC_DEFUN(BASH_DECL_PRINTF, +[AC_MSG_CHECKING(for declaration of printf in ) +AC_CACHE_VAL(bash_cv_printf_declared, +[AC_TRY_RUN([ +#include +#ifdef __STDC__ +typedef int (*_bashfunc)(const char *, ...); +#else +typedef int (*_bashfunc)(); +#endif +main() +{ +_bashfunc pf; +pf = (_bashfunc) printf; +exit(pf == 0); +} +], bash_cv_printf_declared=yes, bash_cv_printf_declared=no, + [AC_MSG_WARN(cannot check printf declaration if cross compiling -- defaulting to yes) + bash_cv_printf_declared=yes] +)]) +AC_MSG_RESULT($bash_cv_printf_declared) +if test $bash_cv_printf_declared = yes; then +AC_DEFINE(PRINTF_DECLARED) +fi +]) + +AC_DEFUN(BASH_DECL_SBRK, +[AC_MSG_CHECKING(for declaration of sbrk in ) +AC_CACHE_VAL(bash_cv_sbrk_declared, +[AC_EGREP_HEADER(sbrk, unistd.h, + bash_cv_sbrk_declared=yes, bash_cv_sbrk_declared=no)]) +AC_MSG_RESULT($bash_cv_sbrk_declared) +if test $bash_cv_sbrk_declared = yes; then +AC_DEFINE(SBRK_DECLARED) +fi +]) + +dnl +dnl Check for sys_siglist[] or _sys_siglist[] +dnl +AC_DEFUN(BASH_DECL_UNDER_SYS_SIGLIST, +[AC_MSG_CHECKING([for _sys_siglist in signal.h or unistd.h]) +AC_CACHE_VAL(bash_cv_decl_under_sys_siglist, +[AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif], [ char *msg = _sys_siglist[2]; ], + bash_cv_decl_under_sys_siglist=yes, bash_cv_decl_under_sys_siglist=no, + [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no)])])dnl +AC_MSG_RESULT($bash_cv_decl_under_sys_siglist) +if test $bash_cv_decl_under_sys_siglist = yes; then +AC_DEFINE(UNDER_SYS_SIGLIST_DECLARED) +fi +]) + +AC_DEFUN(BASH_UNDER_SYS_SIGLIST, +[AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST]) +AC_MSG_CHECKING([for _sys_siglist in system C library]) +AC_CACHE_VAL(bash_cv_under_sys_siglist, +[AC_TRY_RUN([ +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifndef UNDER_SYS_SIGLIST_DECLARED +extern char *_sys_siglist[]; +#endif +main() +{ +char *msg = (char *)_sys_siglist[2]; +exit(msg == 0); +}], + bash_cv_under_sys_siglist=yes, bash_cv_under_sys_siglist=no, + [AC_MSG_WARN(cannot check for _sys_siglist[] if cross compiling -- defaulting to no) + bash_cv_under_sys_siglist=no])]) +AC_MSG_RESULT($bash_cv_under_sys_siglist) +if test $bash_cv_under_sys_siglist = yes; then +AC_DEFINE(HAVE_UNDER_SYS_SIGLIST) +fi +]) + +AC_DEFUN(BASH_SYS_SIGLIST, +[AC_REQUIRE([AC_DECL_SYS_SIGLIST]) +AC_MSG_CHECKING([for sys_siglist in system C library]) +AC_CACHE_VAL(bash_cv_sys_siglist, +[AC_TRY_RUN([ +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifndef SYS_SIGLIST_DECLARED +extern char *sys_siglist[]; +#endif +main() +{ +char *msg = sys_siglist[2]; +exit(msg == 0); +}], + bash_cv_sys_siglist=yes, bash_cv_sys_siglist=no, + [AC_MSG_WARN(cannot check for sys_siglist if cross compiling -- defaulting to no) + bash_cv_sys_siglist=no])]) +AC_MSG_RESULT($bash_cv_sys_siglist) +if test $bash_cv_sys_siglist = yes; then +AC_DEFINE(HAVE_SYS_SIGLIST) +fi +]) + +dnl Check for the various permutations of sys_siglist and make sure we +dnl compile in siglist.o if they're not defined +AC_DEFUN(BASH_CHECK_SYS_SIGLIST, [ +AC_REQUIRE([BASH_SYS_SIGLIST]) +AC_REQUIRE([BASH_DECL_UNDER_SYS_SIGLIST]) +AC_REQUIRE([BASH_FUNC_STRSIGNAL]) +if test "$bash_cv_sys_siglist" = no && test "$bash_cv_under_sys_siglist" = no && test "$bash_cv_have_strsignal" = no; then + SIGLIST_O=siglist.o +else + SIGLIST_O= +fi +AC_SUBST([SIGLIST_O]) +]) + +dnl Check for sys_errlist[] and sys_nerr, check for declaration +AC_DEFUN(BASH_SYS_ERRLIST, +[AC_MSG_CHECKING([for sys_errlist and sys_nerr]) +AC_CACHE_VAL(bash_cv_sys_errlist, +[AC_TRY_LINK([#include ], +[extern char *sys_errlist[]; + extern int sys_nerr; + char *msg = sys_errlist[sys_nerr - 1];], + bash_cv_sys_errlist=yes, bash_cv_sys_errlist=no)])dnl +AC_MSG_RESULT($bash_cv_sys_errlist) +if test $bash_cv_sys_errlist = yes; then +AC_DEFINE(HAVE_SYS_ERRLIST) +fi +]) + +dnl +dnl Check if dup2() does not clear the close on exec flag +dnl +AC_DEFUN(BASH_FUNC_DUP2_CLOEXEC_CHECK, +[AC_MSG_CHECKING(if dup2 fails to clear the close-on-exec flag) +AC_CACHE_VAL(bash_cv_dup2_broken, +[AC_TRY_RUN([ +#include +#include +main() +{ + int fd1, fd2, fl; + fd1 = open("/dev/null", 2); + if (fcntl(fd1, 2, 1) < 0) + exit(1); + fd2 = dup2(fd1, 1); + if (fd2 < 0) + exit(2); + fl = fcntl(fd2, 1, 0); + /* fl will be 1 if dup2 did not reset the close-on-exec flag. */ + exit(fl != 1); +} +], bash_cv_dup2_broken=yes, bash_cv_dup2_broken=no, + [AC_MSG_WARN(cannot check dup2 if cross compiling -- defaulting to no) + bash_cv_dup2_broken=no]) +]) +AC_MSG_RESULT($bash_cv_dup2_broken) +if test $bash_cv_dup2_broken = yes; then +AC_DEFINE(DUP2_BROKEN) +fi +]) + +AC_DEFUN(BASH_FUNC_STRSIGNAL, +[AC_MSG_CHECKING([for the existence of strsignal]) +AC_CACHE_VAL(bash_cv_have_strsignal, +[AC_TRY_LINK([#include +#include ], +[char *s = (char *)strsignal(2);], + bash_cv_have_strsignal=yes, bash_cv_have_strsignal=no)]) +AC_MSG_RESULT($bash_cv_have_strsignal) +if test $bash_cv_have_strsignal = yes; then +AC_DEFINE(HAVE_STRSIGNAL) +fi +]) + +dnl Check to see if opendir will open non-directories (not a nice thing) +AC_DEFUN(BASH_FUNC_OPENDIR_CHECK, +[AC_REQUIRE([AC_HEADER_DIRENT])dnl +AC_MSG_CHECKING(if opendir() opens non-directories) +AC_CACHE_VAL(bash_cv_opendir_not_robust, +[AC_TRY_RUN([ +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include +# endif +#endif /* HAVE_DIRENT_H */ +main() +{ +DIR *dir; +int fd, err; +err = mkdir("/tmp/bash-aclocal", 0700); +if (err < 0) { + perror("mkdir"); + exit(1); +} +unlink("/tmp/bash-aclocal/not_a_directory"); +fd = open("/tmp/bash-aclocal/not_a_directory", O_WRONLY|O_CREAT|O_EXCL, 0666); +write(fd, "\n", 1); +close(fd); +dir = opendir("/tmp/bash-aclocal/not_a_directory"); +unlink("/tmp/bash-aclocal/not_a_directory"); +rmdir("/tmp/bash-aclocal"); +exit (dir == 0); +}], bash_cv_opendir_not_robust=yes,bash_cv_opendir_not_robust=no, + [AC_MSG_WARN(cannot check opendir if cross compiling -- defaulting to no) + bash_cv_opendir_not_robust=no] +)]) +AC_MSG_RESULT($bash_cv_opendir_not_robust) +if test $bash_cv_opendir_not_robust = yes; then +AC_DEFINE(OPENDIR_NOT_ROBUST) +fi +]) + +dnl +AC_DEFUN(BASH_TYPE_SIGHANDLER, +[AC_MSG_CHECKING([whether signal handlers are of type void]) +AC_CACHE_VAL(bash_cv_void_sighandler, +[AC_TRY_COMPILE([#include +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" +#endif +void (*signal ()) ();], +[int i;], bash_cv_void_sighandler=yes, bash_cv_void_sighandler=no)])dnl +AC_MSG_RESULT($bash_cv_void_sighandler) +if test $bash_cv_void_sighandler = yes; then +AC_DEFINE(VOID_SIGHANDLER) +fi +]) + +dnl +dnl A signed 16-bit integer quantity +dnl +AC_DEFUN(BASH_TYPE_BITS16_T, +[ +if test "$ac_cv_sizeof_short" = 2; then + AC_CHECK_TYPE(bits16_t, short) +elif test "$ac_cv_sizeof_char" = 2; then + AC_CHECK_TYPE(bits16_t, char) +else + AC_CHECK_TYPE(bits16_t, short) +fi +]) + +dnl +dnl An unsigned 16-bit integer quantity +dnl +AC_DEFUN(BASH_TYPE_U_BITS16_T, +[ +if test "$ac_cv_sizeof_short" = 2; then + AC_CHECK_TYPE(u_bits16_t, unsigned short) +elif test "$ac_cv_sizeof_char" = 2; then + AC_CHECK_TYPE(u_bits16_t, unsigned char) +else + AC_CHECK_TYPE(u_bits16_t, unsigned short) +fi +]) + +dnl +dnl A signed 32-bit integer quantity +dnl +AC_DEFUN(BASH_TYPE_BITS32_T, +[ +if test "$ac_cv_sizeof_int" = 4; then + AC_CHECK_TYPE(bits32_t, int) +elif test "$ac_cv_sizeof_long" = 4; then + AC_CHECK_TYPE(bits32_t, long) +else + AC_CHECK_TYPE(bits32_t, int) +fi +]) + +dnl +dnl An unsigned 32-bit integer quantity +dnl +AC_DEFUN(BASH_TYPE_U_BITS32_T, +[ +if test "$ac_cv_sizeof_int" = 4; then + AC_CHECK_TYPE(u_bits32_t, unsigned int) +elif test "$ac_cv_sizeof_long" = 4; then + AC_CHECK_TYPE(u_bits32_t, unsigned long) +else + AC_CHECK_TYPE(u_bits32_t, unsigned int) +fi +]) + +AC_DEFUN(BASH_TYPE_PTRDIFF_T, +[ +if test "$ac_cv_sizeof_int" = "$ac_cv_sizeof_char_p"; then + AC_CHECK_TYPE(ptrdiff_t, int) +elif test "$ac_cv_sizeof_long" = "$ac_cv_sizeof_char_p"; then + AC_CHECK_TYPE(ptrdiff_t, long) +elif test "$ac_cv_type_long_long" = yes && test "$ac_cv_sizeof_long_long" = "$ac_cv_sizeof_char_p"; then + AC_CHECK_TYPE(ptrdiff_t, [long long]) +else + AC_CHECK_TYPE(ptrdiff_t, int) +fi +]) + +dnl +dnl A signed 64-bit quantity +dnl +AC_DEFUN(BASH_TYPE_BITS64_T, +[ +if test "$ac_cv_sizeof_char_p" = 8; then + AC_CHECK_TYPE(bits64_t, char *) +elif test "$ac_cv_sizeof_double" = 8; then + AC_CHECK_TYPE(bits64_t, double) +elif test -n "$ac_cv_type_long_long" && test "$ac_cv_sizeof_long_long" = 8; then + AC_CHECK_TYPE(bits64_t, [long long]) +elif test "$ac_cv_sizeof_long" = 8; then + AC_CHECK_TYPE(bits64_t, long) +else + AC_CHECK_TYPE(bits64_t, double) +fi +]) + +AC_DEFUN(BASH_TYPE_LONG_LONG, +[ +AC_CACHE_CHECK([for long long], bash_cv_type_long_long, +[AC_TRY_LINK([ +long long ll = 1; int i = 63;], +[ +long long llm = (long long) -1; +return ll << i | ll >> i | llm / ll | llm % ll; +], bash_cv_type_long_long='long long', bash_cv_type_long_long='long')]) +if test "$bash_cv_type_long_long" = 'long long'; then + AC_DEFINE(HAVE_LONG_LONG, 1) +fi +]) + +AC_DEFUN(BASH_TYPE_UNSIGNED_LONG_LONG, +[ +AC_CACHE_CHECK([for unsigned long long], bash_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; +], bash_cv_type_unsigned_long_long='unsigned long long', + bash_cv_type_unsigned_long_long='unsigned long')]) +if test "$bash_cv_type_unsigned_long_long" = 'unsigned long long'; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1) +fi +]) + +dnl +dnl Type of struct rlimit fields: some systems (OSF/1, NetBSD, RISC/os 5.0) +dnl have a rlim_t, others (4.4BSD based systems) use quad_t, others use +dnl long and still others use int (HP-UX 9.01, SunOS 4.1.3). To simplify +dnl matters, this just checks for rlim_t, quad_t, or long. +dnl +AC_DEFUN(BASH_TYPE_RLIMIT, +[AC_MSG_CHECKING(for size and type of struct rlimit fields) +AC_CACHE_VAL(bash_cv_type_rlimit, +[AC_TRY_COMPILE([#include +#include ], +[rlim_t xxx;], bash_cv_type_rlimit=rlim_t,[ +AC_TRY_RUN([ +#include +#include +#include +main() +{ +#ifdef HAVE_QUAD_T + struct rlimit rl; + if (sizeof(rl.rlim_cur) == sizeof(quad_t)) + exit(0); +#endif + exit(1); +}], bash_cv_type_rlimit=quad_t, bash_cv_type_rlimit=long, + [AC_MSG_WARN(cannot check quad_t if cross compiling -- defaulting to long) + bash_cv_type_rlimit=long])]) +]) +AC_MSG_RESULT($bash_cv_type_rlimit) +if test $bash_cv_type_rlimit = quad_t; then +AC_DEFINE(RLIMTYPE, quad_t) +elif test $bash_cv_type_rlimit = rlim_t; then +AC_DEFINE(RLIMTYPE, rlim_t) +fi +]) + +AC_DEFUN(BASH_FUNC_LSTAT, +[dnl Cannot use AC_CHECK_FUNCS(lstat) because Linux defines lstat() as an +dnl inline function in . +AC_CACHE_CHECK([for lstat], bash_cv_func_lstat, +[AC_TRY_LINK([ +#include +#include +],[ lstat(".",(struct stat *)0); ], +bash_cv_func_lstat=yes, bash_cv_func_lstat=no)]) +if test $bash_cv_func_lstat = yes; then + AC_DEFINE(HAVE_LSTAT) +fi +]) + +AC_DEFUN(BASH_FUNC_INET_ATON, +[ +AC_CACHE_CHECK([for inet_aton], bash_cv_func_inet_aton, +[AC_TRY_LINK([ +#include +#include +#include +struct in_addr ap;], [ inet_aton("127.0.0.1", &ap); ], +bash_cv_func_inet_aton=yes, bash_cv_func_inet_aton=no)]) +if test $bash_cv_func_inet_aton = yes; then + AC_DEFINE(HAVE_INET_ATON) +else + AC_LIBOBJ(inet_aton) +fi +]) + +AC_DEFUN(BASH_FUNC_GETENV, +[AC_MSG_CHECKING(to see if getenv can be redefined) +AC_CACHE_VAL(bash_cv_getenv_redef, +[AC_TRY_RUN([ +#ifdef HAVE_UNISTD_H +# include +#endif +#ifndef __STDC__ +# ifndef const +# define const +# endif +#endif +char * +getenv (name) +#if defined (__linux__) || defined (__bsdi__) || defined (convex) + const char *name; +#else + char const *name; +#endif /* !__linux__ && !__bsdi__ && !convex */ +{ +return "42"; +} +main() +{ +char *s; +/* The next allows this program to run, but does not allow bash to link + when it redefines getenv. I'm not really interested in figuring out + why not. */ +#if defined (NeXT) +exit(1); +#endif +s = getenv("ABCDE"); +exit(s == 0); /* force optimizer to leave getenv in */ +} +], bash_cv_getenv_redef=yes, bash_cv_getenv_redef=no, + [AC_MSG_WARN(cannot check getenv redefinition if cross compiling -- defaulting to yes) + bash_cv_getenv_redef=yes] +)]) +AC_MSG_RESULT($bash_cv_getenv_redef) +if test $bash_cv_getenv_redef = yes; then +AC_DEFINE(CAN_REDEFINE_GETENV) +fi +]) + +# We should check for putenv before calling this +AC_DEFUN(BASH_FUNC_STD_PUTENV, +[ +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_C_PROTOTYPES]) +AC_CACHE_CHECK([for standard-conformant putenv declaration], bash_cv_std_putenv, +[AC_TRY_LINK([ +#if STDC_HEADERS +#include +#include +#endif +#ifndef __STDC__ +# ifndef const +# define const +# endif +#endif +#ifdef PROTOTYPES +extern int putenv (char *); +#else +extern int putenv (); +#endif +], +[return (putenv == 0);], +bash_cv_std_putenv=yes, bash_cv_std_putenv=no +)]) +if test $bash_cv_std_putenv = yes; then +AC_DEFINE(HAVE_STD_PUTENV) +fi +]) + +# We should check for unsetenv before calling this +AC_DEFUN(BASH_FUNC_STD_UNSETENV, +[ +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_C_PROTOTYPES]) +AC_CACHE_CHECK([for standard-conformant unsetenv declaration], bash_cv_std_unsetenv, +[AC_TRY_LINK([ +#if STDC_HEADERS +#include +#include +#endif +#ifndef __STDC__ +# ifndef const +# define const +# endif +#endif +#ifdef PROTOTYPES +extern int unsetenv (const char *); +#else +extern int unsetenv (); +#endif +], +[return (unsetenv == 0);], +bash_cv_std_unsetenv=yes, bash_cv_std_unsetenv=no +)]) +if test $bash_cv_std_unsetenv = yes; then +AC_DEFINE(HAVE_STD_UNSETENV) +fi +]) + +AC_DEFUN(BASH_FUNC_ULIMIT_MAXFDS, +[AC_MSG_CHECKING(whether ulimit can substitute for getdtablesize) +AC_CACHE_VAL(bash_cv_ulimit_maxfds, +[AC_TRY_RUN([ +main() +{ +long maxfds = ulimit(4, 0L); +exit (maxfds == -1L); +} +], bash_cv_ulimit_maxfds=yes, bash_cv_ulimit_maxfds=no, + [AC_MSG_WARN(cannot check ulimit if cross compiling -- defaulting to no) + bash_cv_ulimit_maxfds=no] +)]) +AC_MSG_RESULT($bash_cv_ulimit_maxfds) +if test $bash_cv_ulimit_maxfds = yes; then +AC_DEFINE(ULIMIT_MAXFDS) +fi +]) + +AC_DEFUN(BASH_FUNC_GETCWD, +[AC_MSG_CHECKING([if getcwd() calls popen()]) +AC_CACHE_VAL(bash_cv_getcwd_calls_popen, +[AC_TRY_RUN([ +#include +#ifdef HAVE_UNISTD_H +#include +#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); +} +], 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] +)]) +AC_MSG_RESULT($bash_cv_getcwd_calls_popen) +if test $bash_cv_getcwd_calls_popen = yes; then +AC_DEFINE(GETCWD_BROKEN) +AC_LIBOBJ(getcwd) +fi +]) + +dnl +dnl This needs BASH_CHECK_SOCKLIB, but since that's not called on every +dnl system, we can't use AC_PREREQ +dnl +AC_DEFUN(BASH_FUNC_GETHOSTBYNAME, +[if test "X$bash_cv_have_gethostbyname" = "X"; then +_bash_needmsg=yes +else +AC_MSG_CHECKING(for gethostbyname in socket library) +_bash_needmsg= +fi +AC_CACHE_VAL(bash_cv_have_gethostbyname, +[AC_TRY_LINK([#include ], +[ struct hostent *hp; + hp = gethostbyname("localhost"); +], bash_cv_have_gethostbyname=yes, bash_cv_have_gethostbyname=no)] +) +if test "X$_bash_needmsg" = Xyes; then + AC_MSG_CHECKING(for gethostbyname in socket library) +fi +AC_MSG_RESULT($bash_cv_have_gethostbyname) +if test "$bash_cv_have_gethostbyname" = yes; then +AC_DEFINE(HAVE_GETHOSTBYNAME) +fi +]) + +AC_DEFUN(BASH_FUNC_FNMATCH_EXTMATCH, +[AC_MSG_CHECKING(if fnmatch does extended pattern matching with FNM_EXTMATCH) +AC_CACHE_VAL(bash_cv_fnm_extmatch, +[AC_TRY_RUN([ +#include + +main() +{ +#ifdef FNM_EXTMATCH + exit (0); +#else + exit (1); +#endif +} +], bash_cv_fnm_extmatch=yes, bash_cv_fnm_extmatch=no, + [AC_MSG_WARN(cannot check FNM_EXTMATCH if cross compiling -- defaulting to no) + bash_cv_fnm_extmatch=no]) +]) +AC_MSG_RESULT($bash_cv_fnm_extmatch) +if test $bash_cv_fnm_extmatch = yes; then +AC_DEFINE(HAVE_LIBC_FNM_EXTMATCH) +fi +]) + +AC_DEFUN(BASH_FUNC_POSIX_SETJMP, +[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) +AC_MSG_CHECKING(for presence of POSIX-style sigsetjmp/siglongjmp) +AC_CACHE_VAL(bash_cv_func_sigsetjmp, +[AC_TRY_RUN([ +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +main() +{ +#if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) +exit (1); +#else + +int code; +sigset_t set, oset; +sigjmp_buf xx; + +/* get the mask */ +sigemptyset(&set); +sigemptyset(&oset); +sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set); +sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); + +/* save it */ +code = sigsetjmp(xx, 1); +if (code) + exit(0); /* could get sigmask and compare to oset here. */ + +/* change it */ +sigaddset(&set, SIGINT); +sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); + +/* and siglongjmp */ +siglongjmp(xx, 10); +exit(1); +#endif +}], bash_cv_func_sigsetjmp=present, bash_cv_func_sigsetjmp=missing, + [AC_MSG_WARN(cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing) + bash_cv_func_sigsetjmp=missing] +)]) +AC_MSG_RESULT($bash_cv_func_sigsetjmp) +if test $bash_cv_func_sigsetjmp = present; then +AC_DEFINE(HAVE_POSIX_SIGSETJMP) +fi +]) + +AC_DEFUN(BASH_FUNC_STRCOLL, +[ +AC_MSG_CHECKING(whether or not strcoll and strcmp differ) +AC_CACHE_VAL(bash_cv_func_strcoll_broken, +[AC_TRY_RUN([ +#include +#if defined (HAVE_LOCALE_H) +#include +#endif + +main(c, v) +int c; +char *v[]; +{ + int r1, r2; + char *deflocale, *defcoll; + +#ifdef HAVE_SETLOCALE + deflocale = setlocale(LC_ALL, ""); + defcoll = setlocale(LC_COLLATE, ""); +#endif + +#ifdef HAVE_STRCOLL + /* These two values are taken from tests/glob-test. */ + r1 = strcoll("abd", "aXd"); +#else + r1 = 0; +#endif + r2 = strcmp("abd", "aXd"); + + /* These two should both be greater than 0. It is permissible for + a system to return different values, as long as the sign is the + same. */ + + /* Exit with 1 (failure) if these two values are both > 0, since + this tests whether strcoll(3) is broken with respect to strcmp(3) + in the default locale. */ + exit (r1 > 0 && r2 > 0); +} +], bash_cv_func_strcoll_broken=yes, bash_cv_func_strcoll_broken=no, + [AC_MSG_WARN(cannot check strcoll if cross compiling -- defaulting to no) + bash_cv_func_strcoll_broken=no] +)]) +AC_MSG_RESULT($bash_cv_func_strcoll_broken) +if test $bash_cv_func_strcoll_broken = yes; then +AC_DEFINE(STRCOLL_BROKEN) +fi +]) + +AC_DEFUN(BASH_FUNC_PRINTF_A_FORMAT, +[AC_MSG_CHECKING([for printf floating point output in hex notation]) +AC_CACHE_VAL(bash_cv_printf_a_format, +[AC_TRY_RUN([ +#include +#include + +int +main() +{ + double y = 0.0; + char abuf[1024]; + + sprintf(abuf, "%A", y); + exit(strchr(abuf, 'P') == (char *)0); +} +], bash_cv_printf_a_format=yes, bash_cv_printf_a_format=no, + [AC_MSG_WARN(cannot check printf if cross compiling -- defaulting to no) + bash_cv_printf_a_format=no] +)]) +AC_MSG_RESULT($bash_cv_printf_a_format) +if test $bash_cv_printf_a_format = yes; then +AC_DEFINE(HAVE_PRINTF_A_FORMAT) +fi +]) + +AC_DEFUN(BASH_STRUCT_TERMIOS_LDISC, +[ +AC_CHECK_MEMBER(struct termios.c_line, AC_DEFINE(TERMIOS_LDISC), ,[ +#include +#include +]) +]) + +AC_DEFUN(BASH_STRUCT_TERMIO_LDISC, +[ +AC_CHECK_MEMBER(struct termio.c_line, AC_DEFINE(TERMIO_LDISC), ,[ +#include +#include +]) +]) + +dnl +dnl Like AC_STRUCT_ST_BLOCKS, but doesn't muck with LIBOBJS +dnl +dnl sets bash_cv_struct_stat_st_blocks +dnl +dnl unused for now; we'll see how AC_CHECK_MEMBERS works +dnl +AC_DEFUN(BASH_STRUCT_ST_BLOCKS, +[ +AC_MSG_CHECKING([for struct stat.st_blocks]) +AC_CACHE_VAL(bash_cv_struct_stat_st_blocks, +[AC_TRY_COMPILE( +[ +#include +#include +], +[ +main() +{ +static struct stat a; +if (a.st_blocks) return 0; +return 0; +} +], bash_cv_struct_stat_st_blocks=yes, bash_cv_struct_stat_st_blocks=no) +]) +AC_MSG_RESULT($bash_cv_struct_stat_st_blocks) +if test "$bash_cv_struct_stat_st_blocks" = "yes"; then +AC_DEFINE(HAVE_STRUCT_STAT_ST_BLOCKS) +fi +]) + +AC_DEFUN(BASH_CHECK_LIB_TERMCAP, +[ +if test "X$bash_cv_termcap_lib" = "X"; then +_bash_needmsg=yes +else +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_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)])])])]) +if test "X$_bash_needmsg" = "Xyes"; then +AC_MSG_CHECKING(which library has the termcap functions) +fi +AC_MSG_RESULT(using $bash_cv_termcap_lib) +if test $bash_cv_termcap_lib = gnutermcap && test -z "$prefer_curses"; then +LDFLAGS="$LDFLAGS -L./lib/termcap" +TERMCAP_LIB="./lib/termcap/libtermcap.a" +TERMCAP_DEP="./lib/termcap/libtermcap.a" +elif test $bash_cv_termcap_lib = libtermcap && test -z "$prefer_curses"; then +TERMCAP_LIB=-ltermcap +TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libtinfo; then +TERMCAP_LIB=-ltinfo +TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libncurses; then +TERMCAP_LIB=-lncurses +TERMCAP_DEP= +else +TERMCAP_LIB=-lcurses +TERMCAP_DEP= +fi +]) + +dnl +dnl Check for the presence of getpeername in libsocket. +dnl If libsocket is present, check for libnsl and add it to LIBS if +dnl it's there, since most systems with libsocket require linking +dnl with libnsl as well. This should only be called if getpeername +dnl was not found in libc. +dnl +dnl NOTE: IF WE FIND GETPEERNAME, WE ASSUME THAT WE HAVE BIND/CONNECT +dnl AS WELL +dnl +AC_DEFUN(BASH_CHECK_LIB_SOCKET, +[ +if test "X$bash_cv_have_socklib" = "X"; then +_bash_needmsg= +else +AC_MSG_CHECKING(for socket library) +_bash_needmsg=yes +fi +AC_CACHE_VAL(bash_cv_have_socklib, +[AC_CHECK_LIB(socket, getpeername, + bash_cv_have_socklib=yes, bash_cv_have_socklib=no, -lnsl)]) +if test "X$_bash_needmsg" = Xyes; then + AC_MSG_RESULT($bash_cv_have_socklib) + _bash_needmsg= +fi +if test $bash_cv_have_socklib = yes; then + # check for libnsl, add it to LIBS if present + if test "X$bash_cv_have_libnsl" = "X"; then + _bash_needmsg= + else + AC_MSG_CHECKING(for libnsl) + _bash_needmsg=yes + fi + AC_CACHE_VAL(bash_cv_have_libnsl, + [AC_CHECK_LIB(nsl, t_open, + bash_cv_have_libnsl=yes, bash_cv_have_libnsl=no)]) + if test "X$_bash_needmsg" = Xyes; then + AC_MSG_RESULT($bash_cv_have_libnsl) + _bash_needmsg= + fi + if test $bash_cv_have_libnsl = yes; then + LIBS="-lsocket -lnsl $LIBS" + else + LIBS="-lsocket $LIBS" + fi + AC_DEFINE(HAVE_LIBSOCKET) + AC_DEFINE(HAVE_GETPEERNAME) +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_CACHE_VAL(bash_cv_dirent_has_dino, +[AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include +# endif +#endif /* HAVE_DIRENT_H */ +],[ +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) +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_CACHE_VAL(bash_cv_dirent_has_d_fileno, +[AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include +# endif +#endif /* HAVE_DIRENT_H */ +],[ +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) +fi +]) + +AC_DEFUN(BASH_STRUCT_TIMEVAL, +[AC_MSG_CHECKING(for struct timeval in sys/time.h and time.h) +AC_CACHE_VAL(bash_cv_struct_timeval, +[ +AC_EGREP_HEADER(struct timeval, sys/time.h, + bash_cv_struct_timeval=yes, + AC_EGREP_HEADER(struct timeval, time.h, + bash_cv_struct_timeval=yes, + bash_cv_struct_timeval=no)) +]) +AC_MSG_RESULT($bash_cv_struct_timeval) +if test $bash_cv_struct_timeval = yes; then + AC_DEFINE(HAVE_TIMEVAL) +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, +[AC_TRY_COMPILE([#include +#include ], [struct winsize x;], + bash_cv_struct_winsize_header=ioctl_h, + [AC_TRY_COMPILE([#include +#include ], [struct winsize x;], + bash_cv_struct_winsize_header=termios_h, bash_cv_struct_winsize_header=other) +])]) +if test $bash_cv_struct_winsize_header = ioctl_h; then + AC_MSG_RESULT(sys/ioctl.h) + AC_DEFINE(STRUCT_WINSIZE_IN_SYS_IOCTL) +elif test $bash_cv_struct_winsize_header = termios_h; then + AC_MSG_RESULT(termios.h) + AC_DEFINE(STRUCT_WINSIZE_IN_TERMIOS) +else + AC_MSG_RESULT(not found) +fi +]) + +dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7) +AC_DEFUN(BASH_SYS_SIGNAL_VINTAGE, +[AC_REQUIRE([AC_TYPE_SIGNAL]) +AC_MSG_CHECKING(for type of signal functions) +AC_CACHE_VAL(bash_cv_signal_vintage, +[ + AC_TRY_LINK([#include ],[ + sigset_t ss; + struct sigaction sa; + sigemptyset(&ss); sigsuspend(&ss); + sigaction(SIGINT, &sa, (struct sigaction *) 0); + sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); + ], bash_cv_signal_vintage=posix, + [ + AC_TRY_LINK([#include ], [ + int mask = sigmask(SIGINT); + sigsetmask(mask); sigblock(mask); sigpause(mask); + ], bash_cv_signal_vintage=4.2bsd, + [ + AC_TRY_LINK([ + #include + RETSIGTYPE foo() { }], [ + int mask = sigmask(SIGINT); + sigset(SIGINT, foo); sigrelse(SIGINT); + sighold(SIGINT); sigpause(SIGINT); + ], bash_cv_signal_vintage=svr3, bash_cv_signal_vintage=v7 + )] + )] +) +]) +AC_MSG_RESULT($bash_cv_signal_vintage) +if test "$bash_cv_signal_vintage" = posix; then +AC_DEFINE(HAVE_POSIX_SIGNALS) +elif test "$bash_cv_signal_vintage" = "4.2bsd"; then +AC_DEFINE(HAVE_BSD_SIGNALS) +elif test "$bash_cv_signal_vintage" = svr3; then +AC_DEFINE(HAVE_USG_SIGHOLD) +fi +]) + +dnl Check if the pgrp of setpgrp() can't be the pid of a zombie process. +AC_DEFUN(BASH_SYS_PGRP_SYNC, +[AC_REQUIRE([AC_FUNC_GETPGRP]) +AC_MSG_CHECKING(whether pgrps need synchronization) +AC_CACHE_VAL(bash_cv_pgrp_pipe, +[AC_TRY_RUN([ +#ifdef HAVE_UNISTD_H +# include +#endif +main() +{ +# ifdef GETPGRP_VOID +# define getpgID() getpgrp() +# else +# define getpgID() getpgrp(0) +# define setpgid(x,y) setpgrp(x,y) +# endif + int pid1, pid2, fds[2]; + int status; + char ok; + + switch (pid1 = fork()) { + case -1: + exit(1); + case 0: + setpgid(0, getpid()); + exit(0); + } + setpgid(pid1, pid1); + + sleep(2); /* let first child die */ + + if (pipe(fds) < 0) + exit(2); + + switch (pid2 = fork()) { + case -1: + exit(3); + case 0: + setpgid(0, pid1); + ok = getpgID() == pid1; + write(fds[1], &ok, 1); + exit(0); + } + setpgid(pid2, pid1); + + close(fds[1]); + if (read(fds[0], &ok, 1) != 1) + exit(4); + wait(&status); + wait(&status); + exit(ok ? 0 : 5); +} +], bash_cv_pgrp_pipe=no,bash_cv_pgrp_pipe=yes, + [AC_MSG_WARN(cannot check pgrp synchronization if cross compiling -- defaulting to no) + bash_cv_pgrp_pipe=no]) +]) +AC_MSG_RESULT($bash_cv_pgrp_pipe) +if test $bash_cv_pgrp_pipe = yes; then +AC_DEFINE(PGRP_PIPE) +fi +]) + +AC_DEFUN(BASH_SYS_REINSTALL_SIGHANDLERS, +[AC_REQUIRE([AC_TYPE_SIGNAL]) +AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) +AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked]) +AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers, +[AC_TRY_RUN([ +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +typedef RETSIGTYPE sigfunc(); + +int nsigint; + +#ifdef HAVE_POSIX_SIGNALS +sigfunc * +set_signal_handler(sig, handler) + int sig; + sigfunc *handler; +{ + struct sigaction act, oact; + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigemptyset (&oact.sa_mask); + sigaction (sig, &act, &oact); + return (oact.sa_handler); +} +#else +#define set_signal_handler(s, h) signal(s, h) +#endif + +RETSIGTYPE +sigint(s) +int s; +{ + nsigint++; +} + +main() +{ + nsigint = 0; + set_signal_handler(SIGINT, sigint); + kill((int)getpid(), SIGINT); + kill((int)getpid(), SIGINT); + exit(nsigint != 2); +} +], bash_cv_must_reinstall_sighandlers=no, bash_cv_must_reinstall_sighandlers=yes, + [AC_MSG_WARN(cannot check signal handling if cross compiling -- defaulting to no) + bash_cv_must_reinstall_sighandlers=no] +)]) +AC_MSG_RESULT($bash_cv_must_reinstall_sighandlers) +if test $bash_cv_must_reinstall_sighandlers = yes; then +AC_DEFINE(MUST_REINSTALL_SIGHANDLERS) +fi +]) + +dnl check that some necessary job control definitions are present +AC_DEFUN(BASH_SYS_JOB_CONTROL_MISSING, +[AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) +AC_MSG_CHECKING(for presence of necessary job control definitions) +AC_CACHE_VAL(bash_cv_job_control_missing, +[AC_TRY_RUN([ +#include +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +/* Add more tests in here as appropriate. */ +main() +{ +/* signal type */ +#if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS) +exit(1); +#endif + +/* signals and tty control. */ +#if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT) +exit (1); +#endif + +/* process control */ +#if !defined (WNOHANG) || !defined (WUNTRACED) +exit(1); +#endif + +/* Posix systems have tcgetpgrp and waitpid. */ +#if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP) +exit(1); +#endif + +#if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID) +exit(1); +#endif + +/* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */ +#if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3) +exit(1); +#endif + +exit(0); +}], bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing, + [AC_MSG_WARN(cannot check job control if cross-compiling -- defaulting to missing) + bash_cv_job_control_missing=missing] +)]) +AC_MSG_RESULT($bash_cv_job_control_missing) +if test $bash_cv_job_control_missing = missing; then +AC_DEFINE(JOB_CONTROL_MISSING) +fi +]) + +dnl check whether named pipes are present +dnl this requires a previous check for mkfifo, but that is awkward to specify +AC_DEFUN(BASH_SYS_NAMED_PIPES, +[AC_MSG_CHECKING(for presence of named pipes) +AC_CACHE_VAL(bash_cv_sys_named_pipes, +[AC_TRY_RUN([ +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +/* Add more tests in here as appropriate. */ +main() +{ +int fd, err; + +#if defined (HAVE_MKFIFO) +exit (0); +#endif + +#if !defined (S_IFIFO) && (defined (_POSIX_VERSION) && !defined (S_ISFIFO)) +exit (1); +#endif + +#if defined (NeXT) +exit (1); +#endif +err = mkdir("/tmp/bash-aclocal", 0700); +if (err < 0) { + perror ("mkdir"); + exit(1); +} +fd = mknod ("/tmp/bash-aclocal/sh-np-autoconf", 0666 | S_IFIFO, 0); +if (fd == -1) { + rmdir ("/tmp/bash-aclocal"); + exit (1); +} +close(fd); +unlink ("/tmp/bash-aclocal/sh-np-autoconf"); +rmdir ("/tmp/bash-aclocal"); +exit(0); +}], bash_cv_sys_named_pipes=present, bash_cv_sys_named_pipes=missing, + [AC_MSG_WARN(cannot check for named pipes if cross-compiling -- defaulting to missing) + bash_cv_sys_named_pipes=missing] +)]) +AC_MSG_RESULT($bash_cv_sys_named_pipes) +if test $bash_cv_sys_named_pipes = missing; then +AC_DEFINE(NAMED_PIPES_MISSING) +fi +]) + +AC_DEFUN(BASH_SYS_DEFAULT_MAIL_DIR, +[AC_MSG_CHECKING(for default mail directory) +AC_CACHE_VAL(bash_cv_mail_dir, +[if test -d /var/mail; then + bash_cv_mail_dir=/var/mail + elif test -d /var/spool/mail; then + bash_cv_mail_dir=/var/spool/mail + elif test -d /usr/mail; then + bash_cv_mail_dir=/usr/mail + elif test -d /usr/spool/mail; then + bash_cv_mail_dir=/usr/spool/mail + else + bash_cv_mail_dir=unknown + fi +]) +AC_MSG_RESULT($bash_cv_mail_dir) +AC_DEFINE_UNQUOTED(DEFAULT_MAIL_DIRECTORY, "$bash_cv_mail_dir") +]) + +AC_DEFUN(BASH_HAVE_TIOCGWINSZ, +[AC_MSG_CHECKING(for TIOCGWINSZ in sys/ioctl.h) +AC_CACHE_VAL(bash_cv_tiocgwinsz_in_ioctl, +[AC_TRY_COMPILE([#include +#include ], [int x = TIOCGWINSZ;], + bash_cv_tiocgwinsz_in_ioctl=yes,bash_cv_tiocgwinsz_in_ioctl=no)]) +AC_MSG_RESULT($bash_cv_tiocgwinsz_in_ioctl) +if test $bash_cv_tiocgwinsz_in_ioctl = yes; then +AC_DEFINE(GWINSZ_IN_SYS_IOCTL) +fi +]) + +AC_DEFUN(BASH_HAVE_TIOCSTAT, +[AC_MSG_CHECKING(for TIOCSTAT in sys/ioctl.h) +AC_CACHE_VAL(bash_cv_tiocstat_in_ioctl, +[AC_TRY_COMPILE([#include +#include ], [int x = TIOCSTAT;], + bash_cv_tiocstat_in_ioctl=yes,bash_cv_tiocstat_in_ioctl=no)]) +AC_MSG_RESULT($bash_cv_tiocstat_in_ioctl) +if test $bash_cv_tiocstat_in_ioctl = yes; then +AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL) +fi +]) + +AC_DEFUN(BASH_HAVE_FIONREAD, +[AC_MSG_CHECKING(for FIONREAD in sys/ioctl.h) +AC_CACHE_VAL(bash_cv_fionread_in_ioctl, +[AC_TRY_COMPILE([#include +#include ], [int x = FIONREAD;], + bash_cv_fionread_in_ioctl=yes,bash_cv_fionread_in_ioctl=no)]) +AC_MSG_RESULT($bash_cv_fionread_in_ioctl) +if test $bash_cv_fionread_in_ioctl = yes; then +AC_DEFINE(FIONREAD_IN_SYS_IOCTL) +fi +]) + +dnl +dnl See if speed_t is declared in . Some versions of linux +dnl require a definition of speed_t each time is included, +dnl but you can only get speed_t if you include (on some +dnl versions) or (on others). +dnl +AC_DEFUN(BASH_CHECK_SPEED_T, +[AC_MSG_CHECKING(for speed_t in sys/types.h) +AC_CACHE_VAL(bash_cv_speed_t_in_sys_types, +[AC_TRY_COMPILE([#include ], [speed_t x;], + bash_cv_speed_t_in_sys_types=yes,bash_cv_speed_t_in_sys_types=no)]) +AC_MSG_RESULT($bash_cv_speed_t_in_sys_types) +if test $bash_cv_speed_t_in_sys_types = yes; then +AC_DEFINE(SPEED_T_IN_SYS_TYPES) +fi +]) + +AC_DEFUN(BASH_CHECK_GETPW_FUNCS, +[AC_MSG_CHECKING(whether getpw functions are declared in pwd.h) +AC_CACHE_VAL(bash_cv_getpw_declared, +[AC_EGREP_CPP(getpwuid, +[ +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +], +bash_cv_getpw_declared=yes,bash_cv_getpw_declared=no)]) +AC_MSG_RESULT($bash_cv_getpw_declared) +if test $bash_cv_getpw_declared = yes; then +AC_DEFINE(HAVE_GETPW_DECLS) +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 + bash_cv_dev_fd=whacky + else + bash_cv_dev_fd=absent + fi +]) +AC_MSG_RESULT($bash_cv_dev_fd) +if test $bash_cv_dev_fd = "standard"; then + AC_DEFINE(HAVE_DEV_FD) + AC_DEFINE(DEV_FD_PREFIX, "/dev/fd/") +elif test $bash_cv_dev_fd = "whacky"; then + AC_DEFINE(HAVE_DEV_FD) + AC_DEFINE(DEV_FD_PREFIX, "/proc/self/fd/") +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 + bash_cv_dev_stdin=present + elif test -d /proc/self/fd && test -r /dev/stdin; then + bash_cv_dev_stdin=present + else + bash_cv_dev_stdin=absent + fi +]) +AC_MSG_RESULT($bash_cv_dev_stdin) +if test $bash_cv_dev_stdin = "present"; then + AC_DEFINE(HAVE_DEV_STDIN) +fi +]) + +dnl +dnl Check if HPUX needs _KERNEL defined for RLIMIT_* definitions +dnl +AC_DEFUN(BASH_CHECK_KERNEL_RLIMIT, +[AC_MSG_CHECKING([whether $host_os needs _KERNEL for RLIMIT defines]) +AC_CACHE_VAL(bash_cv_kernel_rlimit, +[AC_TRY_COMPILE([ +#include +#include +], +[ + int f; + f = RLIMIT_DATA; +], bash_cv_kernel_rlimit=no, +[AC_TRY_COMPILE([ +#include +#define _KERNEL +#include +#undef _KERNEL +], +[ + int f; + f = RLIMIT_DATA; +], bash_cv_kernel_rlimit=yes, bash_cv_kernel_rlimit=no)] +)]) +AC_MSG_RESULT($bash_cv_kernel_rlimit) +if test $bash_cv_kernel_rlimit = yes; then +AC_DEFINE(RLIMIT_NEEDS_KERNEL) +fi +]) + +dnl +dnl Check for 64-bit off_t -- used for malloc alignment +dnl +dnl C does not allow duplicate case labels, so the compile will fail if +dnl sizeof(off_t) is > 4. +dnl +AC_DEFUN(BASH_CHECK_OFF_T_64, +[AC_CACHE_CHECK(for 64-bit off_t, bash_cv_off_t_64, +AC_TRY_COMPILE([ +#ifdef HAVE_UNISTD_H +#include +#endif +#include +],[ +switch (0) case 0: case (sizeof (off_t) <= 4):; +], bash_cv_off_t_64=no, bash_cv_off_t_64=yes)) +if test $bash_cv_off_t_64 = yes; then + AC_DEFINE(HAVE_OFF_T_64) +fi]) + +AC_DEFUN(BASH_CHECK_RTSIGS, +[AC_MSG_CHECKING(for unusable real-time signals due to large values) +AC_CACHE_VAL(bash_cv_unusable_rtsigs, +[AC_TRY_RUN([ +#include +#include + +#ifndef NSIG +# define NSIG 64 +#endif + +main () +{ + int n_sigs = 2 * NSIG; +#ifdef SIGRTMIN + int rtmin = SIGRTMIN; +#else + int rtmin = 0; +#endif + + exit(rtmin < n_sigs); +}], bash_cv_unusable_rtsigs=yes, bash_cv_unusable_rtsigs=no, + [AC_MSG_WARN(cannot check real-time signals if cross compiling -- defaulting to yes) + bash_cv_unusable_rtsigs=yes] +)]) +AC_MSG_RESULT($bash_cv_unusable_rtsigs) +if test $bash_cv_unusable_rtsigs = yes; then +AC_DEFINE(UNUSABLE_RT_SIGNALS) +fi +]) + +dnl +dnl check for availability of multibyte characters and functions +dnl +AC_DEFUN(BASH_CHECK_MULTIBYTE, +[ +AC_CHECK_HEADERS(wctype.h) +AC_CHECK_HEADERS(wchar.h) +AC_CHECK_HEADERS(langinfo.h) + +AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS)) +AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH)) + +AC_CACHE_CHECK([for mbstate_t], bash_cv_have_mbstate_t, +[AC_TRY_RUN([ +#include +int +main () +{ + mbstate_t ps; + return 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 + +AC_CACHE_CHECK([for nl_langinfo and CODESET], bash_cv_langinfo_codeset, +[AC_TRY_LINK( +[#include ], +[char* cs = nl_langinfo(CODESET);], +bash_cv_langinfo_codeset=yes, bash_cv_langinfo_codeset=no)]) +if test $bash_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET) +fi + +]) + +dnl need: prefix exec_prefix libdir includedir CC TERMCAP_LIB +dnl require: +dnl AC_PROG_CC +dnl BASH_CHECK_LIB_TERMCAP + +AC_DEFUN(RL_LIB_READLINE_VERSION, +[ +AC_REQUIRE([BASH_CHECK_LIB_TERMCAP]) + +AC_MSG_CHECKING([version of installed readline library]) + +# What a pain in the ass this is. + +# save cpp and ld options +_save_CFLAGS="$CFLAGS" +_save_LDFLAGS="$LDFLAGS" +_save_LIBS="$LIBS" + +# Don't set ac_cv_rl_prefix if the caller has already assigned a value. This +# allows the caller to do something like $_rl_prefix=$withval if the user +# specifies --with-installed-readline=PREFIX as an argument to configure + +if test -z "$ac_cv_rl_prefix"; then +test "x$prefix" = xNONE && ac_cv_rl_prefix=$ac_default_prefix || ac_cv_rl_prefix=${prefix} +fi + +eval ac_cv_rl_includedir=${ac_cv_rl_prefix}/include +eval ac_cv_rl_libdir=${ac_cv_rl_prefix}/lib + +LIBS="$LIBS -lreadline ${TERMCAP_LIB}" +CFLAGS="$CFLAGS -I${ac_cv_rl_includedir}" +LDFLAGS="$LDFLAGS -L${ac_cv_rl_libdir}" + +AC_TRY_RUN([ +#include +#include + +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"); + fclose(fp); + exit(0); +} +], +ac_cv_rl_version=`cat conftest.rlv`, +ac_cv_rl_version='0.0', +ac_cv_rl_version='4.2') + +CFLAGS="$_save_CFLAGS" +LDFLAGS="$_save_LDFLAGS" +LIBS="$_save_LIBS" + +RL_MAJOR=0 +RL_MINOR=0 + +# ( +case "$ac_cv_rl_version" in +2*|3*|4*|5*|6*|7*|8*|9*) + RL_MAJOR=`echo $ac_cv_rl_version | sed 's:\..*$::'` + RL_MINOR=`echo $ac_cv_rl_version | sed -e 's:^.*\.::' -e 's:[[a-zA-Z]]*$::'` + ;; +esac + +# ((( +case $RL_MAJOR in +[[0-9][0-9]]) _RL_MAJOR=$RL_MAJOR ;; +[[0-9]]) _RL_MAJOR=0$RL_MAJOR ;; +*) _RL_MAJOR=00 ;; +esac + +# ((( +case $RL_MINOR in +[[0-9][0-9]]) _RL_MINOR=$RL_MINOR ;; +[[0-9]]) _RL_MINOR=0$RL_MINOR ;; +*) _RL_MINOR=00 ;; +esac + +RL_VERSION="0x${_RL_MAJOR}${_RL_MINOR}" + +# Readline versions greater than 4.2 have these defines in readline.h + +if test $ac_cv_rl_version = '0.0' ; then + AC_MSG_WARN([Could not test version of installed readline library.]) +elif test $RL_MAJOR -gt 4 || { test $RL_MAJOR = 4 && test $RL_MINOR -gt 2 ; } ; then + # set these for use by the caller + RL_PREFIX=$ac_cv_rl_prefix + RL_LIBDIR=$ac_cv_rl_libdir + RL_INCLUDEDIR=$ac_cv_rl_includedir + AC_MSG_RESULT($ac_cv_rl_version) +else + +AC_DEFINE_UNQUOTED(RL_READLINE_VERSION, $RL_VERSION, [encoded version of the installed readline library]) +AC_DEFINE_UNQUOTED(RL_VERSION_MAJOR, $RL_MAJOR, [major version of installed readline library]) +AC_DEFINE_UNQUOTED(RL_VERSION_MINOR, $RL_MINOR, [minor version of installed readline library]) + +AC_SUBST(RL_VERSION) +AC_SUBST(RL_MAJOR) +AC_SUBST(RL_MINOR) + +# set these for use by the caller +RL_PREFIX=$ac_cv_rl_prefix +RL_LIBDIR=$ac_cv_rl_libdir +RL_INCLUDEDIR=$ac_cv_rl_includedir + +AC_MSG_RESULT($ac_cv_rl_version) + +fi +]) diff --git a/readline-4.3/ansi_stdlib.h b/readline-4.3/ansi_stdlib.h new file mode 100644 index 0000000..db13cd2 --- /dev/null +++ b/readline-4.3/ansi_stdlib.h @@ -0,0 +1,54 @@ +/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */ +/* A minimal stdlib.h containing extern declarations for those functions + that bash uses. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_STDLIB_H_) +#define _STDLIB_H_ 1 + +/* String conversion functions. */ +extern int atoi (); + +extern double atof (); +extern double strtod (); + +/* Memory allocation functions. */ +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +extern PTR_T malloc (); +extern PTR_T realloc (); +extern void free (); + +/* Other miscellaneous functions. */ +extern void abort (); +extern void exit (); +extern char *getenv (); +extern void qsort (); + +#endif /* _STDLIB_H */ diff --git a/readline-4.3/bind.c b/readline-4.3/bind.c new file mode 100644 index 0000000..65ef401 --- /dev/null +++ b/readline-4.3/bind.c @@ -0,0 +1,2150 @@ +/* bind.c -- key binding and startup file support for the readline library. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "posixstat.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +/* Variables exported by this file. */ +Keymap rl_binding_keymap; + +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 substring_member_of_array PARAMS((char *, const char **)); + +static int currently_reading_init_file; + +/* used only in this file */ +static int _rl_prefer_visible_bell = 1; + +/* **************************************************************** */ +/* */ +/* Binding keys */ +/* */ +/* **************************************************************** */ + +/* rl_add_defun (char *name, rl_command_func_t *function, int key) + Add NAME to the list of named functions. Make FUNCTION be the function + that gets called. If KEY is not -1, then bind it. */ +int +rl_add_defun (name, function, key) + const char *name; + rl_command_func_t *function; + int key; +{ + if (key != -1) + rl_bind_key (key, function); + rl_add_funmap_entry (name, function); + return 0; +} + +/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ +int +rl_bind_key (key, function) + int key; + rl_command_func_t *function; +{ + if (key < 0) + return (key); + + if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + { + if (_rl_keymap[ESC].type == ISKMAP) + { + Keymap escmap; + + escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); + key = UNMETA (key); + escmap[key].type = ISFUNC; + escmap[key].function = function; + return (0); + } + return (key); + } + + _rl_keymap[key].type = ISFUNC; + _rl_keymap[key].function = function; + rl_binding_keymap = _rl_keymap; + return (0); +} + +/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid + KEY. */ +int +rl_bind_key_in_map (key, function, map) + int key; + rl_command_func_t *function; + Keymap map; +{ + int result; + Keymap oldmap; + + oldmap = _rl_keymap; + _rl_keymap = map; + result = rl_bind_key (key, function); + _rl_keymap = oldmap; + return (result); +} + +/* Make KEY do nothing in the currently selected keymap. + Returns non-zero in case of error. */ +int +rl_unbind_key (key) + int key; +{ + return (rl_bind_key (key, (rl_command_func_t *)NULL)); +} + +/* Make KEY do nothing in MAP. + Returns non-zero in case of error. */ +int +rl_unbind_key_in_map (key, map) + int key; + Keymap map; +{ + return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map)); +} + +/* Unbind all keys bound to FUNCTION in MAP. */ +int +rl_unbind_function_in_map (func, map) + rl_command_func_t *func; + Keymap map; +{ + register int i, rval; + + for (i = rval = 0; i < KEYMAP_SIZE; i++) + { + if (map[i].type == ISFUNC && map[i].function == func) + { + map[i].function = (rl_command_func_t *)NULL; + rval = 1; + } + } + return rval; +} + +int +rl_unbind_command_in_map (command, map) + const char *command; + Keymap map; +{ + rl_command_func_t *func; + + func = rl_named_function (command); + if (func == 0) + return 0; + return (rl_unbind_function_in_map (func, map)); +} + +/* 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_set_key (keyseq, function, map) + const char *keyseq; + rl_command_func_t *function; + Keymap map; +{ + return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); +} + +/* 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. */ +int +rl_macro_bind (keyseq, macro, map) + const char *keyseq, *macro; + Keymap map; +{ + char *macro_keys; + int macro_keys_len; + + macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); + + if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) + { + free (macro_keys); + return -1; + } + rl_generic_bind (ISMACR, keyseq, macro_keys, map); + return 0; +} + +/* Bind the key sequence represented by the string KEYSEQ to + the arbitrary pointer DATA. TYPE says what kind of data is + pointed to by DATA, right now this can be a function (ISFUNC), + a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps + as necessary. The initial place to do bindings is in MAP. */ +int +rl_generic_bind (type, keyseq, data, map) + int type; + const char *keyseq; + char *data; + Keymap map; +{ + char *keys; + int keys_len; + register int i; + KEYMAP_ENTRY k; + + k.function = 0; + + /* If no keys to bind to, exit right away. */ + if (!keyseq || !*keyseq) + { + if (type == ISMACR) + free (data); + return -1; + } + + keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); + + /* Translate the ASCII representation of KEYSEQ into an array of + characters. Stuff the characters into KEYS, and the length of + KEYS into KEYS_LEN. */ + if (rl_translate_keyseq (keyseq, keys, &keys_len)) + { + free (keys); + return -1; + } + + /* Bind keys, making new keymaps as necessary. */ + for (i = 0; i < keys_len; i++) + { + unsigned char uc = keys[i]; + int ic; + + ic = uc; + if (ic < 0 || ic >= KEYMAP_SIZE) + return -1; + + if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic)) + { + ic = UNMETA (ic); + if (map[ESC].type == ISKMAP) + map = FUNCTION_TO_KEYMAP (map, ESC); + } + + if ((i + 1) < keys_len) + { + if (map[ic].type != ISKMAP) + { + /* We allow subsequences of keys. If a keymap is being + created that will `shadow' an existing function or macro + key binding, we save that keybinding into the ANYOTHERKEY + index in the new map. The dispatch code will look there + to find the function to execute if the subsequence is not + matched. ANYOTHERKEY was chosen to be greater than + UCHAR_MAX. */ + k = map[ic]; + + map[ic].type = ISKMAP; + map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); + } + map = FUNCTION_TO_KEYMAP (map, ic); + /* The dispatch code will return this function if no matching + key sequence is found in the keymap. This (with a little + help from the dispatch code in readline.c) allows `a' to be + mapped to something, `abc' to be mapped to something else, + and the function bound to `a' to be executed when the user + types `abx', leaving `bx' in the input queue. */ + if (k.function /* && k.type == ISFUNC */) + { + map[ANYOTHERKEY] = k; + k.function = 0; + } + } + else + { + if (map[ic].type == ISMACR) + free ((char *)map[ic].function); + else if (map[ic].type == ISKMAP) + { + map = FUNCTION_TO_KEYMAP (map, ic); + ic = ANYOTHERKEY; + } + + map[ic].function = KEYMAP_TO_FUNCTION (data); + map[ic].type = type; + } + + rl_binding_keymap = map; + } + free (keys); + return 0; +} + +/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, + an array of characters. LEN gets the final length of ARRAY. Return + non-zero if there was an error parsing SEQ. */ +int +rl_translate_keyseq (seq, array, len) + const char *seq; + char *array; + int *len; +{ + register int i, c, l, temp; + + for (i = l = 0; c = seq[i]; i++) + { + if (c == '\\') + { + c = seq[++i]; + + if (c == 0) + break; + + /* Handle \C- and \M- prefixes. */ + if ((c == 'C' || c == 'M') && seq[i + 1] == '-') + { + /* Handle special case of backwards define. */ + if (strncmp (&seq[i], "C-\\M-", 5) == 0) + { + array[l++] = ESC; /* ESC is meta-prefix */ + i += 5; + array[l++] = CTRL (_rl_to_upper (seq[i])); + if (seq[i] == '\0') + i--; + } + else if (c == 'M') + { + i++; + array[l++] = ESC; /* ESC is meta-prefix */ + } + else if (c == 'C') + { + i += 2; + /* Special hack for C-?... */ + array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); + } + continue; + } + + /* Translate other backslash-escaped characters. These are the + same escape sequences that bash's `echo' and `printf' builtins + handle, with the addition of \d -> RUBOUT. A backslash + preceding a character that is not special is stripped. */ + switch (c) + { + case 'a': + array[l++] = '\007'; + break; + case 'b': + array[l++] = '\b'; + break; + case 'd': + array[l++] = RUBOUT; /* readline-specific */ + break; + case 'e': + array[l++] = ESC; + break; + case 'f': + array[l++] = '\f'; + break; + case 'n': + array[l++] = NEWLINE; + break; + case 'r': + array[l++] = RETURN; + break; + case 't': + array[l++] = TAB; + break; + case 'v': + array[l++] = 0x0B; + break; + case '\\': + array[l++] = '\\'; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + i++; + for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++) + c = (c * 8) + OCTVALUE (seq[i]); + i--; /* auto-increment in for loop */ + array[l++] = c & largest_char; + break; + case 'x': + i++; + for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++) + c = (c * 16) + HEXVALUE (seq[i]); + if (temp == 2) + c = 'x'; + i--; /* auto-increment in for loop */ + array[l++] = c & largest_char; + break; + default: /* backslashes before non-special chars just add the char */ + array[l++] = c; + break; /* the backslash is stripped */ + } + continue; + } + + array[l++] = c; + } + + *len = l; + array[l] = '\0'; + return (0); +} + +char * +rl_untranslate_keyseq (seq) + int seq; +{ + static char kseq[16]; + int i, c; + + i = 0; + c = seq; + if (META_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'M'; + kseq[i++] = '-'; + c = UNMETA (c); + } + else if (CTRL_CHAR (c)) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + else if (c == RUBOUT) + { + kseq[i++] = '\\'; + kseq[i++] = 'C'; + kseq[i++] = '-'; + c = '?'; + } + + if (c == ESC) + { + kseq[i++] = '\\'; + c = 'e'; + } + else if (c == '\\' || c == '"') + { + kseq[i++] = '\\'; + } + + kseq[i++] = (unsigned char) c; + kseq[i] = '\0'; + return kseq; +} + +static char * +_rl_untranslate_macro_value (seq) + char *seq; +{ + char *ret, *r, *s; + int c; + + r = ret = (char *)xmalloc (7 * strlen (seq) + 1); + for (s = seq; *s; s++) + { + c = *s; + if (META_CHAR (c)) + { + *r++ = '\\'; + *r++ = 'M'; + *r++ = '-'; + c = UNMETA (c); + } + else if (CTRL_CHAR (c) && c != ESC) + { + *r++ = '\\'; + *r++ = 'C'; + *r++ = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + else if (c == RUBOUT) + { + *r++ = '\\'; + *r++ = 'C'; + *r++ = '-'; + c = '?'; + } + + if (c == ESC) + { + *r++ = '\\'; + c = 'e'; + } + else if (c == '\\' || c == '"') + *r++ = '\\'; + + *r++ = (unsigned char)c; + } + *r = '\0'; + return ret; +} + +/* Return a pointer to the function that STRING represents. + If STRING doesn't have a matching function, then a NULL pointer + is returned. */ +rl_command_func_t * +rl_named_function (string) + const char *string; +{ + register int i; + + rl_initialize_funmap (); + + for (i = 0; funmap[i]; i++) + if (_rl_stricmp (funmap[i]->name, string) == 0) + return (funmap[i]->function); + return ((rl_command_func_t *)NULL); +} + +/* Return the function (or macro) definition which would be invoked via + KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is + used. TYPE, if non-NULL, is a pointer to an int which will receive the + type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), + or ISMACR (macro). */ +rl_command_func_t * +rl_function_of_keyseq (keyseq, map, type) + const char *keyseq; + Keymap map; + int *type; +{ + register int i; + + if (!map) + map = _rl_keymap; + + for (i = 0; keyseq && keyseq[i]; i++) + { + unsigned char ic = keyseq[i]; + + if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + { + if (map[ESC].type != ISKMAP) + { + if (type) + *type = map[ESC].type; + + return (map[ESC].function); + } + else + { + map = FUNCTION_TO_KEYMAP (map, ESC); + ic = UNMETA (ic); + } + } + + if (map[ic].type == ISKMAP) + { + /* If this is the last key in the key sequence, return the + map. */ + if (!keyseq[i + 1]) + { + if (type) + *type = ISKMAP; + + return (map[ic].function); + } + else + map = FUNCTION_TO_KEYMAP (map, ic); + } + else + { + if (type) + *type = map[ic].type; + + return (map[ic].function); + } + } + return ((rl_command_func_t *) NULL); +} + +/* The last key bindings file read. */ +static char *last_readline_init_file = (char *)NULL; + +/* The file we're currently reading key bindings from. */ +static const char *current_readline_init_file; +static int current_readline_init_include_level; +static int current_readline_init_lineno; + +/* Read FILENAME into a locally-allocated buffer and return the buffer. + The size of the buffer is returned in *SIZEP. Returns NULL if any + errors were encountered. */ +static char * +_rl_read_file (filename, sizep) + char *filename; + size_t *sizep; +{ + struct stat finfo; + size_t file_size; + char *buffer; + int i, file; + + if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) + return ((char *)NULL); + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + if (file >= 0) + close (file); +#if defined (EFBIG) + errno = EFBIG; +#endif + return ((char *)NULL); + } + + /* Read the file into BUFFER. */ + buffer = (char *)xmalloc (file_size + 1); + i = read (file, buffer, file_size); + close (file); + + if (i < 0) + { + free (buffer); + return ((char *)NULL); + } + + buffer[i] = '\0'; + if (sizep) + *sizep = i; + + return (buffer); +} + +/* Re-read the current keybindings file. */ +int +rl_re_read_init_file (count, ignore) + int count, ignore; +{ + int r; + r = rl_read_init_file ((const char *)NULL); + rl_set_keymap_from_edit_mode (); + return r; +} + +/* Do key bindings from a file. If FILENAME is NULL it defaults + to the first non-null filename from this list: + 1. the filename used for the previous call + 2. the value of the shell variable `INPUTRC' + 3. ~/.inputrc + If the file existed and could be opened and read, 0 is returned, + otherwise errno is returned. */ +int +rl_read_init_file (filename) + const char *filename; +{ + /* Default the filename. */ + if (filename == 0) + { + filename = last_readline_init_file; + if (filename == 0) + filename = sh_get_env_value ("INPUTRC"); + if (filename == 0) + filename = DEFAULT_INPUTRC; + } + + if (*filename == 0) + filename = DEFAULT_INPUTRC; + +#if defined (__MSDOS__) + if (_rl_read_init_file (filename, 0) == 0) + return 0; + filename = "~/_inputrc"; +#endif + return (_rl_read_init_file (filename, 0)); +} + +static int +_rl_read_init_file (filename, include_level) + const char *filename; + int include_level; +{ + register int i; + char *buffer, *openname, *line, *end; + size_t file_size; + + current_readline_init_file = filename; + current_readline_init_include_level = include_level; + + openname = tilde_expand (filename); + buffer = _rl_read_file (openname, &file_size); + free (openname); + + if (buffer == 0) + return (errno); + + if (include_level == 0 && filename != last_readline_init_file) + { + FREE (last_readline_init_file); + last_readline_init_file = savestring (filename); + } + + currently_reading_init_file = 1; + + /* Loop over the lines in the file. Lines that start with `#' are + comments; all other lines are commands for readline initialization. */ + current_readline_init_lineno = 1; + line = buffer; + end = buffer + file_size; + while (line < end) + { + /* Find the end of this line. */ + for (i = 0; line + i != end && line[i] != '\n'; i++); + +#if defined (__CYGWIN__) + /* ``Be liberal in what you accept.'' */ + if (line[i] == '\n' && line[i-1] == '\r') + line[i - 1] = '\0'; +#endif + + /* Mark end of line. */ + line[i] = '\0'; + + /* Skip leading whitespace. */ + while (*line && whitespace (*line)) + { + line++; + i--; + } + + /* If the line is not a comment, then parse it. */ + if (*line && *line != '#') + rl_parse_and_bind (line); + + /* Move to the next line. */ + line += i + 1; + current_readline_init_lineno++; + } + + free (buffer); + currently_reading_init_file = 0; + return (0); +} + +static void +_rl_init_file_error (msg) + const char *msg; +{ + if (currently_reading_init_file) + fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file, + current_readline_init_lineno, msg); + else + fprintf (stderr, "readline: %s\n", msg); +} + +/* **************************************************************** */ +/* */ +/* Parser Directives */ +/* */ +/* **************************************************************** */ + +typedef int _rl_parser_func_t PARAMS((char *)); + +/* Things that mean `Control'. */ +const char *_rl_possible_control_prefixes[] = { + "Control-", "C-", "CTRL-", (const char *)NULL +}; + +const char *_rl_possible_meta_prefixes[] = { + "Meta", "M-", (const char *)NULL +}; + +/* Conditionals. */ + +/* Calling programs set this to have their argv[0]. */ +const char *rl_readline_name = "other"; + +/* Stack of previous values of parsing_conditionalized_out. */ +static unsigned char *if_stack = (unsigned char *)NULL; +static int if_stack_depth; +static int if_stack_size; + +/* Push _rl_parsing_conditionalized_out, and set parser state based + on ARGS. */ +static int +parser_if (args) + char *args; +{ + register int i; + + /* Push parser state. */ + if (if_stack_depth + 1 >= if_stack_size) + { + if (!if_stack) + if_stack = (unsigned char *)xmalloc (if_stack_size = 20); + else + if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); + } + if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; + + /* If parsing is turned off, then nothing can turn it back on except + for finding the matching endif. In that case, return right now. */ + if (_rl_parsing_conditionalized_out) + return 0; + + /* Isolate first argument. */ + for (i = 0; args[i] && !whitespace (args[i]); i++); + + if (args[i]) + args[i++] = '\0'; + + /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this + isn't term=foo, or mode=emacs, then check to see if the first + word in ARGS is the same as the value stored in rl_readline_name. */ + if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) + { + char *tem, *tname; + + /* Terminals like "aaa-60" are equivalent to "aaa". */ + tname = savestring (rl_terminal_name); + tem = strchr (tname, '-'); + if (tem) + *tem = '\0'; + + /* Test the `long' and `short' forms of the terminal name so that + if someone has a `sun-cmd' and does not want to have bindings + that will be executed if the terminal is a `sun', they can put + `$if term=sun-cmd' into their .inputrc. */ + _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && + _rl_stricmp (args + 5, rl_terminal_name); + free (tname); + } +#if defined (VI_MODE) + else if (_rl_strnicmp (args, "mode=", 5) == 0) + { + int mode; + + if (_rl_stricmp (args + 5, "emacs") == 0) + mode = emacs_mode; + else if (_rl_stricmp (args + 5, "vi") == 0) + mode = vi_mode; + else + mode = no_mode; + + _rl_parsing_conditionalized_out = mode != rl_editing_mode; + } +#endif /* VI_MODE */ + /* Check to see if the first word in ARGS is the same as the + value stored in rl_readline_name. */ + else if (_rl_stricmp (args, rl_readline_name) == 0) + _rl_parsing_conditionalized_out = 0; + else + _rl_parsing_conditionalized_out = 1; + return 0; +} + +/* Invert the current parser state if there is anything on the stack. */ +static int +parser_else (args) + char *args; +{ + register int i; + + if (if_stack_depth == 0) + { + _rl_init_file_error ("$else found without matching $if"); + return 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++) + if (if_stack[i] == 1) + return 0; + + /* Invert the state of parsing if at top level. */ + _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; + return 0; +} + +/* Terminate a conditional, popping the value of + _rl_parsing_conditionalized_out from the stack. */ +static int +parser_endif (args) + char *args; +{ + if (if_stack_depth) + _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; + else + _rl_init_file_error ("$endif without matching $if"); + return 0; +} + +static int +parser_include (args) + char *args; +{ + const char *old_init_file; + char *e; + int old_line_number, old_include_level, r; + + if (_rl_parsing_conditionalized_out) + return (0); + + old_init_file = current_readline_init_file; + old_line_number = current_readline_init_lineno; + old_include_level = current_readline_init_include_level; + + e = strchr (args, '\n'); + if (e) + *e = '\0'; + r = _rl_read_init_file ((const char *)args, old_include_level + 1); + + current_readline_init_file = old_init_file; + current_readline_init_lineno = old_line_number; + current_readline_init_include_level = old_include_level; + + return r; +} + +/* Associate textual names with actual functions. */ +static struct { + const char *name; + _rl_parser_func_t *function; +} parser_directives [] = { + { "if", parser_if }, + { "endif", parser_endif }, + { "else", parser_else }, + { "include", parser_include }, + { (char *)0x0, (_rl_parser_func_t *)0x0 } +}; + +/* Handle a parser directive. STATEMENT is the line of the directive + without any leading `$'. */ +static int +handle_parser_directive (statement) + char *statement; +{ + register int i; + char *directive, *args; + + /* Isolate the actual directive. */ + + /* Skip whitespace. */ + for (i = 0; whitespace (statement[i]); i++); + + directive = &statement[i]; + + for (; statement[i] && !whitespace (statement[i]); i++); + + if (statement[i]) + statement[i++] = '\0'; + + for (; statement[i] && whitespace (statement[i]); i++); + + args = &statement[i]; + + /* Lookup the command, and act on it. */ + for (i = 0; parser_directives[i].name; i++) + if (_rl_stricmp (directive, parser_directives[i].name) == 0) + { + (*parser_directives[i].function) (args); + return (0); + } + + /* display an error message about the unknown parser directive */ + _rl_init_file_error ("unknown parser directive"); + return (1); +} + +/* Read the binding command from STRING and perform it. + A key binding command looks like: Keyname: function-name\0, + a variable binding command looks like: set variable value. + A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ +int +rl_parse_and_bind (string) + char *string; +{ + char *funname, *kname; + register int c, i; + int key, equivalency; + + while (string && whitespace (*string)) + string++; + + if (!string || !*string || *string == '#') + return 0; + + /* If this is a parser directive, act on it. */ + if (*string == '$') + { + handle_parser_directive (&string[1]); + return 0; + } + + /* If we aren't supposed to be parsing right now, then we're done. */ + if (_rl_parsing_conditionalized_out) + return 0; + + i = 0; + /* If this keyname is a complex key expression surrounded by quotes, + advance to after the matching close quote. This code allows the + backslash to quote characters in the key expression. */ + if (*string == '"') + { + int passc = 0; + + for (i = 1; c = string[i]; i++) + { + if (passc) + { + passc = 0; + continue; + } + + if (c == '\\') + { + passc++; + continue; + } + + if (c == '"') + break; + } + /* If we didn't find a closing quote, abort the line. */ + if (string[i] == '\0') + { + _rl_init_file_error ("no closing `\"' in key binding"); + return 1; + } + } + + /* Advance to the colon (:) or whitespace which separates the two objects. */ + for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); + + equivalency = (c == ':' && string[i + 1] == '='); + + /* Mark the end of the command (or keyname). */ + if (string[i]) + string[i++] = '\0'; + + /* If doing assignment, skip the '=' sign as well. */ + if (equivalency) + string[i++] = '\0'; + + /* If this is a command to set a variable, then do that. */ + if (_rl_stricmp (string, "set") == 0) + { + char *var = string + i; + char *value; + + /* Make VAR point to start of variable name. */ + while (*var && whitespace (*var)) var++; + + /* Make VALUE point to start of value string. */ + value = var; + while (*value && !whitespace (*value)) value++; + if (*value) + *value++ = '\0'; + while (*value && whitespace (*value)) value++; + + rl_variable_bind (var, value); + return 0; + } + + /* Skip any whitespace between keyname and funname. */ + for (; string[i] && whitespace (string[i]); i++); + funname = &string[i]; + + /* Now isolate funname. + For straight function names just look for whitespace, since + that will signify the end of the string. But this could be a + macro definition. In that case, the string is quoted, so skip + to the matching delimiter. We allow the backslash to quote the + delimiter characters in the macro body. */ + /* This code exists to allow whitespace in macro expansions, which + would otherwise be gobbled up by the next `for' loop.*/ + /* XXX - it may be desirable to allow backslash quoting only if " is + the quoted string delimiter, like the shell. */ + if (*funname == '\'' || *funname == '"') + { + int delimiter = string[i++], passc; + + for (passc = 0; c = string[i]; i++) + { + if (passc) + { + passc = 0; + continue; + } + + if (c == '\\') + { + passc = 1; + continue; + } + + if (c == delimiter) + break; + } + if (c) + i++; + } + + /* Advance to the end of the string. */ + for (; string[i] && !whitespace (string[i]); i++); + + /* No extra whitespace at the end of the string. */ + string[i] = '\0'; + + /* Handle equivalency bindings here. Make the left-hand side be exactly + whatever the right-hand evaluates to, including keymaps. */ + if (equivalency) + { + return 0; + } + + /* If this is a new-style key-binding, then do the binding with + rl_set_key (). Otherwise, let the older code deal with it. */ + if (*string == '"') + { + char *seq; + register int j, k, passc; + + seq = (char *)xmalloc (1 + strlen (string)); + for (j = 1, k = passc = 0; string[j]; j++) + { + /* Allow backslash to quote characters, but leave them in place. + This allows a string to end with a backslash quoting another + backslash, or with a backslash quoting a double quote. The + backslashes are left in place for rl_translate_keyseq (). */ + if (passc || (string[j] == '\\')) + { + seq[k++] = string[j]; + passc = !passc; + continue; + } + + if (string[j] == '"') + break; + + seq[k++] = string[j]; + } + seq[k] = '\0'; + + /* Binding macro? */ + if (*funname == '\'' || *funname == '"') + { + j = strlen (funname); + + /* Remove the delimiting quotes from each end of FUNNAME. */ + if (j && funname[j - 1] == *funname) + funname[j - 1] = '\0'; + + rl_macro_bind (seq, &funname[1], _rl_keymap); + } + else + rl_set_key (seq, rl_named_function (funname), _rl_keymap); + + free (seq); + return 0; + } + + /* Get the actual character we want to deal with. */ + kname = strrchr (string, '-'); + if (!kname) + kname = string; + else + kname++; + + key = glean_key_from_name (kname); + + /* Add in control and meta bits. */ + if (substring_member_of_array (string, _rl_possible_control_prefixes)) + key = CTRL (_rl_to_upper (key)); + + if (substring_member_of_array (string, _rl_possible_meta_prefixes)) + key = META (key); + + /* Temporary. Handle old-style keyname with macro-binding. */ + if (*funname == '\'' || *funname == '"') + { + char useq[2]; + int fl = strlen (funname); + + useq[0] = key; useq[1] = '\0'; + if (fl && funname[fl - 1] == *funname) + funname[fl - 1] = '\0'; + + rl_macro_bind (useq, &funname[1], _rl_keymap); + } +#if defined (PREFIX_META_HACK) + /* Ugly, but working hack to keep prefix-meta around. */ + else if (_rl_stricmp (funname, "prefix-meta") == 0) + { + char seq[2]; + + seq[0] = key; + seq[1] = '\0'; + rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap); + } +#endif /* PREFIX_META_HACK */ + else + rl_bind_key (key, rl_named_function (funname)); + return 0; +} + +/* Simple structure for boolean readline variables (i.e., those that can + have one of two values; either "On" or 1 for truth, or "Off" or 0 for + false. */ + +#define V_SPECIAL 0x1 + +static struct { + const char *name; + int *value; + int flags; +} boolean_varlist [] = { + { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL }, + { "byte-oriented", &rl_byte_oriented, 0 }, + { "completion-ignore-case", &_rl_completion_case_fold, 0 }, + { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 }, + { "disable-completion", &rl_inhibit_completion, 0 }, + { "enable-keypad", &_rl_enable_keypad, 0 }, + { "expand-tilde", &rl_complete_with_tilde_expansion, 0 }, + { "history-preserve-point", &_rl_history_preserve_point, 0 }, + { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 }, + { "input-meta", &_rl_meta_flag, 0 }, + { "mark-directories", &_rl_complete_mark_directories, 0 }, + { "mark-modified-lines", &_rl_mark_modified_lines, 0 }, + { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 }, + { "match-hidden-files", &_rl_match_hidden_files, 0 }, + { "meta-flag", &_rl_meta_flag, 0 }, + { "output-meta", &_rl_output_meta_chars, 0 }, + { "page-completions", &_rl_page_completions, 0 }, + { "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 }, +#if defined (VISIBLE_STATS) + { "visible-stats", &rl_visible_stats, 0 }, +#endif /* VISIBLE_STATS */ + { (char *)NULL, (int *)NULL } +}; + +static int +find_boolean_var (name) + const char *name; +{ + register int i; + + for (i = 0; boolean_varlist[i].name; i++) + if (_rl_stricmp (name, boolean_varlist[i].name) == 0) + return i; + return -1; +} + +/* Hooks for handling special boolean variables, where a + function needs to be called or another variable needs + to be changed when they're changed. */ +static void +hack_special_boolean_var (i) + int i; +{ + const char *name; + + name = boolean_varlist[i].name; + + if (_rl_stricmp (name, "blink-matching-paren") == 0) + _rl_enable_paren_matching (rl_blink_matching_paren); + else if (_rl_stricmp (name, "prefer-visible-bell") == 0) + { + if (_rl_prefer_visible_bell) + _rl_bell_preference = VISIBLE_BELL; + else + _rl_bell_preference = AUDIBLE_BELL; + } +} + +typedef int _rl_sv_func_t PARAMS((const char *)); + +/* These *must* correspond to the array indices for the appropriate + string variable. (Though they're not used right now.) */ +#define V_BELLSTYLE 0 +#define V_COMBEGIN 1 +#define V_EDITMODE 2 +#define V_ISRCHTERM 3 +#define V_KEYMAP 4 + +#define V_STRING 1 +#define V_INT 2 + +/* Forward declarations */ +static int sv_bell_style PARAMS((const char *)); +static int sv_combegin PARAMS((const char *)); +static int sv_compquery PARAMS((const char *)); +static int sv_editmode PARAMS((const char *)); +static int sv_isrchterm PARAMS((const char *)); +static int sv_keymap PARAMS((const char *)); + +static struct { + const char *name; + int flags; + _rl_sv_func_t *set_func; +} string_varlist[] = { + { "bell-style", V_STRING, sv_bell_style }, + { "comment-begin", V_STRING, sv_combegin }, + { "completion-query-items", V_INT, sv_compquery }, + { "editing-mode", V_STRING, sv_editmode }, + { "isearch-terminators", V_STRING, sv_isrchterm }, + { "keymap", V_STRING, sv_keymap }, + { (char *)NULL, 0 } +}; + +static int +find_string_var (name) + const char *name; +{ + register int i; + + for (i = 0; string_varlist[i].name; i++) + if (_rl_stricmp (name, string_varlist[i].name) == 0) + return i; + return -1; +} + +/* A boolean value that can appear in a `set variable' command is true if + the value is null or empty, `on' (case-insenstive), or "1". Any other + values result in 0 (false). */ +static int +bool_to_int (value) + char *value; +{ + return (value == 0 || *value == '\0' || + (_rl_stricmp (value, "on") == 0) || + (value[0] == '1' && value[1] == '\0')); +} + +int +rl_variable_bind (name, value) + const char *name, *value; +{ + register int i; + int v; + + /* Check for simple variables first. */ + i = find_boolean_var (name); + if (i >= 0) + { + *boolean_varlist[i].value = bool_to_int (value); + if (boolean_varlist[i].flags & V_SPECIAL) + hack_special_boolean_var (i); + return 0; + } + + i = find_string_var (name); + + /* For the time being, unknown variable names or string names without a + handler function are simply ignored. */ + if (i < 0 || string_varlist[i].set_func == 0) + return 0; + + v = (*string_varlist[i].set_func) (value); + return v; +} + +static int +sv_editmode (value) + const char *value; +{ + if (_rl_strnicmp (value, "vi", 2) == 0) + { +#if defined (VI_MODE) + _rl_keymap = vi_insertion_keymap; + rl_editing_mode = vi_mode; +#endif /* VI_MODE */ + return 0; + } + else if (_rl_strnicmp (value, "emacs", 5) == 0) + { + _rl_keymap = emacs_standard_keymap; + rl_editing_mode = emacs_mode; + return 0; + } + return 1; +} + +static int +sv_combegin (value) + const char *value; +{ + if (value && *value) + { + FREE (_rl_comment_begin); + _rl_comment_begin = savestring (value); + return 0; + } + return 1; +} + +static int +sv_compquery (value) + const char *value; +{ + int nval = 100; + + if (value && *value) + { + nval = atoi (value); + if (nval < 0) + nval = 0; + } + rl_completion_query_items = nval; + return 0; +} + +static int +sv_keymap (value) + const char *value; +{ + Keymap kmap; + + kmap = rl_get_keymap_by_name (value); + if (kmap) + { + rl_set_keymap (kmap); + return 0; + } + return 1; +} + +static int +sv_bell_style (value) + const char *value; +{ + if (value == 0 || *value == '\0') + _rl_bell_preference = AUDIBLE_BELL; + else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0) + _rl_bell_preference = NO_BELL; + else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0) + _rl_bell_preference = AUDIBLE_BELL; + else if (_rl_stricmp (value, "visible") == 0) + _rl_bell_preference = VISIBLE_BELL; + else + return 1; + return 0; +} + +static int +sv_isrchterm (value) + const char *value; +{ + int beg, end, delim; + char *v; + + if (value == 0) + return 1; + + /* Isolate the value and translate it into a character string. */ + v = savestring (value); + FREE (_rl_isearch_terminators); + if (v[0] == '"' || v[0] == '\'') + { + delim = v[0]; + for (beg = end = 1; v[end] && v[end] != delim; end++) + ; + } + else + { + for (beg = end = 0; whitespace (v[end]) == 0; end++) + ; + } + + v[end] = '\0'; + + /* The value starts at v + beg. Translate it into a character string. */ + _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1); + rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end); + _rl_isearch_terminators[end] = '\0'; + + free (v); + return 0; +} + +/* Return the character which matches NAME. + For example, `Space' returns ' '. */ + +typedef struct { + const char *name; + int value; +} assoc_list; + +static assoc_list name_key_alist[] = { + { "DEL", 0x7f }, + { "ESC", '\033' }, + { "Escape", '\033' }, + { "LFD", '\n' }, + { "Newline", '\n' }, + { "RET", '\r' }, + { "Return", '\r' }, + { "Rubout", 0x7f }, + { "SPC", ' ' }, + { "Space", ' ' }, + { "Tab", 0x09 }, + { (char *)0x0, 0 } +}; + +static int +glean_key_from_name (name) + char *name; +{ + register int i; + + for (i = 0; name_key_alist[i].name; i++) + if (_rl_stricmp (name, name_key_alist[i].name) == 0) + return (name_key_alist[i].value); + + return (*(unsigned char *)name); /* XXX was return (*name) */ +} + +/* Auxiliary functions to manage keymaps. */ +static struct { + const char *name; + Keymap map; +} keymap_names[] = { + { "emacs", emacs_standard_keymap }, + { "emacs-standard", emacs_standard_keymap }, + { "emacs-meta", emacs_meta_keymap }, + { "emacs-ctlx", emacs_ctlx_keymap }, +#if defined (VI_MODE) + { "vi", vi_movement_keymap }, + { "vi-move", vi_movement_keymap }, + { "vi-command", vi_movement_keymap }, + { "vi-insert", vi_insertion_keymap }, +#endif /* VI_MODE */ + { (char *)0x0, (Keymap)0x0 } +}; + +Keymap +rl_get_keymap_by_name (name) + const char *name; +{ + register int i; + + for (i = 0; keymap_names[i].name; i++) + if (_rl_stricmp (name, keymap_names[i].name) == 0) + return (keymap_names[i].map); + return ((Keymap) NULL); +} + +char * +rl_get_keymap_name (map) + Keymap map; +{ + register int i; + for (i = 0; keymap_names[i].name; i++) + if (map == keymap_names[i].map) + return ((char *)keymap_names[i].name); + return ((char *)NULL); +} + +void +rl_set_keymap (map) + Keymap map; +{ + if (map) + _rl_keymap = map; +} + +Keymap +rl_get_keymap () +{ + return (_rl_keymap); +} + +void +rl_set_keymap_from_edit_mode () +{ + if (rl_editing_mode == emacs_mode) + _rl_keymap = emacs_standard_keymap; +#if defined (VI_MODE) + else if (rl_editing_mode == vi_mode) + _rl_keymap = vi_insertion_keymap; +#endif /* VI_MODE */ +} + +char * +rl_get_keymap_name_from_edit_mode () +{ + if (rl_editing_mode == emacs_mode) + return "emacs"; +#if defined (VI_MODE) + else if (rl_editing_mode == vi_mode) + return "vi"; +#endif /* VI_MODE */ + else + return "none"; +} + +/* **************************************************************** */ +/* */ +/* Key Binding and Function Information */ +/* */ +/* **************************************************************** */ + +/* 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 (). */ + +/* Print the names of functions known to Readline. */ +void +rl_list_funmap_names () +{ + register int i; + const char **funmap_names; + + funmap_names = rl_funmap_names (); + + if (!funmap_names) + return; + + for (i = 0; funmap_names[i]; i++) + fprintf (rl_outstream, "%s\n", funmap_names[i]); + + free (funmap_names); +} + +static char * +_rl_get_keyname (key) + int key; +{ + char *keyname; + int i, c; + + keyname = (char *)xmalloc (8); + + c = key; + /* Since this is going to be used to write out keysequence-function + pairs for possible inclusion in an inputrc file, we don't want to + do any special meta processing on KEY. */ + +#if 1 + /* XXX - Experimental */ + /* We might want to do this, but the old version of the code did not. */ + + /* If this is an escape character, we don't want to do any more processing. + Just add the special ESC key sequence and return. */ + if (c == ESC) + { + keyname[0] = '\\'; + keyname[1] = 'e'; + keyname[2] = '\0'; + return keyname; + } +#endif + + /* RUBOUT is translated directly into \C-? */ + if (key == RUBOUT) + { + keyname[0] = '\\'; + keyname[1] = 'C'; + keyname[2] = '-'; + keyname[3] = '?'; + keyname[4] = '\0'; + return keyname; + } + + i = 0; + /* Now add special prefixes needed for control characters. This can + potentially change C. */ + if (CTRL_CHAR (c)) + { + keyname[i++] = '\\'; + keyname[i++] = 'C'; + keyname[i++] = '-'; + c = _rl_to_lower (UNCTRL (c)); + } + + /* XXX experimental code. Turn the characters that are not ASCII or + ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237). + This changes C. */ + if (c >= 128 && c <= 159) + { + keyname[i++] = '\\'; + keyname[i++] = '2'; + c -= 128; + keyname[i++] = (c / 8) + '0'; + c = (c % 8) + '0'; + } + + /* Now, if the character needs to be quoted with a backslash, do that. */ + if (c == '\\' || c == '"') + keyname[i++] = '\\'; + + /* Now add the key, terminate the string, and return it. */ + keyname[i++] = (char) c; + keyname[i] = '\0'; + + return keyname; +} + +/* Return a NULL terminated array of strings which represent the key + sequences that are used to invoke FUNCTION in MAP. */ +char ** +rl_invoking_keyseqs_in_map (function, map) + rl_command_func_t *function; + Keymap map; +{ + register int key; + char **result; + int result_index, result_size; + + result = (char **)NULL; + result_index = result_size = 0; + + for (key = 0; key < KEYMAP_SIZE; key++) + { + switch (map[key].type) + { + case ISMACR: + /* Macros match, if, and only if, the pointers are identical. + Thus, they are treated exactly like functions in here. */ + case ISFUNC: + /* If the function in the keymap is the one we are looking for, + then add the current KEY to the list of invoking keys. */ + if (map[key].function == function) + { + char *keyname; + + keyname = _rl_get_keyname (key); + + if (result_index + 2 > result_size) + { + result_size += 10; + result = (char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index++] = keyname; + result[result_index] = (char *)NULL; + } + break; + + case ISKMAP: + { + char **seqs; + register int i; + + /* Find the list of keyseqs in this map which have FUNCTION as + their target. Add the key sequences found to RESULT. */ + if (map[key].function) + seqs = + rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); + else + break; + + if (seqs == 0) + break; + + for (i = 0; seqs[i]; i++) + { + char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); + + if (key == ESC) +#if 0 + sprintf (keyname, "\\e"); +#else + /* XXX - experimental */ + sprintf (keyname, "\\M-"); +#endif + else if (CTRL_CHAR (key)) + sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); + else if (key == RUBOUT) + sprintf (keyname, "\\C-?"); + else if (key == '\\' || key == '"') + { + keyname[0] = '\\'; + keyname[1] = (char) key; + keyname[2] = '\0'; + } + else + { + keyname[0] = (char) key; + keyname[1] = '\0'; + } + + strcat (keyname, seqs[i]); + free (seqs[i]); + + if (result_index + 2 > result_size) + { + result_size += 10; + result = (char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index++] = keyname; + result[result_index] = (char *)NULL; + } + + free (seqs); + } + break; + } + } + return (result); +} + +/* Return a NULL terminated array of strings which represent the key + sequences that can be used to invoke FUNCTION using the current keymap. */ +char ** +rl_invoking_keyseqs (function) + rl_command_func_t *function; +{ + return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); +} + +/* Print all of the functions and their bindings to rl_outstream. If + PRINT_READABLY is non-zero, then print the output in such a way + that it can be read back in. */ +void +rl_function_dumper (print_readably) + int print_readably; +{ + register int i; + const char **names; + const char *name; + + names = rl_funmap_names (); + + fprintf (rl_outstream, "\n"); + + for (i = 0; name = names[i]; i++) + { + rl_command_func_t *function; + char **invokers; + + function = rl_named_function (name); + invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap); + + if (print_readably) + { + if (!invokers) + fprintf (rl_outstream, "# %s (not bound)\n", name); + else + { + register int j; + + for (j = 0; invokers[j]; j++) + { + fprintf (rl_outstream, "\"%s\": %s\n", + invokers[j], name); + free (invokers[j]); + } + + free (invokers); + } + } + else + { + if (!invokers) + fprintf (rl_outstream, "%s is not bound to any keys\n", + name); + else + { + register int j; + + fprintf (rl_outstream, "%s can be found on ", name); + + for (j = 0; invokers[j] && j < 5; j++) + { + fprintf (rl_outstream, "\"%s\"%s", invokers[j], + invokers[j + 1] ? ", " : ".\n"); + } + + if (j == 5 && invokers[j]) + fprintf (rl_outstream, "...\n"); + + for (j = 0; invokers[j]; j++) + free (invokers[j]); + + free (invokers); + } + } + } +} + +/* Print all of the current functions and their bindings to + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_functions (count, key) + int count, key; +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_function_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +static void +_rl_macro_dumper_internal (print_readably, map, prefix) + int print_readably; + Keymap map; + char *prefix; +{ + register int key; + char *keyname, *out; + int prefix_len; + + for (key = 0; key < KEYMAP_SIZE; key++) + { + switch (map[key].type) + { + case ISMACR: + keyname = _rl_get_keyname (key); + out = _rl_untranslate_macro_value ((char *)map[key].function); + + if (print_readably) + fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", + keyname, + out ? out : ""); + else + fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "", + keyname, + out ? out : ""); + free (keyname); + free (out); + break; + case ISFUNC: + break; + case ISKMAP: + prefix_len = prefix ? strlen (prefix) : 0; + if (key == ESC) + { + keyname = (char *)xmalloc (3 + prefix_len); + if (prefix) + strcpy (keyname, prefix); + keyname[prefix_len] = '\\'; + keyname[prefix_len + 1] = 'e'; + keyname[prefix_len + 2] = '\0'; + } + else + { + keyname = _rl_get_keyname (key); + if (prefix) + { + out = (char *)xmalloc (strlen (keyname) + prefix_len + 1); + strcpy (out, prefix); + strcpy (out + prefix_len, keyname); + free (keyname); + keyname = out; + } + } + + _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); + free (keyname); + break; + } + } +} + +void +rl_macro_dumper (print_readably) + int print_readably; +{ + _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); +} + +int +rl_dump_macros (count, key) + int count, key; +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_macro_dumper (rl_explicit_arg); + rl_on_new_line (); + return (0); +} + +void +rl_variable_dumper (print_readably) + int print_readably; +{ + int i; + const char *kname; + + for (i = 0; boolean_varlist[i].name; i++) + { + if (print_readably) + fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name, + *boolean_varlist[i].value ? "on" : "off"); + else + fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name, + *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) + { + char *disp; + + disp = _rl_untranslate_macro_value (_rl_isearch_terminators); + + if (print_readably) + fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp); + else + fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp); + + free (disp); + } + + /* 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 + rl_outstream. If an explicit argument is given, then print + the output in such a way that it can be read back in. */ +int +rl_dump_variables (count, key) + int count, key; +{ + if (rl_dispatching) + fprintf (rl_outstream, "\r\n"); + rl_variable_dumper (rl_explicit_arg); + rl_on_new_line (); + 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) + char *string; + const char **array; +{ + while (*array) + { + if (_rl_strindex (string, *array)) + return (1); + array++; + } + return (0); +} diff --git a/readline-4.3/callback.c b/readline-4.3/callback.c new file mode 100644 index 0000000..a8f4323 --- /dev/null +++ b/readline-4.3/callback.c @@ -0,0 +1,156 @@ +/* callback.c -- functions to use readline as an X `callback' mechanism. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include "rlconf.h" + +#if defined (READLINE_CALLBACKS) + +#include + +#ifdef HAVE_STDLIB_H +# include +#else +# include "ansi_stdlib.h" +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "readline.h" +#include "rlprivate.h" + +/* **************************************************************** */ +/* */ +/* Callback Readline Functions */ +/* */ +/* **************************************************************** */ + +/* Allow using readline in situations where a program may have multiple + things to handle at once, and dispatches them via select(). Call + rl_callback_handler_install() with the prompt and a function to call + whenever a complete line of input is ready. The user must then + call rl_callback_read_char() every time some input is available, and + rl_callback_read_char() will call the user's function with the complete + text read in at each end of line. The terminal is kept prepped and + signals handled all the time, except during calls to the user's function. */ + +rl_vcpfunc_t *rl_linefunc; /* user callback function */ +static int in_handler; /* terminal_prepped and signals set? */ + +/* Make sure the terminal is set up, initialize readline, and prompt. */ +static void +_rl_callback_newline () +{ + rl_initialize (); + + if (in_handler == 0) + { + in_handler = 1; + + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + rl_set_signals (); +#endif + } + + readline_internal_setup (); +} + +/* Install a readline handler, set up the terminal, and issue the prompt. */ +void +rl_callback_handler_install (prompt, linefunc) + const char *prompt; + rl_vcpfunc_t *linefunc; +{ + rl_set_prompt (prompt); + rl_linefunc = linefunc; + _rl_callback_newline (); +} + +/* Read one character, and dispatch to the handler if it ends the line. */ +void +rl_callback_read_char () +{ + char *line; + int eof; + + if (rl_linefunc == NULL) + { + fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n"); + abort (); + } + + eof = readline_internal_char (); + + /* We loop in case some function has pushed input back with rl_execute_next. */ + for (;;) + { + if (rl_done) + { + line = readline_internal_teardown (eof); + + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + in_handler = 0; + (*rl_linefunc) (line); + + /* If the user did not clear out the line, do it for him. */ + if (rl_line_buffer[0]) + _rl_init_line_state (); + + /* Redisplay the prompt if readline_handler_{install,remove} + not called. */ + if (in_handler == 0 && rl_linefunc) + _rl_callback_newline (); + } + if (rl_pending_input) + eof = readline_internal_char (); + else + break; + } +} + +/* Remove the handler, and make sure the terminal is in its normal state. */ +void +rl_callback_handler_remove () +{ + rl_linefunc = NULL; + if (in_handler) + { + in_handler = 0; + (*rl_deprep_term_function) (); +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + } +} + +#endif diff --git a/readline-4.3/chardefs.h b/readline-4.3/chardefs.h new file mode 100644 index 0000000..a537be2 --- /dev/null +++ b/readline-4.3/chardefs.h @@ -0,0 +1,159 @@ +/* chardefs.h -- Character definitions for readline. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _CHARDEFS_H_ +#define _CHARDEFS_H_ + +#include + +#if defined (HAVE_CONFIG_H) +# if defined (HAVE_STRING_H) +# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H) +# include +# endif +# include +# endif /* HAVE_STRING_H */ +# if defined (HAVE_STRINGS_H) +# include +# endif /* HAVE_STRINGS_H */ +#else +# include +#endif /* !HAVE_CONFIG_H */ + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifdef CTRL +# undef CTRL +#endif +#ifdef UNCTRL +# undef UNCTRL +#endif + +/* Some character stuff. */ +#define control_character_threshold 0x020 /* Smaller than this is control. */ +#define control_character_mask 0x1f /* 0x20 - 1 */ +#define meta_character_threshold 0x07f /* Larger than this is Meta. */ +#define control_character_bit 0x40 /* 0x000000, must be off. */ +#define meta_character_bit 0x080 /* x0000000, must be on. */ +#define largest_char 255 /* Largest character value. */ + +#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) +#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) + +#define CTRL(c) ((c) & control_character_mask) +#define META(c) ((c) | meta_character_bit) + +#define UNMETA(c) ((c) & (~meta_character_bit)) +#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit)) + +#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII)) +# define IN_CTYPE_DOMAIN(c) 1 +#else +# define IN_CTYPE_DOMAIN(c) isascii(c) +#endif + +#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) +# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) + +/* Some systems define these; we want our definitions. */ +#undef ISPRINT + +#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)) +#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c)) +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) +#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c)) + +#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c)) +#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c)) +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') + +#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c)) +#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c)) + +#ifndef _rl_to_upper +# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c)) +# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c)) +#endif + +#ifndef _rl_digit_value +# define _rl_digit_value(x) ((x) - '0') +#endif + +#ifndef _rl_isident +# define _rl_isident(c) (ISALNUM(c) || (c) == '_') +#endif + +#ifndef ISOCTAL +# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') +#endif +#define OCTVALUE(c) ((c) - '0') + +#define HEXVALUE(c) \ + (((c) >= 'a' && (c) <= 'f') \ + ? (c)-'a'+10 \ + : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') + +#ifndef NEWLINE +#define NEWLINE '\n' +#endif + +#ifndef RETURN +#define RETURN CTRL('M') +#endif + +#ifndef RUBOUT +#define RUBOUT 0x7f +#endif + +#ifndef TAB +#define TAB '\t' +#endif + +#ifdef ABORT_CHAR +#undef ABORT_CHAR +#endif +#define ABORT_CHAR CTRL('G') + +#ifdef PAGE +#undef PAGE +#endif +#define PAGE CTRL('L') + +#ifdef SPACE +#undef SPACE +#endif +#define SPACE ' ' /* XXX - was 0x20 */ + +#ifdef ESC +#undef ESC +#endif +#define ESC CTRL('[') + +#endif /* _CHARDEFS_H_ */ diff --git a/readline-4.3/compat.c b/readline-4.3/compat.c new file mode 100644 index 0000000..a66d210 --- /dev/null +++ b/readline-4.3/compat.c @@ -0,0 +1,113 @@ +/* compat.c -- backwards compatibility functions. */ + +/* Copyright (C) 2000 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include "rlstdc.h" +#include "rltypedefs.h" + +extern void rl_free_undo_list PARAMS((void)); +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +extern int rl_crlf PARAMS((void)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +/* Provide backwards-compatible entry points for old function names. */ + +void +free_undo_list () +{ + rl_free_undo_list (); +} + +int +maybe_replace_line () +{ + return rl_maybe_replace_line (); +} + +int +maybe_save_line () +{ + return rl_maybe_save_line (); +} + +int +maybe_unsave_line () +{ + return rl_maybe_unsave_line (); +} + +int +ding () +{ + return rl_ding (); +} + +int +crlf () +{ + return rl_crlf (); +} + +int +alphabetic (c) + int c; +{ + return rl_alphabetic (c); +} + +char ** +completion_matches (s, f) + const char *s; + rl_compentry_func_t *f; +{ + return rl_completion_matches (s, f); +} + +char * +username_completion_function (s, i) + const char *s; + int i; +{ + return rl_username_completion_function (s, i); +} + +char * +filename_completion_function (s, i) + const char *s; + int i; +{ + return rl_filename_completion_function (s, i); +} diff --git a/readline-4.3/complete.c b/readline-4.3/complete.c new file mode 100644 index 0000000..21a9d70 --- /dev/null +++ b/readline-4.3/complete.c @@ -0,0 +1,2004 @@ +/* complete.c -- filename completion for readline. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#if defined (HAVE_SYS_FILE_H) +#include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include + +#include "posixdir.h" +#include "posixstat.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "xmalloc.h" +#include "rlprivate.h" + +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +#ifdef HAVE_LSTAT +# define LSTAT lstat +#else +# define LSTAT stat +#endif + +/* Unix version of a hidden file. Could be different on other systems. */ +#define HIDDEN_FILE(fname) ((fname)[0] == '.') + +/* Most systems don't declare getpwent in if _POSIX_SOURCE is + defined. */ +#if !defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE) +extern struct passwd *getpwent PARAMS((void)); +#endif /* !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. + This function is called instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL; + +#if defined (VISIBLE_STATS) +# if !defined (X_OK) +# define X_OK 1 +# endif +static int stat_char PARAMS((char *)); +#endif + +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 print_filename PARAMS((char *, char *)); + +static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int)); + +static char **remove_duplicate_matches PARAMS((char **)); +static void insert_match PARAMS((char *, int, int, char *)); +static int append_to_match PARAMS((char *, int, int, int)); +static void insert_all_matches PARAMS((char **, int, char *)); +static void display_matches PARAMS((char **)); +static int compute_lcd_of_matches PARAMS((char **, int, const char *)); +static int postprocess_matches PARAMS((char ***, int)); + +static char *make_quoted_replacement PARAMS((char *, int, char *)); + +/* **************************************************************** */ +/* */ +/* Completion matching, from readline's point of view. */ +/* */ +/* **************************************************************** */ + +/* Variables known only to the readline library. */ + +/* If non-zero, non-unique completions always show the list of matches. */ +int _rl_complete_show_all = 0; + +/* If non-zero, completed directory names have a slash appended. */ +int _rl_complete_mark_directories = 1; + +/* If non-zero, the symlinked directory completion behavior introduced in + readline-4.2a is disabled, and symlinks that point to directories have + a slash appended (subject to the value of _rl_complete_mark_directories). + This is user-settable via the mark-symlinked-directories variable. */ +int _rl_complete_mark_symlink_dirs = 0; + +/* If non-zero, completions are printed horizontally in alphabetical order, + like `ls -x'. */ +int _rl_print_completions_horizontally; + +/* Non-zero means that case is not significant in filename completion. */ +#if defined (__MSDOS__) && !defined (__DJGPP__) +int _rl_completion_case_fold = 1; +#else +int _rl_completion_case_fold; +#endif + +/* If non-zero, don't match hidden files (filenames beginning with a `.' on + Unix) when doing filename completion. */ +int _rl_match_hidden_files = 1; + +/* Global variables available to applications using readline. */ + +#if defined (VISIBLE_STATS) +/* Non-zero means add an additional character to each filename displayed + during listing completion iff rl_filename_completion_desired which helps + to indicate the type of file being listed. */ +int rl_visible_stats = 0; +#endif /* VISIBLE_STATS */ + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. */ +rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL; + +rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; + +/* Non-zero means readline completion functions perform tilde expansion. */ +int rl_complete_with_tilde_expansion = 0; + +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default filename + completer. */ +rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +int rl_attempted_completion_over = 0; + +/* Set to a character indicating the type of completion being performed + by rl_complete_internal, available for use by application completion + functions. */ +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. */ +int rl_completion_query_items = 100; + +int _rl_page_completions = 1; + +/* The basic list of characters that signal a break between words for the + completer routine. The contents of this variable is what breaks words + in the shell, i.e. " \t\n\"\\'`@$><=" */ +const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */ + +/* List of basic quoting characters. */ +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; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +const char *rl_completer_quote_characters = (const char *)NULL; + +/* List of characters that should be quoted in filenames by the completer. */ +const char *rl_filename_quote_characters = (const char *)NULL; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +const char *rl_special_prefixes = (const char *)NULL; + +/* If non-zero, then disallow duplicates in the matches. */ +int rl_ignore_completion_duplicates = 1; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +int rl_filename_completion_desired = 0; + +/* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_filename_quote_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +int rl_filename_quoting_desired = 1; + +/* 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 (char**) known as matches in the code below. + It consists of a NULL-terminated array of pointers to potential + matching strings. The 1st element (matches[0]) is the maximal + substring that is common to all matches. This function can re-arrange + the list of matches as required, but all elements of the array must be + free()'d if they are deleted. The main intent of this function is + to implement FIGNORE a la SunOS csh. */ +rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. Readline doesn't do anything + with this; it's set only by applications. */ +rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL; + +/* If non-zero, the completion functions don't append anything except a + possible 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_append = 0; + +/* Character appended to completed words when at the end of the line. The + default is a space. */ +int rl_completion_append_character = ' '; + +/* 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 + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +int rl_completion_mark_symlink_dirs; + +/* If non-zero, inhibit completion (temporarily). */ +int rl_inhibit_completion; + +/* Variables local to this file. */ + +/* Local variable states what happened during the last completion attempt. */ +static int completion_changed_buffer; + +/*************************************/ +/* */ +/* Bindable completion functions */ +/* */ +/*************************************/ + +/* Complete the word at or before point. You have supplied the function + that does the initial simple matching selection algorithm (see + rl_completion_matches ()). The default is to do filename completion. */ +int +rl_complete (ignore, invoking_key) + int ignore, invoking_key; +{ + if (rl_inhibit_completion) + return (_rl_insert_char (ignore, invoking_key)); + else if (rl_last_func == rl_complete && !completion_changed_buffer) + return (rl_complete_internal ('?')); + else if (_rl_complete_show_all) + return (rl_complete_internal ('!')); + else + return (rl_complete_internal (TAB)); +} + +/* List the possible completions. See description of rl_complete (). */ +int +rl_possible_completions (ignore, invoking_key) + int ignore, invoking_key; +{ + return (rl_complete_internal ('?')); +} + +int +rl_insert_completions (ignore, invoking_key) + int ignore, invoking_key; +{ + return (rl_complete_internal ('*')); +} + +/* Return the correct value to pass to rl_complete_internal performing + the same tests as rl_complete. This allows consecutive calls to an + application's completion function to list possible completions and for + an application-specific completion function to honor the + show-all-if-ambiguous readline variable. */ +int +rl_completion_mode (cfunc) + rl_command_func_t *cfunc; +{ + if (rl_last_func == cfunc && !completion_changed_buffer) + return '?'; + else if (_rl_complete_show_all) + return '!'; + else + return TAB; +} + +/************************************/ +/* */ +/* Completion utility functions */ +/* */ +/************************************/ + +/* Set default values for readline word completion. These are the variables + that application completion functions can change or inspect. */ +static void +set_completion_defaults (what_to_do) + int what_to_do; +{ + /* Only the completion entry function can change these. */ + rl_filename_completion_desired = 0; + rl_filename_quoting_desired = 1; + rl_completion_type = what_to_do; + rl_completion_suppress_append = 0; + + /* The completion entry function may optionally change this. */ + rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs; +} + +/* The user must press "y" or "n". Non-zero return means "y" pressed. */ +static int +get_y_or_n (for_pager) + int for_pager; +{ + int c; + + for (;;) + { + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (c == 'y' || c == 'Y' || c == ' ') + return (1); + if (c == 'n' || c == 'N' || c == RUBOUT) + return (0); + if (c == ABORT_CHAR) + _rl_abort_internal (); + if (for_pager && (c == NEWLINE || c == RETURN)) + return (2); + if (for_pager && (c == 'q' || c == 'Q')) + return (0); + rl_ding (); + } +} + +static int +_rl_internal_pager (lines) + int lines; +{ + int i; + + fprintf (rl_outstream, "--More--"); + fflush (rl_outstream); + i = get_y_or_n (1); + _rl_erase_entire_line (); + if (i == 0) + return -1; + else if (i == 2) + return (lines - 1); + else + return 0; +} + +#if defined (VISIBLE_STATS) +/* Return the character which best describes FILENAME. + `@' for symbolic links + `/' for directories + `*' for executables + `=' for sockets + `|' for FIFOs + `%' for character special devices + `#' for block special devices */ +static int +stat_char (filename) + char *filename; +{ + struct stat finfo; + int character, r; + +#if defined (HAVE_LSTAT) && defined (S_ISLNK) + r = lstat (filename, &finfo); +#else + r = stat (filename, &finfo); +#endif + + if (r == -1) + return (0); + + character = 0; + if (S_ISDIR (finfo.st_mode)) + character = '/'; +#if defined (S_ISCHR) + else if (S_ISCHR (finfo.st_mode)) + character = '%'; +#endif /* S_ISCHR */ +#if defined (S_ISBLK) + else if (S_ISBLK (finfo.st_mode)) + character = '#'; +#endif /* S_ISBLK */ +#if defined (S_ISLNK) + else if (S_ISLNK (finfo.st_mode)) + character = '@'; +#endif /* S_ISLNK */ +#if defined (S_ISSOCK) + else if (S_ISSOCK (finfo.st_mode)) + character = '='; +#endif /* S_ISSOCK */ +#if defined (S_ISFIFO) + else if (S_ISFIFO (finfo.st_mode)) + character = '|'; +#endif + else if (S_ISREG (finfo.st_mode)) + { + if (access (filename, X_OK) == 0) + character = '*'; + } + return (character); +} +#endif /* VISIBLE_STATS */ + +/* Return the portion of PATHNAME that should be output when listing + possible completions. If we are hacking filename completion, we + are only interested in the basename, the portion following the + final slash. Otherwise, we return what we were passed. Since + printing empty strings is not very informative, if we're doing + filename completion, and the basename is the empty string, we look + for the previous slash and return the portion following that. If + there's no previous slash, we just return what we were passed. */ +static char * +printable_part (pathname) + char *pathname; +{ + char *temp, *x; + + if (rl_filename_completion_desired == 0) /* don't need to do anything */ + return (pathname); + + temp = strrchr (pathname, '/'); +#if defined (__MSDOS__) + if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':') + temp = pathname + 1; +#endif + + if (temp == 0 || *temp == '\0') + return (pathname); + /* If the basename is NULL, we might have a pathname like '/usr/src/'. + Look for a previous slash and, if one is found, return the portion + following that slash. If there's no previous slash, just return the + pathname we were passed. */ + else if (temp[1] == '\0') + { + for (x = temp - 1; x > pathname; x--) + if (*x == '/') + break; + return ((*x == '/') ? x + 1 : pathname); + } + else + return ++temp; +} + +/* 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; + + for (s = to_print; *s; s++) + { + PUTX (*s); + } +#else + char *s, c, *new_full_pathname; + int extension_char, slen, tlen; + + for (s = to_print; *s; s++) + { + PUTX (*s); + } + + if (rl_filename_completion_desired && rl_visible_stats) + { + /* If to_print != full_pathname, to_print is the basename of the + path passed. In this case, we try to expand the directory + name before checking for the stat character. */ + if (to_print != full_pathname) + { + /* Terminate the directory name. */ + c = to_print[-1]; + to_print[-1] = '\0'; + + /* If setting the last slash in full_pathname to a NUL results in + full_pathname being the empty string, we are trying to complete + 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 (rl_directory_completion_hook) + (*rl_directory_completion_hook) (&s); + + slen = strlen (s); + tlen = strlen (to_print); + new_full_pathname = (char *)xmalloc (slen + tlen + 2); + strcpy (new_full_pathname, s); + new_full_pathname[slen] = '/'; + strcpy (new_full_pathname + slen + 1, to_print); + + extension_char = stat_char (new_full_pathname); + + free (new_full_pathname); + to_print[-1] = c; + } + else + { + s = tilde_expand (full_pathname); + extension_char = stat_char (s); + } + + free (s); + if (extension_char) + { + putc (extension_char, rl_outstream); + printed_len++; + } + } +#endif /* VISIBLE_STATS */ + return printed_len; +} + +static char * +rl_quote_filename (s, rtype, qcp) + char *s; + int rtype; + char *qcp; +{ + char *r; + + r = (char *)xmalloc (strlen (s) + 2); + *r = *rl_completer_quote_characters; + strcpy (r + 1, s); + if (qcp) + *qcp = *rl_completer_quote_characters; + return r; +} + +/* Find the bounds of the current word for completion purposes, and leave + rl_point set to the end of the word. This function skips quoted + substrings (characters between matched pairs of characters in + rl_completer_quote_characters). First we try to find an unclosed + quoted substring on which to do matching. If one is not found, we use + the word break characters to find the boundaries of the current word. + We call an application-specific function to decide whether or not a + particular word break character is quoted; if that function returns a + non-zero result, the character does not break a word. This function + returns the opening quote character if we found an unclosed quoted + substring, '\0' otherwise. FP, if non-null, is set to a value saying + which (shell-like) quote characters we found (single quote, double + quote, or backslash) anywhere in the string. DP, if non-null, is set to + the value of the delimiter character that caused a word break. */ + +char +_rl_find_completion_word (fp, dp) + int *fp, *dp; +{ + int scan, end, found_quote, delimiter, pass_next, isbrk; + char quote_char; + + end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + 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++) + { + if (pass_next) + { + pass_next = 0; + continue; + } + + /* Shell-like semantics for single quotes -- don't allow backslash + to quote anything in single quotes, especially not the closing + quote. If you don't like this, take out the check on the value + of quote_char. */ + if (quote_char != '\'' && rl_line_buffer[scan] == '\\') + { + pass_next = 1; + found_quote |= RL_QF_BACKSLASH; + continue; + } + + if (quote_char != '\0') + { + /* Ignore everything until the matching close quote char. */ + if (rl_line_buffer[scan] == quote_char) + { + /* Found matching close. Abandon this substring. */ + quote_char = '\0'; + rl_point = end; + } + } + else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan])) + { + /* Found start of a quoted substring. */ + quote_char = rl_line_buffer[scan]; + rl_point = scan + 1; + /* Shell-like quoting conventions. */ + if (quote_char == '\'') + found_quote |= RL_QF_SINGLE_QUOTE; + else if (quote_char == '"') + found_quote |= RL_QF_DOUBLE_QUOTE; + else + found_quote |= RL_QF_OTHER_QUOTE; + } + } + } + + if (rl_point == end && quote_char == '\0') + { + /* 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 + { + scan = rl_line_buffer[rl_point]; + + if (strchr (rl_completer_word_break_characters, scan) == 0) + continue; + + /* Call the application-specific function to tell us whether + this word break character is quoted and should be skipped. */ + if (rl_char_is_quoted_p && found_quote && + (*rl_char_is_quoted_p) (rl_line_buffer, rl_point)) + continue; + + /* Convoluted code, but it avoids an n^2 algorithm with calls + to char_is_quoted. */ + break; + } + } + + /* If we are at an unquoted word break, then advance past it. */ + scan = rl_line_buffer[rl_point]; + + /* If there is an application-specific function to say whether or not + a character is quoted and we found a quote character, let that + function decide whether or not a character is a word break, even + if it is found in rl_completer_word_break_characters. Don't bother + if we're at the end of the line, though. */ + if (scan) + { + 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; + else + isbrk = strchr (rl_completer_word_break_characters, scan) != 0; + + if (isbrk) + { + /* If the character that caused the word break was a quoting + character, then remember it as the delimiter. */ + if (rl_basic_quote_characters && + strchr (rl_basic_quote_characters, scan) && + (end - rl_point) > 1) + delimiter = scan; + + /* If the character isn't needed to determine something special + about what kind of completion to perform, then advance past it. */ + if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0) + rl_point++; + } + } + + if (fp) + *fp = found_quote; + if (dp) + *dp = delimiter; + + return (quote_char); +} + +static char ** +gen_completion_matches (text, start, end, our_func, found_quote, quote_char) + char *text; + int start, end; + rl_compentry_func_t *our_func; + int found_quote, quote_char; +{ + char **matches, *temp; + + /* 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. */ + if (rl_attempted_completion_function) + { + matches = (*rl_attempted_completion_function) (text, start, end); + + if (matches || rl_attempted_completion_over) + { + rl_attempted_completion_over = 0; + return (matches); + } + } + + /* Beware -- we're stripping the quotes here. Do this only if we know + we are doing filename completion and the application has defined a + filename dequoting function. */ + temp = (char *)NULL; + + if (found_quote && our_func == rl_filename_completion_function && + rl_filename_dequoting_function) + { + /* delete single and double quotes */ + temp = (*rl_filename_dequoting_function) (text, quote_char); + text = temp; /* not freeing text is not a memory leak */ + } + + matches = rl_completion_matches (text, our_func); + FREE (temp); + return matches; +} + +/* Filter out duplicates in MATCHES. This frees up the strings in + MATCHES. */ +static char ** +remove_duplicate_matches (matches) + char **matches; +{ + char *lowest_common; + int i, j, newlen; + char dead_slot; + char **temp_array; + + /* Sort the items. */ + for (i = 0; matches[i]; i++) + ; + + /* Sort the array without matches[0], since we need it to + stay in place no matter what. */ + if (i) + qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + + /* Remember the lowest common denominator for it may be unique. */ + lowest_common = savestring (matches[0]); + + for (i = newlen = 0; matches[i + 1]; i++) + { + if (strcmp (matches[i], matches[i + 1]) == 0) + { + free (matches[i]); + matches[i] = (char *)&dead_slot; + } + else + newlen++; + } + + /* We have marked all the dead slots with (char *)&dead_slot. + Copy all the non-dead entries into a new array. */ + temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *)); + for (i = j = 1; matches[i]; i++) + { + if (matches[i] != (char *)&dead_slot) + temp_array[j++] = matches[i]; + } + temp_array[j] = (char *)NULL; + + if (matches[0] != (char *)&dead_slot) + free (matches[0]); + + /* Place the lowest common denominator back in [0]. */ + temp_array[0] = lowest_common; + + /* If there is one string left, and it is identical to the + lowest common denominator, then the LCD is the string to + insert. */ + if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0) + { + free (temp_array[1]); + temp_array[1] = (char *)NULL; + } + return (temp_array); +} + +/* Find the common prefix of the list of matches, and put it into + matches[0]. */ +static int +compute_lcd_of_matches (match_list, matches, text) + char **match_list; + int matches; + const char *text; +{ + register int i, c1, c2, si; + int low; /* Count of max-matched characters. */ +#if defined (HANDLE_MULTIBYTE) + int v; + mbstate_t ps1, ps2; + wchar_t wc1, wc2; +#endif + + /* If only one match, just use that. Otherwise, compare each + member of the list with the next, finding out where they + stop matching. */ + if (matches == 1) + { + match_list[0] = match_list[1]; + match_list[1] = (char *)NULL; + return 1; + } + + for (i = 1, low = 100000; i < matches; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + memset (&ps1, 0, sizeof (mbstate_t)); + memset (&ps2, 0, sizeof (mbstate_t)); + } +#endif + if (_rl_completion_case_fold) + { + for (si = 0; + (c1 = _rl_to_lower(match_list[i][si])) && + (c2 = _rl_to_lower(match_list[i + 1][si])); + si++) +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1); + mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2); + wc1 = towlower (wc1); + wc2 = towlower (wc2); + if (wc1 != wc2) + break; + else if (v > 1) + si += v - 1; + } + else +#endif + if (c1 != c2) + break; + } + else + { + for (si = 0; + (c1 = match_list[i][si]) && + (c2 = match_list[i + 1][si]); + si++) +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + mbstate_t ps_back = ps1; + if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2)) + break; + else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1) + si += v - 1; + } + else +#endif + if (c1 != c2) + break; + } + + if (low > si) + low = si; + } + + /* If there were multiple matches, but none matched up to even the + first character, and the user typed something, use that as the + value of matches[0]. */ + if (low == 0 && text && *text) + { + match_list[0] = (char *)xmalloc (strlen (text) + 1); + strcpy (match_list[0], text); + } + else + { + match_list[0] = (char *)xmalloc (low + 1); + + /* XXX - this might need changes in the presence of multibyte chars */ + + /* If we are ignoring case, try to preserve the case of the string + the user typed in the face of multiple matches differing in case. */ + if (_rl_completion_case_fold) + { + /* sort the list to get consistent answers. */ + qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); + + si = strlen (text); + if (si <= low) + { + for (i = 1; i <= matches; i++) + if (strncmp (match_list[i], text, si) == 0) + { + strncpy (match_list[0], match_list[i], low); + break; + } + /* no casematch, use first entry */ + if (i > matches) + strncpy (match_list[0], match_list[1], low); + } + else + /* otherwise, just use the text the user typed. */ + strncpy (match_list[0], text, low); + } + else + strncpy (match_list[0], match_list[1], low); + + match_list[0][low] = '\0'; + } + + return matches; +} + +static int +postprocess_matches (matchesp, matching_filenames) + char ***matchesp; + int matching_filenames; +{ + char *t, **matches, **temp_matches; + int nmatch, i; + + matches = *matchesp; + + if (matches == 0) + return 0; + + /* It seems to me that in all the cases we handle we would like + to ignore duplicate possiblilities. Scan for the text to + insert being identical to the other completions. */ + if (rl_ignore_completion_duplicates) + { + temp_matches = remove_duplicate_matches (matches); + free (matches); + matches = temp_matches; + } + + /* If we are matching filenames, then here is our chance to + do clever processing by re-examining the list. Call the + ignore function with the array as a parameter. It can + munge the array, deleting matches as it desires. */ + if (rl_ignore_some_completions_function && matching_filenames) + { + for (nmatch = 1; matches[nmatch]; nmatch++) + ; + (void)(*rl_ignore_some_completions_function) (matches); + if (matches == 0 || matches[0] == 0) + { + FREE (matches); + *matchesp = (char **)0; + return 0; + } + else + { + /* If we removed some matches, recompute the common prefix. */ + for (i = 1; matches[i]; i++) + ; + if (i > 1 && i < nmatch) + { + t = matches[0]; + compute_lcd_of_matches (matches, i - 1, t); + FREE (t); + } + } + } + + *matchesp = matches; + return (1); +} + +/* A convenience function for displaying a list of strings in + columnar format on readline's output stream. MATCHES is the list + of strings, in argv format, LEN is the number of strings in MATCHES, + and MAX is the length of the longest string in MATCHES. */ +void +rl_display_match_list (matches, len, max) + char **matches; + int len, max; +{ + int count, limit, printed_len, lines; + int i, j, k, l; + char *temp; + + /* How many items of MAX length can we fit in the screen window? */ + max += 2; + limit = _rl_screenwidth / max; + if (limit != 1 && (limit * max == _rl_screenwidth)) + limit--; + + /* Avoid a possible floating exception. If max > _rl_screenwidth, + limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (len + (limit - 1)) / limit; + + /* Watch out for special case. If LEN is less than LIMIT, then + just do the inner printing loop. + 0 < len <= limit implies count = 1. */ + + /* Sort the items if they are not already sorted. */ + if (rl_ignore_completion_duplicates == 0) + qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + + rl_crlf (); + + lines = 0; + if (_rl_print_completions_horizontally == 0) + { + /* Print the sorted items, up-and-down alphabetically, like ls. */ + for (i = 1; i <= count; i++) + { + for (j = 0, l = i; j < limit; j++) + { + if (l > len || matches[l] == 0) + break; + else + { + temp = printable_part (matches[l]); + printed_len = print_filename (temp, matches[l]); + + if (j + 1 < limit) + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); + } + l += count; + } + rl_crlf (); + lines++; + if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count) + { + lines = _rl_internal_pager (lines); + if (lines < 0) + return; + } + } + } + else + { + /* Print the sorted items, across alphabetically, like ls -x. */ + for (i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + printed_len = print_filename (temp, matches[i]); + /* Have we reached the end of this line? */ + if (matches[i+1]) + { + if (i && (limit > 1) && (i % limit) == 0) + { + rl_crlf (); + lines++; + if (_rl_page_completions && lines >= _rl_screenheight - 1) + { + lines = _rl_internal_pager (lines); + if (lines < 0) + return; + } + } + else + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); + } + } + rl_crlf (); + } +} + +/* Display MATCHES, a list of matching filenames in argv format. This + handles the simple case -- a single match -- first. If there is more + than one match, we compute the number of strings in the list and the + length of the longest string, which will be needed by the display + function. If the application wants to handle displaying the list of + matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the + address of a function, and we just call it. If we're handling the + display ourselves, we just call rl_display_match_list. We also check + that the list of matches doesn't exceed the user-settable threshold, + and ask the user if he wants to see the list if there are more matches + than RL_COMPLETION_QUERY_ITEMS. */ +static void +display_matches (matches) + char **matches; +{ + int len, max, i; + char *temp; + + /* Move to the last visible line of a possibly-multiple-line command. */ + _rl_move_vert (_rl_vis_botlin); + + /* Handle simple case first. What if there is only one answer? */ + if (matches[1] == 0) + { + temp = printable_part (matches[0]); + rl_crlf (); + print_filename (temp, matches[0]); + rl_crlf (); + + rl_forced_update_display (); + rl_display_fixed = 1; + + return; + } + + /* There is more than one answer. Find out how many there are, + and find the maximum printed length of a single entry. */ + for (max = 0, i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + len = strlen (temp); + + if (len > max) + max = len; + } + + len = i - 1; + + /* If the caller has defined a display hook, then call that now. */ + if (rl_completion_display_matches_hook) + { + (*rl_completion_display_matches_hook) (matches, len, max); + return; + } + + /* If there are many items, then ask the user if she really wants to + see them all. */ + if (len >= rl_completion_query_items) + { + rl_crlf (); + fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len); + fflush (rl_outstream); + if (get_y_or_n (0) == 0) + { + rl_crlf (); + + rl_forced_update_display (); + rl_display_fixed = 1; + + return; + } + } + + rl_display_match_list (matches, len, max); + + rl_forced_update_display (); + rl_display_fixed = 1; +} + +static char * +make_quoted_replacement (match, mtype, qc) + char *match; + int mtype; + char *qc; /* Pointer to quoting character, if any */ +{ + int should_quote, do_replace; + char *replacement; + + /* If we are doing completion on quoted substrings, and any matches + contain any of the completer_word_break_characters, then auto- + matically prepend the substring with a quote character (just pick + the first one from the list of such) if it does not already begin + with a quote string. FIXME: Need to remove any such automatically + inserted quote character when it no longer is necessary, such as + if we change the string we are completing on and the new set of + matches don't require a quoted substring. */ + replacement = match; + + should_quote = match && rl_completer_quote_characters && + rl_filename_completion_desired && + rl_filename_quoting_desired; + + if (should_quote) + should_quote = should_quote && (!qc || !*qc || + (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc))); + + if (should_quote) + { + /* If there is a single match, see if we need to quote it. + This also checks whether the common prefix of several + matches needs to be quoted. */ + should_quote = rl_filename_quote_characters + ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0) + : 0; + + do_replace = should_quote ? mtype : NO_MATCH; + /* Quote the replacement, since we found an embedded + word break character in a potential match. */ + if (do_replace != NO_MATCH && rl_filename_quoting_function) + replacement = (*rl_filename_quoting_function) (match, do_replace, qc); + } + return (replacement); +} + +static void +insert_match (match, start, mtype, qc) + char *match; + int start, mtype; + char *qc; +{ + char *replacement; + char oqc; + + oqc = qc ? *qc : '\0'; + replacement = make_quoted_replacement (match, mtype, qc); + + /* Now insert the match. */ + if (replacement) + { + /* Don't double an opening quote character. */ + if (qc && *qc && start && rl_line_buffer[start - 1] == *qc && + replacement[0] == *qc) + start--; + /* If make_quoted_replacement changed the quoting character, remove + the opening quote and insert the (fully-quoted) replacement. */ + else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc && + replacement[0] != oqc) + start--; + _rl_replace_text (replacement, start, rl_point - 1); + if (replacement != match) + free (replacement); + } +} + +/* Append any necessary closing quote and a separator character to the + just-inserted match. If the user has specified that directories + should be marked by a trailing `/', append one of those instead. The + default trailing character is a space. Returns the number of characters + appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS + has them) and don't add a suffix for a symlink to a directory. A + nontrivial match is one that actually adds to the word being completed. + The variable rl_completion_mark_symlink_dirs controls this behavior + (it's initially set to the what the user has chosen, indicated by the + value of _rl_complete_mark_symlink_dirs, but may be modified by an + application's completion function). */ +static int +append_to_match (text, delimiter, quote_char, nontrivial_match) + char *text; + int delimiter, quote_char, nontrivial_match; +{ + char temp_string[4], *filename; + int temp_string_index, s; + struct stat finfo; + + temp_string_index = 0; + if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char) + temp_string[temp_string_index++] = quote_char; + + if (delimiter) + temp_string[temp_string_index++] = delimiter; + else if (rl_completion_suppress_append == 0 && rl_completion_append_character) + temp_string[temp_string_index++] = rl_completion_append_character; + + temp_string[temp_string_index++] = '\0'; + + if (rl_filename_completion_desired) + { + filename = tilde_expand (text); + s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0) + ? LSTAT (filename, &finfo) + : stat (filename, &finfo); + if (s == 0 && S_ISDIR (finfo.st_mode)) + { + if (_rl_complete_mark_directories) + { + /* This is clumsy. Avoid putting in a double slash if point + is at the end of the line and the previous character is a + slash. */ + if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/') + ; + else if (rl_line_buffer[rl_point] != '/') + rl_insert_text ("/"); + } + } +#ifdef S_ISLNK + /* Don't add anything if the filename is a symlink and resolves to a + directory. */ + else if (s == 0 && S_ISLNK (finfo.st_mode) && + stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)) + ; +#endif + else + { + if (rl_point == rl_end && temp_string_index) + rl_insert_text (temp_string); + } + free (filename); + } + else + { + if (rl_point == rl_end && temp_string_index) + rl_insert_text (temp_string); + } + + return (temp_string_index); +} + +static void +insert_all_matches (matches, point, qc) + char **matches; + int point; + char *qc; +{ + int i; + char *rp; + + rl_begin_undo_group (); + /* remove any opening quote character; make_quoted_replacement will add + it back. */ + if (qc && *qc && point && rl_line_buffer[point - 1] == *qc) + point--; + rl_delete_text (point, rl_point); + rl_point = point; + + if (matches[1]) + { + for (i = 1; matches[i]; i++) + { + rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[i]) + free (rp); + } + } + else + { + rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc); + rl_insert_text (rp); + rl_insert_text (" "); + if (rp != matches[0]) + free (rp); + } + rl_end_undo_group (); +} + +void +_rl_free_match_list (matches) + char **matches; +{ + register int i; + + if (matches == 0) + return; + + for (i = 0; matches[i]; i++) + free (matches[i]); + free (matches); +} + +/* Complete the word at or before point. + WHAT_TO_DO says what to do with the completion. + `?' means list the possible completions. + 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. */ +int +rl_complete_internal (what_to_do) + int what_to_do; +{ + char **matches; + rl_compentry_func_t *our_func; + int start, end, delimiter, found_quote, i, nontrivial_lcd; + char *text, *saved_line_buffer; + char quote_char; + + RL_SETSTATE(RL_STATE_COMPLETING); + + set_completion_defaults (what_to_do); + + saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; + 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; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = _rl_find_completion_word (&found_quote, &delimiter); + + start = rl_point; + rl_point = end; + + text = rl_copy_text (start, end); + matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char); + /* nontrivial_lcd is set if the common prefix adds something to the word + being completed. */ + nontrivial_lcd = matches && strcmp (text, matches[0]) != 0; + free (text); + + if (matches == 0) + { + rl_ding (); + FREE (saved_line_buffer); + completion_changed_buffer = 0; + RL_UNSETSTATE(RL_STATE_COMPLETING); + return (0); + } + + /* If we are matching filenames, the attempted completion function will + have set rl_filename_completion_desired to a non-zero value. The basic + rl_filename_completion_function does this. */ + i = rl_filename_completion_desired; + + if (postprocess_matches (&matches, i) == 0) + { + rl_ding (); + FREE (saved_line_buffer); + completion_changed_buffer = 0; + RL_UNSETSTATE(RL_STATE_COMPLETING); + return (0); + } + + switch (what_to_do) + { + case TAB: + case '!': + /* Insert the first match with proper quoting. */ + if (*matches[0]) + insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char); + + /* If there are more matches, ring the bell to indicate. + If we are in vi mode, Posix.2 says to not ring the bell. + If the `show-all-if-ambiguous' variable is set, display + all the matches immediately. Otherwise, if this was the + only match, and we are hacking files, check the file to + see if it was a directory. If so, and the `mark-directories' + variable is set, add a '/' to the name. If not, and we + are at the end of the line, then add a space. */ + if (matches[1]) + { + if (what_to_do == '!') + { + display_matches (matches); + break; + } + else if (rl_editing_mode != vi_mode) + rl_ding (); /* There are other matches remaining. */ + } + else + append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd); + + break; + + case '*': + insert_all_matches (matches, start, "e_char); + break; + + case '?': + display_matches (matches); + break; + + default: + fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do); + rl_ding (); + FREE (saved_line_buffer); + RL_UNSETSTATE(RL_STATE_COMPLETING); + return 1; + } + + _rl_free_match_list (matches); + + /* Check to see if the line has changed through all of this manipulation. */ + if (saved_line_buffer) + { + completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0; + free (saved_line_buffer); + } + + RL_UNSETSTATE(RL_STATE_COMPLETING); + return 0; +} + +/***************************************************************/ +/* */ +/* Application-callable completion match generator functions */ +/* */ +/***************************************************************/ + +/* Return an array of (char *) which is a list of completions for TEXT. + If there are no completions, return a NULL pointer. + The first entry in the returned array is the substitution for TEXT. + The remaining entries are the possible completions. + The array is terminated with a NULL pointer. + + ENTRY_FUNCTION is a function of two args, and returns a (char *). + The first argument is TEXT. + The second is a state argument; it should be zero on the first call, and + non-zero on subsequent calls. It returns a NULL pointer to the caller + when there are no more matches. + */ +char ** +rl_completion_matches (text, entry_function) + const char *text; + rl_compentry_func_t *entry_function; +{ + /* Number of slots in match_list. */ + int match_list_size; + + /* The list of matches. */ + char **match_list; + + /* Number of matches actually found. */ + int matches; + + /* Temporary string binder. */ + char *string; + + matches = 0; + match_list_size = 10; + match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *)); + match_list[1] = (char *)NULL; + + while (string = (*entry_function) (text, matches)) + { + if (matches + 1 == match_list_size) + match_list = (char **)xrealloc + (match_list, ((match_list_size += 10) + 1) * sizeof (char *)); + + match_list[++matches] = string; + match_list[matches + 1] = (char *)NULL; + } + + /* If there were any matches, then look through them finding out the + lowest common denominator. That then becomes match_list[0]. */ + if (matches) + compute_lcd_of_matches (match_list, matches, text); + else /* There were no matches. */ + { + free (match_list); + match_list = (char **)NULL; + } + return (match_list); +} + +/* A completion function for usernames. + TEXT contains a partial username preceded by a random + character (usually `~'). */ +char * +rl_username_completion_function (text, state) + const char *text; + int state; +{ +#if defined (__WIN32__) || defined (__OPENNT) + return (char *)NULL; +#else /* !__WIN32__ && !__OPENNT) */ + static char *username = (char *)NULL; + static struct passwd *entry; + static int namelen, first_char, first_char_loc; + char *value; + + if (state == 0) + { + FREE (username); + + first_char = *text; + first_char_loc = first_char == '~'; + + username = savestring (&text[first_char_loc]); + namelen = strlen (username); + setpwent (); + } + + while (entry = getpwent ()) + { + /* Null usernames should result in all users as possible completions. */ + if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) + break; + } + + if (entry == 0) + { + endpwent (); + return ((char *)NULL); + } + else + { + value = (char *)xmalloc (2 + strlen (entry->pw_name)); + + *value = *text; + + strcpy (value + first_char_loc, entry->pw_name); + + if (first_char == '~') + rl_filename_completion_desired = 1; + + return (value); + } +#endif /* !__WIN32__ && !__OPENNT */ +} + +/* Okay, now we write the entry_function for filename completion. In the + general case. Note that completion in the shell is a little different + because of all the pathnames that must be followed when looking up the + completion for a command. */ +char * +rl_filename_completion_function (text, state) + const char *text; + int state; +{ + static DIR *directory = (DIR *)NULL; + static char *filename = (char *)NULL; + static char *dirname = (char *)NULL; + static char *users_dirname = (char *)NULL; + static int filename_len; + char *temp; + int dirlen; + struct dirent *entry; + + /* If we don't have any state, then do some initialization. */ + if (state == 0) + { + /* If we were interrupted before closing the directory or reading + all of its contents, close it. */ + if (directory) + { + closedir (directory); + directory = (DIR *)NULL; + } + FREE (dirname); + FREE (filename); + FREE (users_dirname); + + filename = savestring (text); + if (*text == 0) + text = "."; + dirname = savestring (text); + + temp = strrchr (dirname, '/'); + +#if defined (__MSDOS__) + /* special hack for //X/... */ + if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/') + temp = strrchr (dirname + 3, '/'); +#endif + + if (temp) + { + strcpy (filename, ++temp); + *temp = '\0'; + } +#if defined (__MSDOS__) + /* searches from current directory on the drive */ + else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':') + { + strcpy (filename, dirname + 2); + dirname[2] = '\0'; + } +#endif + else + { + dirname[0] = '.'; + dirname[1] = '\0'; + } + + /* We aren't done yet. We also support the "~user" syntax. */ + + /* Save the version of the directory that the user typed. */ + users_dirname = savestring (dirname); + + if (*dirname == '~') + { + temp = tilde_expand (dirname); + free (dirname); + dirname = temp; + } + + if (rl_directory_rewrite_hook) + (*rl_directory_rewrite_hook) (&dirname); + + if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname)) + { + free (users_dirname); + users_dirname = savestring (dirname); + } + + directory = opendir (dirname); + filename_len = strlen (filename); + + rl_filename_completion_desired = 1; + } + + /* At this point we should entertain the possibility of hacking wildcarded + filenames, like /usr/man/man/te. If the directory name + contains globbing characters, then build an array of directories, and + then map over that list while completing. */ + /* *** UNIMPLEMENTED *** */ + + /* Now that we have some state, we can read the directory. */ + + entry = (struct dirent *)NULL; + while (directory && (entry = readdir (directory))) + { + /* Special case for no filename. If the user has disabled the + `match-hidden-files' variable, skip filenames beginning with `.'. + All other entries except "." and ".." match. */ + if (filename_len == 0) + { + if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name)) + continue; + + if (entry->d_name[0] != '.' || + (entry->d_name[1] && + (entry->d_name[1] != '.' || entry->d_name[2]))) + break; + } + else + { + /* Otherwise, if these match up to the length of filename, then + it is a match. */ + if (_rl_completion_case_fold) + { + if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) && + (((int)D_NAMLEN (entry)) >= filename_len) && + (_rl_strnicmp (filename, entry->d_name, filename_len) == 0)) + break; + } + else + { + if ((entry->d_name[0] == filename[0]) && + (((int)D_NAMLEN (entry)) >= filename_len) && + (strncmp (filename, entry->d_name, filename_len) == 0)) + break; + } + } + } + + if (entry == 0) + { + if (directory) + { + closedir (directory); + directory = (DIR *)NULL; + } + if (dirname) + { + free (dirname); + dirname = (char *)NULL; + } + if (filename) + { + free (filename); + filename = (char *)NULL; + } + if (users_dirname) + { + free (users_dirname); + users_dirname = (char *)NULL; + } + + return (char *)NULL; + } + else + { + /* dirname && (strcmp (dirname, ".") != 0) */ + if (dirname && (dirname[0] != '.' || dirname[1])) + { + if (rl_complete_with_tilde_expansion && *users_dirname == '~') + { + dirlen = strlen (dirname); + temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); + strcpy (temp, dirname); + /* Canonicalization cuts off any final slash present. We + may need to add it back. */ + if (dirname[dirlen - 1] != '/') + { + temp[dirlen++] = '/'; + temp[dirlen] = '\0'; + } + } + else + { + dirlen = strlen (users_dirname); + temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry)); + strcpy (temp, users_dirname); + /* Make sure that temp has a trailing slash here. */ + if (users_dirname[dirlen - 1] != '/') + temp[dirlen++] = '/'; + } + + strcpy (temp + dirlen, entry->d_name); + } + else + temp = savestring (entry->d_name); + + return (temp); + } +} + +/* An initial implementation of a menu completion function a la tcsh. The + first time (if the last readline command was not rl_menu_complete), we + generate the list of matches. This code is very similar to the code in + rl_complete_internal -- there should be a way to combine the two. Then, + for each item in the list of matches, we insert the match in an undoable + fashion, with the appropriate character appended (this happens on the + second and subsequent consecutive calls to rl_menu_complete). When we + hit the end of the match list, we restore the original unmatched text, + ring the bell, and reset the counter to zero. */ +int +rl_menu_complete (count, ignore) + int count, ignore; +{ + rl_compentry_func_t *our_func; + int matching_filenames, found_quote; + + static char *orig_text; + static char **matches = (char **)0; + static int match_list_index = 0; + static int match_list_size = 0; + static int orig_start, orig_end; + static char quote_char; + static int delimiter; + + /* The first time through, we generate the list of matches and set things + up to insert them. */ + if (rl_last_func != rl_menu_complete) + { + /* Clean up from previous call, if any. */ + FREE (orig_text); + if (matches) + _rl_free_match_list (matches); + + match_list_index = match_list_size = 0; + matches = (char **)NULL; + + /* Only the completion entry function can change these. */ + set_completion_defaults ('%'); + + 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. */ + orig_end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = _rl_find_completion_word (&found_quote, &delimiter); + + orig_start = rl_point; + rl_point = orig_end; + + orig_text = rl_copy_text (orig_start, orig_end); + matches = gen_completion_matches (orig_text, orig_start, orig_end, + our_func, found_quote, quote_char); + + /* If we are matching filenames, the attempted completion function will + have set rl_filename_completion_desired to a non-zero value. The basic + rl_filename_completion_function does this. */ + matching_filenames = rl_filename_completion_desired; + + if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + FREE (orig_text); + orig_text = (char *)0; + completion_changed_buffer = 0; + return (0); + } + + for (match_list_size = 0; matches[match_list_size]; match_list_size++) + ; + /* matches[0] is lcd if match_list_size > 1, but the circular buffer + code below should take care of it. */ + } + + /* Now we have the list of matches. Replace the text between + rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with + matches[match_list_index], and add any necessary closing char. */ + + if (matches == 0 || match_list_size == 0) + { + rl_ding (); + FREE (matches); + matches = (char **)0; + completion_changed_buffer = 0; + return (0); + } + + match_list_index = (match_list_index + count) % match_list_size; + if (match_list_index < 0) + match_list_index += match_list_size; + + if (match_list_index == 0 && match_list_size > 1) + { + rl_ding (); + insert_match (orig_text, orig_start, MULT_MATCH, "e_char); + } + else + { + insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); + append_to_match (matches[match_list_index], delimiter, quote_char, + strcmp (orig_text, matches[match_list_index])); + } + + completion_changed_buffer = 1; + return (0); +} diff --git a/readline-4.3/config.h.in b/readline-4.3/config.h.in new file mode 100644 index 0000000..c53c2a1 --- /dev/null +++ b/readline-4.3/config.h.in @@ -0,0 +1,200 @@ +/* config.h.in. Maintained by hand. */ + +/* Define if on MINIX. */ +#undef _MINIX + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Characteristics of the compiler. */ +#undef const + +#undef size_t + +#undef ssize_t + +#undef PROTOTYPES + +#undef __CHAR_UNSIGNED__ + +/* Define if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +#undef VOID_SIGHANDLER + +/* Define if you have the isascii function. */ +#undef HAVE_ISASCII + +/* Define if you have the isxdigit function. */ +#undef HAVE_ISXDIGIT + +/* Define if you have the lstat function. */ +#undef HAVE_LSTAT + +/* Define if you have the mbsrtowcs function. */ +#undef HAVE_MBSRTOWCS + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the select function. */ +#undef HAVE_SELECT + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strcoll function. */ +#undef HAVE_STRCOLL + +#undef STRCOLL_BROKEN + +/* Define if you have the strpbrk function. */ +#undef HAVE_STRPBRK + +/* Define if you have the tcgetattr function. */ +#undef HAVE_TCGETATTR + +/* Define if you have the vsnprintf function. */ +#undef HAVE_VSNPRINTF + +/* Define if you have the wcwidth function. */ +#undef HAVE_WCWIDTH + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define if you have the header file. */ +#undef HAVE_LANGINFO_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#undef HAVE_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_DIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_FILE_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PTE_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_PTEM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STREAM_H + +/* Define if you have the header file. */ +#undef HAVE_TERMCAP_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_VARARGS_H + +/* Define if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define if you have the header file. */ +#undef HAVE_WCTYPE_H + +#undef HAVE_MBSTATE_T + +/* Define if you have and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Definitions pulled in from aclocal.m4. */ +#undef VOID_SIGHANDLER + +#undef GWINSZ_IN_SYS_IOCTL + +#undef STRUCT_WINSIZE_IN_SYS_IOCTL + +#undef STRUCT_WINSIZE_IN_TERMIOS + +#undef TIOCSTAT_IN_SYS_IOCTL + +#undef FIONREAD_IN_SYS_IOCTL + +#undef SPEED_T_IN_SYS_TYPES + +#undef HAVE_GETPW_DECLS + +#undef STRUCT_DIRENT_HAS_D_INO + +#undef STRUCT_DIRENT_HAS_D_FILENO + +#undef HAVE_BSD_SIGNALS + +#undef HAVE_POSIX_SIGNALS + +#undef HAVE_USG_SIGHOLD + +#undef MUST_REINSTALL_SIGHANDLERS + +#undef HAVE_POSIX_SIGSETJMP + +/* 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-4.3/configure b/readline-4.3/configure new file mode 100755 index 0000000..fc3769f --- /dev/null +++ b/readline-4.3/configure @@ -0,0 +1,5865 @@ +#! /bin/sh +# From configure.in for Readline 4.3, version 2.45, from autoconf version 2.52. +# Guess values for system-dependent variables and create Makefiles. +# Generated by Autoconf 2.52 for readline 4.3. +# +# Report bugs to . +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +cross_compiling=no +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +ac_unique_file="readline.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Identity of this package. +PACKAGE_NAME='readline' +PACKAGE_TARNAME='readline' +PACKAGE_VERSION='4.3' +PACKAGE_STRING='readline 4.3' +PACKAGE_BUGREPORT='bug-readline@gnu.org' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: should be removed in autoconf 3.0. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +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 < if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +EOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_subdir in : $ac_subdirs_all; do test "x$ac_subdir" = x: && continue + cd $ac_subdir + # A "../" for each directory in /$ac_subdir. + ac_dots=`echo $ac_subdir | + sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g'` + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_subdir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_subdir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure.gnu; then + echo + $SHELL $ac_sub_srcdir/configure.gnu --help=recursive + elif test -f $ac_sub_srcdir/configure; then + echo + $SHELL $ac_sub_srcdir/configure --help=recursive + elif test -f $ac_sub_srcdir/configure.ac || + test -f $ac_sub_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_subdir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\EOF +readline configure 4.3 +generated by GNU Autoconf 2.52 + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +EOF + exit 0 +fi +exec 5>config.log +cat >&5 </dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +PATH = $PATH + +_ASUNAME +} >&5 + +cat >&5 <\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + echo >&5 + echo "## ----------------- ##" >&5 + echo "## Cache variables. ##" >&5 + echo "## ----------------- ##" >&5 + echo >&5 + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} >&5 + sed "/^$/d" confdefs.h >conftest.log + if test -s conftest.log; then + echo >&5 + echo "## ------------ ##" >&5 + echo "## confdefs.h. ##" >&5 + echo "## ------------ ##" >&5 + echo >&5 + cat conftest.log >&5 + fi + (echo; echo) >&5 + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" >&5 + echo "$as_me: exit $exit_status" >&5 + rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:879: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + cat "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:890: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:898: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:914: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:918: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:924: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:926: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:928: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. It doesn't matter if + # we pass some twice (in addition to the command line arguments). + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val" + ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:947: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:949: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +echo "#! $SHELL" >conftest.sh +echo "exit 0" >>conftest.sh +chmod +x conftest.sh +if { (echo "$as_me:969: PATH=\".;.\"; conftest.sh") >&5 + (PATH=".;."; conftest.sh) 2>&5 + ac_status=$? + echo "$as_me:972: \$? = $ac_status" >&5 + (exit $ac_status); }; then + ac_path_separator=';' +else + ac_path_separator=: +fi +PATH_SEPARATOR="$ac_path_separator" +rm -f conftest.sh + +ac_aux_dir= +for ac_dir in ./support $srcdir/./support; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:998: error: cannot find install-sh or install.sh in ./support $srcdir/./support" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in ./support $srcdir/./support" >&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=4.3 + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:1012: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:1016: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:1025: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:1029: error: $ac_config_sub $ac_cv_build_alias failed." >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed." >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:1034: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +echo "$as_me:1041: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:1050: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:1055: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +opt_curses=no + +# Check whether --with-curses or --without-curses was given. +if test "${with_curses+set}" = set; then + withval="$with_curses" + opt_curses=$withval +fi; + +if test "$opt_curses" = "yes"; then + prefer_curses=yes +fi + +opt_static_libs=yes +opt_shared_libs=yes + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + opt_shared_libs=$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; + +echo "" +echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}" +echo "" + +# We want these before the checks, so the checks can modify their values. +test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1 + +echo "$as_me:1095: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:1115: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:1119: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:1132: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}gcc" +echo "$as_me:1147: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1155: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1158: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:1167: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="gcc" +echo "$as_me:1182: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1190: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1193: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:1206: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}cc" +echo "$as_me:1221: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1229: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1232: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:1241: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="cc" +echo "$as_me:1256: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1264: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1267: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:1280: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue +fi +ac_cv_prog_CC="cc" +echo "$as_me:1300: found $ac_dir/$ac_word" >&5 +break +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1322: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1325: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:1336: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +echo "$as_me:1351: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1359: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1362: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:1375: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="$ac_prog" +echo "$as_me:1390: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1398: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1401: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + +test -z "$CC" && { { echo "$as_me:1413: error: no acceptable cc found in \$PATH" >&5 +echo "$as_me: error: no acceptable cc found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:1418:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:1421: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:1424: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1426: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:1429: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1431: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:1434: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line 1438 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:1454: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:1457: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:1460: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. +for ac_file in `ls a.exe conftest.exe 2>/dev/null; + ls a.out conftest 2>/dev/null; + ls a.* conftest.* 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1483: error: C compiler cannot create executables" >&5 +echo "$as_me: error: C compiler cannot create executables" >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:1489: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1494: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:1500: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1503: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:1510: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:1518: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1525: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:1527: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:1530: checking for executable suffix" >&5 +echo $ECHO_N "checking for executable suffix... $ECHO_C" >&6 +if { (eval echo "$as_me:1532: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:1535: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:1551: error: cannot compute EXEEXT: cannot compile and link" >&5 +echo "$as_me: error: cannot compute EXEEXT: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:1557: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:1563: checking for object suffix" >&5 +echo $ECHO_N "checking for object suffix... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1569 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:1581: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1584: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1596: error: cannot compute OBJEXT: cannot compile" >&5 +echo "$as_me: error: cannot compute OBJEXT: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:1603: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:1607: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1613 "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1628: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1631: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1634: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1637: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:1649: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:1655: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1661 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1673: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1676: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1679: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1682: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:1692: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1719: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1722: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1725: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1728: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line 1740 "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1753: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1756: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1759: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1762: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line 1772 "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1784: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1787: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1790: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1793: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:1825: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line 1846 "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:1851: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:1857: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line 1880 "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:1884: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:1890: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:1927: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line 1937 "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:1942: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:1948: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line 1971 "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:1975: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:1981: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:2009: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +echo "$as_me:2020: checking for minix/config.h" >&5 +echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 +if test "${ac_cv_header_minix_config_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2026 "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:2030: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2036: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_minix_config_h=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_minix_config_h=no +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:2055: result: $ac_cv_header_minix_config_h" >&5 +echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 +if test $ac_cv_header_minix_config_h = yes; then + MINIX=yes +else + MINIX= +fi + +if test "$MINIX" = yes; then + +cat >>confdefs.h <<\EOF +#define _POSIX_SOURCE 1 +EOF + +cat >>confdefs.h <<\EOF +#define _POSIX_1_SOURCE 2 +EOF + +cat >>confdefs.h <<\EOF +#define _MINIX 1 +EOF + +fi + +# If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS. +test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O" + +if test $ac_cv_c_compiler_gnu = yes; then + echo "$as_me:2083: checking whether $CC needs -traditional" >&5 +echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +#line 2090 "configure" +#include "confdefs.h" +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +#line 2105 "configure" +#include "confdefs.h" +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +echo "$as_me:2118: result: $ac_cv_prog_gcc_traditional" >&5 +echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:2137: checking for a BSD compatible install" >&5 +echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_IFS=$IFS; IFS=$ac_path_separator + for ac_dir in $PATH; do + IFS=$ac_save_IFS + # Account for people who put trailing slashes in PATH elements. + case $ac_dir/ in + / | ./ | .// | /cC/* \ + | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \ + | /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if $as_executable_p "$ac_dir/$ac_prog"; then + if test $ac_prog = install && + grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:2186: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:2199: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_AR="" +echo "$as_me:2214: found $ac_dir/$ac_word" >&5 +break +done + + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:2223: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:2226: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +test -n "$ARFLAGS" || ARFLAGS="cr" +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:2234: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" +echo "$as_me:2249: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:2257: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:2260: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:2269: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_RANLIB="ranlib" +echo "$as_me:2284: found $ac_dir/$ac_word" >&5 +break +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:2293: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:2296: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +MAKE_SHELL=/bin/sh + +echo "$as_me:2307: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line 2315 "configure" +#include "confdefs.h" +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:2364: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2367: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2370: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2373: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:2390: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:2393: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +echo "$as_me:2398: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2404 "configure" +#include "confdefs.h" + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2462: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2465: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2468: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2471: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2481: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\EOF +#define const +EOF + +fi + +echo "$as_me:2491: checking for function prototypes" >&5 +echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6 +if test "$ac_cv_prog_cc_stdc" != no; then + echo "$as_me:2494: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\EOF +#define PROTOTYPES 1 +EOF + +else + echo "$as_me:2502: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +echo "$as_me:2506: 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 +#line 2512 "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:2520: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:2526: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err 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 +#line 2548 "configure" +#include "confdefs.h" +#include + +_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 +#line 2566 "configure" +#include "confdefs.h" +#include + +_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 +#line 2587 "configure" +#include "confdefs.h" +#include +#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:2613: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:2616: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:2618: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2621: \$? = $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 +cat conftest.$ac_ext >&5 +ac_cv_header_stdc=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:2634: 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 <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:2650: 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 +#line 2656 "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2662: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2665: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2668: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2671: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2681: 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 <&5 +echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6 +if test "${ac_cv_c_char_unsigned+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2697 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +int _array_ [1 - 2 * !(((char) -1) < 0)] + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2709: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2712: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2715: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2718: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_char_unsigned=no +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_char_unsigned=yes +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2728: result: $ac_cv_c_char_unsigned" >&5 +echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6 +if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then + cat >>confdefs.h <<\EOF +#define __CHAR_UNSIGNED__ 1 +EOF + +fi + +echo "$as_me:2737: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2743 "configure" +#include "confdefs.h" +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2765: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2768: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2771: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2774: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_signal=int +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2784: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2797 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2812: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2815: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2818: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2821: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_size_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2831: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <&5 +echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6 +if test "${ac_cv_type_ssize_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2849 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((ssize_t *) 0) + return 0; +if (sizeof (ssize_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2864: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2867: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2870: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2873: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_ssize_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_ssize_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2883: result: $ac_cv_type_ssize_t" >&5 +echo "${ECHO_T}$ac_cv_type_ssize_t" >&6 +if test $ac_cv_type_ssize_t = yes; then + : +else + +cat >>confdefs.h <&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 + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2901 "configure" +#include "confdefs.h" +#include +#include + +#if defined(S_ISBLK) && defined(S_IFDIR) +# if S_ISBLK (S_IFDIR) +You lose. +# endif +#endif + +#if defined(S_ISBLK) && defined(S_IFCHR) +# if S_ISBLK (S_IFCHR) +You lose. +# endif +#endif + +#if defined(S_ISLNK) && defined(S_IFREG) +# if S_ISLNK (S_IFREG) +You lose. +# endif +#endif + +#if defined(S_ISSOCK) && defined(S_IFREG) +# if S_ISSOCK (S_IFREG) +You lose. +# endif +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "You lose" >/dev/null 2>&1; then + ac_cv_header_stat_broken=yes +else + ac_cv_header_stat_broken=no +fi +rm -f conftest* + +fi +echo "$as_me:2940: result: $ac_cv_header_stat_broken" >&5 +echo "${ECHO_T}$ac_cv_header_stat_broken" >&6 +if test $ac_cv_header_stat_broken = yes; then + +cat >>confdefs.h <<\EOF +#define STAT_MACROS_BROKEN 1 +EOF + +fi + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +echo "$as_me:2953: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $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 +#line 2959 "configure" +#include "confdefs.h" +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2974: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2977: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2980: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2983: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2993: 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 <&5 +echo $ECHO_N "checking for opendir in -ldir... $ECHO_C" >&6 +if test "${ac_cv_lib_dir_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldir $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 3014 "configure" +#include "confdefs.h" + +/* 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 opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3033: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3036: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3039: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3042: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dir_opendir=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dir_opendir=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:3053: result: $ac_cv_lib_dir_opendir" >&5 +echo "${ECHO_T}$ac_cv_lib_dir_opendir" >&6 +if test $ac_cv_lib_dir_opendir = yes; then + LIBS="$LIBS -ldir" +fi + +else + echo "$as_me:3060: checking for opendir in -lx" >&5 +echo $ECHO_N "checking for opendir in -lx... $ECHO_C" >&6 +if test "${ac_cv_lib_x_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lx $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 3068 "configure" +#include "confdefs.h" + +/* 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 opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3087: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3090: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3093: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3096: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_x_opendir=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_x_opendir=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:3107: result: $ac_cv_lib_x_opendir" >&5 +echo "${ECHO_T}$ac_cv_lib_x_opendir" >&6 +if test $ac_cv_lib_x_opendir = yes; then + LIBS="$LIBS -lx" +fi + +fi + +for ac_func in lstat memmove putenv select setenv setlocale \ + strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:3119: 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 +#line 3125 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* 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 (); +char (*f) (); + +int +main () +{ +/* 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 +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3156: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3159: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3162: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3165: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3175: 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 <&5 +echo $ECHO_N "checking for working strcoll... $ECHO_C" >&6 +if test "${ac_cv_func_strcoll_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_strcoll_works=no +else + cat >conftest.$ac_ext <<_ACEOF +#line 3194 "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +exit (strcoll ("abc", "def") >= 0 || + strcoll ("ABC", "DEF") >= 0 || + strcoll ("123", "456") >= 0) + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3208: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3211: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3213: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3216: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strcoll_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_strcoll_works=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:3228: result: $ac_cv_func_strcoll_works" >&5 +echo "${ECHO_T}$ac_cv_func_strcoll_works" >&6 +if test $ac_cv_func_strcoll_works = yes; then + +cat >>confdefs.h <<\EOF +#define HAVE_STRCOLL 1 +EOF + +fi + +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 +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:3243: 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 +#line 3249 "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:3253: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:3259: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:3278: 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 <&5 +echo $ECHO_N "checking for type of signal functions... $ECHO_C" >&6 +if test "${bash_cv_signal_vintage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +#line 3295 "configure" +#include "confdefs.h" +#include +int +main () +{ + + sigset_t ss; + struct sigaction sa; + sigemptyset(&ss); sigsuspend(&ss); + sigaction(SIGINT, &sa, (struct sigaction *) 0); + sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3313: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3316: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3319: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3322: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_signal_vintage=posix +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +#line 3330 "configure" +#include "confdefs.h" +#include +int +main () +{ + + int mask = sigmask(SIGINT); + sigsetmask(mask); sigblock(mask); sigpause(mask); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3345: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3348: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3351: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3354: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_signal_vintage=4.2bsd +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +#line 3362 "configure" +#include "confdefs.h" + + #include + RETSIGTYPE foo() { } +int +main () +{ + + int mask = sigmask(SIGINT); + sigset(SIGINT, foo); sigrelse(SIGINT); + sighold(SIGINT); sigpause(SIGINT); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3380: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3383: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3386: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3389: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_signal_vintage=svr3 +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_signal_vintage=v7 + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + +fi + +echo "$as_me:3408: result: $bash_cv_signal_vintage" >&5 +echo "${ECHO_T}$bash_cv_signal_vintage" >&6 +if test "$bash_cv_signal_vintage" = posix; then +cat >>confdefs.h <<\EOF +#define HAVE_POSIX_SIGNALS 1 +EOF + +elif test "$bash_cv_signal_vintage" = "4.2bsd"; then +cat >>confdefs.h <<\EOF +#define HAVE_BSD_SIGNALS 1 +EOF + +elif test "$bash_cv_signal_vintage" = svr3; then +cat >>confdefs.h <<\EOF +#define HAVE_USG_SIGHOLD 1 +EOF + +fi + +echo "$as_me:3427: checking if signal handlers must be reinstalled when invoked" >&5 +echo $ECHO_N "checking if signal handlers must be reinstalled when invoked... $ECHO_C" >&6 +if test "${bash_cv_must_reinstall_sighandlers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { echo "$as_me:3433: WARNING: cannot check signal handling if cross compiling -- defaulting to no" >&5 +echo "$as_me: WARNING: cannot check signal handling if cross compiling -- defaulting to no" >&2;} + bash_cv_must_reinstall_sighandlers=no + +else + cat >conftest.$ac_ext <<_ACEOF +#line 3439 "configure" +#include "confdefs.h" + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +typedef RETSIGTYPE sigfunc(); + +int nsigint; + +#ifdef HAVE_POSIX_SIGNALS +sigfunc * +set_signal_handler(sig, handler) + int sig; + sigfunc *handler; +{ + struct sigaction act, oact; + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigemptyset (&oact.sa_mask); + sigaction (sig, &act, &oact); + return (oact.sa_handler); +} +#else +#define set_signal_handler(s, h) signal(s, h) +#endif + +RETSIGTYPE +sigint(s) +int s; +{ + nsigint++; +} + +main() +{ + nsigint = 0; + set_signal_handler(SIGINT, sigint); + kill((int)getpid(), SIGINT); + kill((int)getpid(), SIGINT); + exit(nsigint != 2); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3487: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3490: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3492: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3495: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_must_reinstall_sighandlers=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_must_reinstall_sighandlers=yes +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:3508: result: $bash_cv_must_reinstall_sighandlers" >&5 +echo "${ECHO_T}$bash_cv_must_reinstall_sighandlers" >&6 +if test $bash_cv_must_reinstall_sighandlers = yes; then +cat >>confdefs.h <<\EOF +#define MUST_REINSTALL_SIGHANDLERS 1 +EOF + +fi + +echo "$as_me:3517: checking for presence of POSIX-style sigsetjmp/siglongjmp" >&5 +echo $ECHO_N "checking for presence of POSIX-style sigsetjmp/siglongjmp... $ECHO_C" >&6 +if test "${bash_cv_func_sigsetjmp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { echo "$as_me:3523: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing" >&5 +echo "$as_me: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing" >&2;} + bash_cv_func_sigsetjmp=missing + +else + cat >conftest.$ac_ext <<_ACEOF +#line 3529 "configure" +#include "confdefs.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +main() +{ +#if !defined (_POSIX_VERSION) || !defined (HAVE_POSIX_SIGNALS) +exit (1); +#else + +int code; +sigset_t set, oset; +sigjmp_buf xx; + +/* get the mask */ +sigemptyset(&set); +sigemptyset(&oset); +sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set); +sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); + +/* save it */ +code = sigsetjmp(xx, 1); +if (code) + exit(0); /* could get sigmask and compare to oset here. */ + +/* change it */ +sigaddset(&set, SIGINT); +sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); + +/* and siglongjmp */ +siglongjmp(xx, 10); +exit(1); +#endif +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3571: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3574: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3576: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3579: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_func_sigsetjmp=present +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_func_sigsetjmp=missing +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:3592: result: $bash_cv_func_sigsetjmp" >&5 +echo "${ECHO_T}$bash_cv_func_sigsetjmp" >&6 +if test $bash_cv_func_sigsetjmp = present; then +cat >>confdefs.h <<\EOF +#define HAVE_POSIX_SIGSETJMP 1 +EOF + +fi + +echo "$as_me:3601: checking for lstat" >&5 +echo $ECHO_N "checking for lstat... $ECHO_C" >&6 +if test "${bash_cv_func_lstat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3607 "configure" +#include "confdefs.h" + +#include +#include + +int +main () +{ + lstat(".",(struct stat *)0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3622: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3625: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3628: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3631: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_func_lstat=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_func_lstat=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3641: result: $bash_cv_func_lstat" >&5 +echo "${ECHO_T}$bash_cv_func_lstat" >&6 +if test $bash_cv_func_lstat = yes; then + cat >>confdefs.h <<\EOF +#define HAVE_LSTAT 1 +EOF + +fi + +echo "$as_me:3650: checking whether or not strcoll and strcmp differ" >&5 +echo $ECHO_N "checking whether or not strcoll and strcmp differ... $ECHO_C" >&6 +if test "${bash_cv_func_strcoll_broken+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { echo "$as_me:3656: WARNING: cannot check strcoll if cross compiling -- defaulting to no" >&5 +echo "$as_me: WARNING: cannot check strcoll if cross compiling -- defaulting to no" >&2;} + bash_cv_func_strcoll_broken=no + +else + cat >conftest.$ac_ext <<_ACEOF +#line 3662 "configure" +#include "confdefs.h" + +#include +#if defined (HAVE_LOCALE_H) +#include +#endif + +main(c, v) +int c; +char *v[]; +{ + int r1, r2; + char *deflocale, *defcoll; + +#ifdef HAVE_SETLOCALE + deflocale = setlocale(LC_ALL, ""); + defcoll = setlocale(LC_COLLATE, ""); +#endif + +#ifdef HAVE_STRCOLL + /* These two values are taken from tests/glob-test. */ + r1 = strcoll("abd", "aXd"); +#else + r1 = 0; +#endif + r2 = strcmp("abd", "aXd"); + + /* These two should both be greater than 0. It is permissible for + a system to return different values, as long as the sign is the + same. */ + + /* Exit with 1 (failure) if these two values are both > 0, since + this tests whether strcoll(3) is broken with respect to strcmp(3) + in the default locale. */ + exit (r1 > 0 && r2 > 0); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:3702: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3705: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:3707: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3710: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_func_strcoll_broken=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_func_strcoll_broken=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + +echo "$as_me:3723: result: $bash_cv_func_strcoll_broken" >&5 +echo "${ECHO_T}$bash_cv_func_strcoll_broken" >&6 +if test $bash_cv_func_strcoll_broken = yes; then +cat >>confdefs.h <<\EOF +#define STRCOLL_BROKEN 1 +EOF + +fi + +echo "$as_me:3732: 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 + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3738 "configure" +#include "confdefs.h" + +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "getpwuid" >/dev/null 2>&1; then + bash_cv_getpw_declared=yes +else + bash_cv_getpw_declared=no +fi +rm -f conftest* + +fi + +echo "$as_me:3758: result: $bash_cv_getpw_declared" >&5 +echo "${ECHO_T}$bash_cv_getpw_declared" >&6 +if test $bash_cv_getpw_declared = yes; then +cat >>confdefs.h <<\EOF +#define HAVE_GETPW_DECLS 1 +EOF + +fi + +echo "$as_me:3767: checking POSIX termios" >&5 +echo $ECHO_N "checking POSIX termios... $ECHO_C" >&6 +if test "${ac_cv_sys_posix_termios+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3773 "configure" +#include "confdefs.h" +#include +#include +#include +int +main () +{ +/* SunOS 4.0.3 has termios.h but not the library calls. */ + tcgetattr(0, 0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:3788: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:3791: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:3794: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3797: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_posix_termios=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_sys_posix_termios=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:3807: result: $ac_cv_sys_posix_termios" >&5 +echo "${ECHO_T}$ac_cv_sys_posix_termios" >&6 + +if test $ac_cv_sys_posix_termios = yes; then + echo "$as_me:3811: checking whether termios.h defines TIOCGWINSZ" >&5 +echo $ECHO_N "checking whether termios.h defines TIOCGWINSZ... $ECHO_C" >&6 +if test "${ac_cv_sys_tiocgwinsz_in_termios_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3817 "configure" +#include "confdefs.h" +#include +#include +#ifdef TIOCGWINSZ + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + ac_cv_sys_tiocgwinsz_in_termios_h=yes +else + ac_cv_sys_tiocgwinsz_in_termios_h=no +fi +rm -f conftest* + +fi +echo "$as_me:3835: result: $ac_cv_sys_tiocgwinsz_in_termios_h" >&5 +echo "${ECHO_T}$ac_cv_sys_tiocgwinsz_in_termios_h" >&6 + +fi +if test $ac_cv_sys_tiocgwinsz_in_termios_h != yes; then + echo "$as_me:3840: checking whether sys/ioctl.h defines TIOCGWINSZ" >&5 +echo $ECHO_N "checking whether sys/ioctl.h defines TIOCGWINSZ... $ECHO_C" >&6 +if test "${ac_cv_sys_tiocgwinsz_in_sys_ioctl_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3846 "configure" +#include "confdefs.h" +#include +#include +#ifdef TIOCGWINSZ + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + ac_cv_sys_tiocgwinsz_in_sys_ioctl_h=yes +else + ac_cv_sys_tiocgwinsz_in_sys_ioctl_h=no +fi +rm -f conftest* + +fi +echo "$as_me:3864: result: $ac_cv_sys_tiocgwinsz_in_sys_ioctl_h" >&5 +echo "${ECHO_T}$ac_cv_sys_tiocgwinsz_in_sys_ioctl_h" >&6 + + if test $ac_cv_sys_tiocgwinsz_in_sys_ioctl_h = yes; then + +cat >>confdefs.h <<\EOF +#define GWINSZ_IN_SYS_IOCTL 1 +EOF + + fi +fi + +echo "$as_me:3876: checking whether signal handlers are of type void" >&5 +echo $ECHO_N "checking whether signal handlers are of type void... $ECHO_C" >&6 +if test "${bash_cv_void_sighandler+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3882 "configure" +#include "confdefs.h" +#include +#include +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" +#endif +void (*signal ()) (); +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3902: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3905: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3908: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3911: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_void_sighandler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_void_sighandler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:3921: result: $bash_cv_void_sighandler" >&5 +echo "${ECHO_T}$bash_cv_void_sighandler" >&6 +if test $bash_cv_void_sighandler = yes; then +cat >>confdefs.h <<\EOF +#define VOID_SIGHANDLER 1 +EOF + +fi + +echo "$as_me:3930: checking for TIOCSTAT in sys/ioctl.h" >&5 +echo $ECHO_N "checking for TIOCSTAT in sys/ioctl.h... $ECHO_C" >&6 +if test "${bash_cv_tiocstat_in_ioctl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3936 "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +int x = TIOCSTAT; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3949: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:3952: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:3955: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:3958: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_tiocstat_in_ioctl=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_tiocstat_in_ioctl=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:3969: result: $bash_cv_tiocstat_in_ioctl" >&5 +echo "${ECHO_T}$bash_cv_tiocstat_in_ioctl" >&6 +if test $bash_cv_tiocstat_in_ioctl = yes; then +cat >>confdefs.h <<\EOF +#define TIOCSTAT_IN_SYS_IOCTL 1 +EOF + +fi + +echo "$as_me:3978: checking for FIONREAD in sys/ioctl.h" >&5 +echo $ECHO_N "checking for FIONREAD in sys/ioctl.h... $ECHO_C" >&6 +if test "${bash_cv_fionread_in_ioctl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 3984 "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +int x = FIONREAD; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:3997: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4000: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4003: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4006: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_fionread_in_ioctl=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_fionread_in_ioctl=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:4017: result: $bash_cv_fionread_in_ioctl" >&5 +echo "${ECHO_T}$bash_cv_fionread_in_ioctl" >&6 +if test $bash_cv_fionread_in_ioctl = yes; then +cat >>confdefs.h <<\EOF +#define FIONREAD_IN_SYS_IOCTL 1 +EOF + +fi + +echo "$as_me:4026: checking for speed_t in sys/types.h" >&5 +echo $ECHO_N "checking for speed_t in sys/types.h... $ECHO_C" >&6 +if test "${bash_cv_speed_t_in_sys_types+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4032 "configure" +#include "confdefs.h" +#include +int +main () +{ +speed_t x; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:4044: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4047: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4050: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4053: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_speed_t_in_sys_types=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_speed_t_in_sys_types=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:4064: result: $bash_cv_speed_t_in_sys_types" >&5 +echo "${ECHO_T}$bash_cv_speed_t_in_sys_types" >&6 +if test $bash_cv_speed_t_in_sys_types = yes; then +cat >>confdefs.h <<\EOF +#define SPEED_T_IN_SYS_TYPES 1 +EOF + +fi + +echo "$as_me:4073: checking for struct winsize in sys/ioctl.h and termios.h" >&5 +echo $ECHO_N "checking for struct winsize in sys/ioctl.h and termios.h... $ECHO_C" >&6 +if test "${bash_cv_struct_winsize_header+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4079 "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +struct winsize x; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:4092: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4095: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4098: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4101: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_struct_winsize_header=ioctl_h +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line 4108 "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +struct winsize x; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:4121: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4124: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4127: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4130: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_struct_winsize_header=termios_h +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_struct_winsize_header=other +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +if test $bash_cv_struct_winsize_header = ioctl_h; then + echo "$as_me:4145: result: sys/ioctl.h" >&5 +echo "${ECHO_T}sys/ioctl.h" >&6 + cat >>confdefs.h <<\EOF +#define STRUCT_WINSIZE_IN_SYS_IOCTL 1 +EOF + +elif test $bash_cv_struct_winsize_header = termios_h; then + echo "$as_me:4152: result: termios.h" >&5 +echo "${ECHO_T}termios.h" >&6 + cat >>confdefs.h <<\EOF +#define STRUCT_WINSIZE_IN_TERMIOS 1 +EOF + +else + echo "$as_me:4159: result: not found" >&5 +echo "${ECHO_T}not found" >&6 +fi + +echo "$as_me:4163: 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 +if test "${bash_cv_dirent_has_dino+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4169 "configure" +#include "confdefs.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include +# endif +#endif /* HAVE_DIRENT_H */ + +int +main () +{ + +struct dirent d; int z; z = d.d_ino; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:4203: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4206: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4209: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4212: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_dirent_has_dino=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_dirent_has_dino=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:4223: 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 <<\EOF +#define STRUCT_DIRENT_HAS_D_INO 1 +EOF + +fi + +echo "$as_me:4232: 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 +if test "${bash_cv_dirent_has_d_fileno+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4238 "configure" +#include "confdefs.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include +# endif +#endif /* HAVE_DIRENT_H */ + +int +main () +{ + +struct dirent d; int z; z = d.d_fileno; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:4272: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:4275: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:4278: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4281: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_dirent_has_d_fileno=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_dirent_has_d_fileno=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:4292: 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 <<\EOF +#define STRUCT_DIRENT_HAS_D_FILENO 1 +EOF + +fi + +case "$host_os" in +aix*) prefer_curses=yes ;; +esac + +if test "X$bash_cv_termcap_lib" = "X"; then +_bash_needmsg=yes +else +echo "$as_me:4308: checking which library has the termcap functions" >&5 +echo $ECHO_N "checking which library has the termcap functions... $ECHO_C" >&6 +_bash_needmsg= +fi +if test "${bash_cv_termcap_lib+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + echo "$as_me:4315: 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 + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltermcap $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 4323 "configure" +#include "confdefs.h" + +/* 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 (); +int +main () +{ +tgetent (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4342: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4345: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4348: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4351: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_termcap_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_termcap_tgetent=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:4362: result: $ac_cv_lib_termcap_tgetent" >&5 +echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6 +if test $ac_cv_lib_termcap_tgetent = yes; then + bash_cv_termcap_lib=libtermcap +else + echo "$as_me:4367: checking for tgetent in -ltinfo" >&5 +echo $ECHO_N "checking for tgetent in -ltinfo... $ECHO_C" >&6 +if test "${ac_cv_lib_tinfo_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 4375 "configure" +#include "confdefs.h" + +/* 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 (); +int +main () +{ +tgetent (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4394: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4397: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4400: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4403: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_tinfo_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_tinfo_tgetent=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:4414: result: $ac_cv_lib_tinfo_tgetent" >&5 +echo "${ECHO_T}$ac_cv_lib_tinfo_tgetent" >&6 +if test $ac_cv_lib_tinfo_tgetent = yes; then + bash_cv_termcap_lib=libtinfo +else + echo "$as_me:4419: checking for tgetent in -lcurses" >&5 +echo $ECHO_N "checking for tgetent in -lcurses... $ECHO_C" >&6 +if test "${ac_cv_lib_curses_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcurses $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 4427 "configure" +#include "confdefs.h" + +/* 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 (); +int +main () +{ +tgetent (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4446: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4449: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4452: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4455: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_curses_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_curses_tgetent=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:4466: result: $ac_cv_lib_curses_tgetent" >&5 +echo "${ECHO_T}$ac_cv_lib_curses_tgetent" >&6 +if test $ac_cv_lib_curses_tgetent = yes; then + bash_cv_termcap_lib=libcurses +else + echo "$as_me:4471: checking for tgetent in -lncurses" >&5 +echo $ECHO_N "checking for tgetent in -lncurses... $ECHO_C" >&6 +if test "${ac_cv_lib_ncurses_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line 4479 "configure" +#include "confdefs.h" + +/* 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 (); +int +main () +{ +tgetent (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4498: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4501: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4504: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4507: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ncurses_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_ncurses_tgetent=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:4518: result: $ac_cv_lib_ncurses_tgetent" >&5 +echo "${ECHO_T}$ac_cv_lib_ncurses_tgetent" >&6 +if test $ac_cv_lib_ncurses_tgetent = yes; then + bash_cv_termcap_lib=libncurses +else + bash_cv_termcap_lib=gnutermcap +fi + +fi + +fi + +fi + +fi + +if test "X$_bash_needmsg" = "Xyes"; then +echo "$as_me:4535: checking which library has the termcap functions" >&5 +echo $ECHO_N "checking which library has the termcap functions... $ECHO_C" >&6 +fi +echo "$as_me:4538: result: using $bash_cv_termcap_lib" >&5 +echo "${ECHO_T}using $bash_cv_termcap_lib" >&6 +if test $bash_cv_termcap_lib = gnutermcap && test -z "$prefer_curses"; then +LDFLAGS="$LDFLAGS -L./lib/termcap" +TERMCAP_LIB="./lib/termcap/libtermcap.a" +TERMCAP_DEP="./lib/termcap/libtermcap.a" +elif test $bash_cv_termcap_lib = libtermcap && test -z "$prefer_curses"; then +TERMCAP_LIB=-ltermcap +TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libtinfo; then +TERMCAP_LIB=-ltinfo +TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libncurses; then +TERMCAP_LIB=-lncurses +TERMCAP_DEP= +else +TERMCAP_LIB=-lcurses +TERMCAP_DEP= +fi + +if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then + if test "$prefer_curses" = yes; then + TERMCAP_LIB=-lcurses + else + TERMCAP_LIB=-ltermcap #default + fi +fi + +for ac_header in wctype.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:4569: 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 +#line 4575 "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:4579: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:4585: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:4604: 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 <&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 +#line 4623 "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:4627: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:4633: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:4652: 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 <&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 +#line 4671 "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:4675: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:4681: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_ext +fi +echo "$as_me:4700: 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 <&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 +#line 4716 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char mbsrtowcs (); below. */ +#include +/* 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 (); +char (*f) (); + +int +main () +{ +/* 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 +f = mbsrtowcs; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4747: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4750: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4753: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4756: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_mbsrtowcs=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_mbsrtowcs=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:4766: 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 <<\EOF +#define HAVE_MBSRTOWCS 1 +EOF + +fi + +echo "$as_me:4775: checking for wcwidth" >&5 +echo $ECHO_N "checking for wcwidth... $ECHO_C" >&6 +if test "${ac_cv_func_wcwidth+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4781 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char wcwidth (); below. */ +#include +/* 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 wcwidth (); +char (*f) (); + +int +main () +{ +/* 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_wcwidth) || defined (__stub___wcwidth) +choke me +#else +f = wcwidth; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4812: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4815: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4818: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4821: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_wcwidth=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_wcwidth=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:4831: result: $ac_cv_func_wcwidth" >&5 +echo "${ECHO_T}$ac_cv_func_wcwidth" >&6 +if test $ac_cv_func_wcwidth = yes; then + cat >>confdefs.h <<\EOF +#define HAVE_WCWIDTH 1 +EOF + +fi + +echo "$as_me:4840: checking for mbstate_t" >&5 +echo $ECHO_N "checking for mbstate_t... $ECHO_C" >&6 +if test "${bash_cv_have_mbstate_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:4846: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line 4851 "configure" +#include "confdefs.h" + +#include +int +main () +{ + mbstate_t ps; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:4863: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4866: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:4868: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4871: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_have_mbstate_t=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_have_mbstate_t=no +fi +rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:4883: result: $bash_cv_have_mbstate_t" >&5 +echo "${ECHO_T}$bash_cv_have_mbstate_t" >&6 +if test $bash_cv_have_mbstate_t = yes; then + cat >>confdefs.h <<\EOF +#define HAVE_MBSTATE_T 1 +EOF + +fi + +echo "$as_me:4892: checking for nl_langinfo and CODESET" >&5 +echo $ECHO_N "checking for nl_langinfo and CODESET... $ECHO_C" >&6 +if test "${bash_cv_langinfo_codeset+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 4898 "configure" +#include "confdefs.h" +#include +int +main () +{ +char* cs = nl_langinfo(CODESET); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:4910: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:4913: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:4916: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:4919: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + bash_cv_langinfo_codeset=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +bash_cv_langinfo_codeset=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:4929: result: $bash_cv_langinfo_codeset" >&5 +echo "${ECHO_T}$bash_cv_langinfo_codeset" >&6 +if test $bash_cv_langinfo_codeset = yes; then + cat >>confdefs.h <<\EOF +#define HAVE_LANGINFO_CODESET 1 +EOF + +fi + +case "$host_cpu" in +*cray*) LOCAL_CFLAGS=-DCRAY ;; +*s390*) LOCAL_CFLAGS=-fsigned-char ;; +esac + +case "$host_os" in +isc*) LOCAL_CFLAGS=-Disc386 ;; +esac + +# shared library configuration section +# +# Shared object configuration section. These values are generated by +# ${srcdir}/support/shobj-conf +# +if test -f ${srcdir}/support/shobj-conf; then + echo "$as_me:4953: 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}` + + echo "$as_me:4957: result: $SHLIB_STATUS" >&5 +echo "${ECHO_T}$SHLIB_STATUS" >&6 + + # SHLIB_STATUS is either `supported' or `unsupported'. If it's + # `unsupported', turn off any default shared library building + if test "$SHLIB_STATUS" = 'unsupported'; then + opt_shared_libs=no + fi + + # shared library versioning + # quoted for m4 so I can use character classes + SHLIB_MAJOR=`expr "$LIBVERSION" : '\([0-9]\)\..*'` + SHLIB_MINOR=`expr "$LIBVERSION" : '[0-9]\.\([0-9]\).*'` + +fi + +if test "$opt_static_libs" = "yes"; then + STATIC_TARGET=static + STATIC_INSTALL_TARGET=install-static +fi +if test "$opt_shared_libs" = "yes"; then + SHARED_TARGET=shared + SHARED_INSTALL_TARGET=install-shared +fi + +case "$host_os" in +msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file +*) BUILD_DIR=`pwd` ;; +esac + +ac_config_files="$ac_config_files Makefile doc/Makefile examples/Makefile shlib/Makefile" +ac_config_commands="$ac_config_commands default" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overriden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:5068: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +ac_cs_invocation="\$0 \$@" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +exec 6>&1 + +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\EOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +EOF + +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:5244: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:5263: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +exec 5>>config.log +cat >&5 << _ACEOF + +## ----------------------- ## +## Running config.status. ## +## ----------------------- ## + +This file was extended by $as_me (readline 4.3) 2.52, executed with + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + > $ac_cs_invocation +on `(hostname || uname -n) 2>/dev/null | sed 1q` + +_ACEOF +EOF + +cat >>$CONFIG_STATUS <<\EOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + "shlib/Makefile" ) CONFIG_FILES="$CONFIG_FILES shlib/Makefile" ;; + "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:5304: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +EOF + +cat >>$CONFIG_STATUS <\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@DEFS@,$DEFS,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +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,@SET_MAKE@,$SET_MAKE,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@AR@,$AR,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@MAKE_SHELL@,$MAKE_SHELL,;t t +s,@SHOBJ_CC@,$SHOBJ_CC,;t t +s,@SHOBJ_CFLAGS@,$SHOBJ_CFLAGS,;t t +s,@SHOBJ_LD@,$SHOBJ_LD,;t t +s,@SHOBJ_LDFLAGS@,$SHOBJ_LDFLAGS,;t t +s,@SHOBJ_XLDFLAGS@,$SHOBJ_XLDFLAGS,;t t +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_LIBSUFF@,$SHLIB_LIBSUFF,;t t +s,@SHLIB_LIBVERSION@,$SHLIB_LIBVERSION,;t t +s,@SHLIB_LIBS@,$SHLIB_LIBS,;t t +s,@SHLIB_MAJOR@,$SHLIB_MAJOR,;t t +s,@SHLIB_MINOR@,$SHLIB_MINOR,;t t +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,@BUILD_DIR@,$BUILD_DIR,;t t +s,@LOCAL_CFLAGS@,$LOCAL_CFLAGS,;t t +s,@LOCAL_LDFLAGS@,$LOCAL_LDFLAGS,;t t +s,@LOCAL_DEFS@,$LOCAL_DEFS,;t t +s,@ARFLAGS@,$ARFLAGS,;t t +s,@LIBVERSION@,$LIBVERSION,;t t +s,@TERMCAP_LIB@,$TERMCAP_LIB,;t t +CEOF + +EOF + + cat >>$CONFIG_STATUS <<\EOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +EOF +cat >>$CONFIG_STATUS <<\EOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'` + else + ac_dir_suffix= ac_dots= + fi + + case $srcdir in + .) ac_srcdir=. + if test -z "$ac_dots"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_dots$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_dots$srcdir ;; + esac + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_dots$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:5549: 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 automatically by config.status. */ + configure_input="Generated automatically from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:5567: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:5580: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +EOF +cat >>$CONFIG_STATUS <<\EOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:5641: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:5652: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:5665: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +EOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\EOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$,${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +EOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\EOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +EOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # egrep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\EOF + # 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 automatically by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated automatically by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated automatically by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:5782: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + fi + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +EOF +cat >>$CONFIG_STATUS <<\EOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + + case $ac_dest in + default ) +# Makefile uses this timestamp file to record whether config.h is up to date. +echo > stamp-h + ;; + esac +done +EOF + +cat >>$CONFIG_STATUS <<\EOF + +{ (exit 0); exit 0; } +EOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/readline-4.3/configure.in b/readline-4.3/configure.in new file mode 100644 index 0000000..bc78f8a --- /dev/null +++ b/readline-4.3/configure.in @@ -0,0 +1,206 @@ +dnl +dnl Configure script for readline library +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) + +dnl make sure we are using a recent autoconf version +AC_PREREQ(2.50) + +AC_CONFIG_SRCDIR(readline.h) +AC_CONFIG_AUX_DIR(./support) +AC_CONFIG_HEADERS(config.h) + +dnl update the value of RL_READLINE_VERSION in readline.h when this changes +LIBVERSION=4.3 + +AC_CANONICAL_HOST + +dnl configure defaults +opt_curses=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) + +if test "$opt_curses" = "yes"; then + prefer_curses=yes +fi + +dnl option parsing for optional features +opt_static_libs=yes +opt_shared_libs=yes + +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) + +echo "" +echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}" +echo "" + +# We want these before the checks, so the checks can modify their values. +test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1 + +AC_PROG_MAKE_SET +AC_PROG_CC +dnl AC_AIX +AC_MINIX + +# If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS. +test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O" + +AC_PROG_GCC_TRADITIONAL +AC_PROG_INSTALL +AC_CHECK_PROG(AR, ar, , ar) +dnl Set default for ARFLAGS, since autoconf does not have a macro for it. +dnl This allows people to set it when running configure or make +test -n "$ARFLAGS" || ARFLAGS="cr" +AC_PROG_RANLIB + +MAKE_SHELL=/bin/sh +AC_SUBST(MAKE_SHELL) + +AC_C_CONST +AC_C_PROTOTYPES +AC_C_CHAR_UNSIGNED + +AC_TYPE_SIGNAL + +AC_TYPE_SIZE_T +AC_CHECK_TYPE(ssize_t, int) + +AC_HEADER_STAT +AC_HEADER_DIRENT + +AC_CHECK_FUNCS(lstat memmove putenv select setenv setlocale \ + strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit) + +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 ) + +BASH_SYS_SIGNAL_VINTAGE +BASH_SYS_REINSTALL_SIGHANDLERS + +BASH_FUNC_POSIX_SETJMP +BASH_FUNC_LSTAT +BASH_FUNC_STRCOLL + +BASH_CHECK_GETPW_FUNCS + +AC_HEADER_TIOCGWINSZ + +BASH_TYPE_SIGHANDLER +BASH_HAVE_TIOCSTAT +BASH_HAVE_FIONREAD +BASH_CHECK_SPEED_T +BASH_STRUCT_WINSIZE +BASH_STRUCT_DIRENT_D_INO +BASH_STRUCT_DIRENT_D_FILENO + +dnl yuck +case "$host_os" in +aix*) prefer_curses=yes ;; +esac +BASH_CHECK_LIB_TERMCAP +if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then + if test "$prefer_curses" = yes; then + TERMCAP_LIB=-lcurses + else + TERMCAP_LIB=-ltermcap #default + fi +fi + +BASH_CHECK_MULTIBYTE + +case "$host_cpu" in +*cray*) LOCAL_CFLAGS=-DCRAY ;; +*s390*) LOCAL_CFLAGS=-fsigned-char ;; +esac + +case "$host_os" in +isc*) LOCAL_CFLAGS=-Disc386 ;; +esac + +# shared library configuration section +# +# Shared object configuration section. These values are generated by +# ${srcdir}/support/shobj-conf +# +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}` + AC_SUBST(SHOBJ_CC) + AC_SUBST(SHOBJ_CFLAGS) + AC_SUBST(SHOBJ_LD) + AC_SUBST(SHOBJ_LDFLAGS) + AC_SUBST(SHOBJ_XLDFLAGS) + AC_SUBST(SHOBJ_LIBS) + AC_SUBST(SHOBJ_STATUS) + AC_SUBST(SHLIB_STATUS) + AC_SUBST(SHLIB_XLDFLAGS) + AC_SUBST(SHLIB_LIBSUFF) + AC_SUBST(SHLIB_LIBVERSION) + AC_SUBST(SHLIB_LIBS) + AC_MSG_RESULT($SHLIB_STATUS) + + # SHLIB_STATUS is either `supported' or `unsupported'. If it's + # `unsupported', turn off any default shared library building + if test "$SHLIB_STATUS" = 'unsupported'; then + opt_shared_libs=no + fi + + # shared library versioning + # quoted for m4 so I can use character classes + SHLIB_MAJOR=[`expr "$LIBVERSION" : '\([0-9]\)\..*'`] + SHLIB_MINOR=[`expr "$LIBVERSION" : '[0-9]\.\([0-9]\).*'`] + AC_SUBST(SHLIB_MAJOR) + AC_SUBST(SHLIB_MINOR) +fi + +if test "$opt_static_libs" = "yes"; then + STATIC_TARGET=static + STATIC_INSTALL_TARGET=install-static +fi +if test "$opt_shared_libs" = "yes"; then + SHARED_TARGET=shared + SHARED_INSTALL_TARGET=install-shared +fi + +AC_SUBST(STATIC_TARGET) +AC_SUBST(SHARED_TARGET) +AC_SUBST(STATIC_INSTALL_TARGET) +AC_SUBST(SHARED_INSTALL_TARGET) + +case "$host_os" in +msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file +*) BUILD_DIR=`pwd` ;; +esac + +AC_SUBST(BUILD_DIR) + +AC_SUBST(CFLAGS) +AC_SUBST(LOCAL_CFLAGS) +AC_SUBST(LOCAL_LDFLAGS) +AC_SUBST(LOCAL_DEFS) + +AC_SUBST(AR) +AC_SUBST(ARFLAGS) + +AC_SUBST(host_cpu) +AC_SUBST(host_os) + +AC_SUBST(LIBVERSION) + +AC_SUBST(TERMCAP_LIB) + +AC_OUTPUT([Makefile doc/Makefile examples/Makefile shlib/Makefile], +[ +# Makefile uses this timestamp file to record whether config.h is up to date. +echo > stamp-h +]) diff --git a/readline-4.3/display.c b/readline-4.3/display.c new file mode 100644 index 0000000..5150ea6 --- /dev/null +++ b/readline-4.3/display.c @@ -0,0 +1,2196 @@ +/* display.c -- readline redisplay facility. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "posixstat.h" + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Termcap library stuff. */ +#include "tcap.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#if defined (HACK_TERMCAP_MOTION) +extern char *_rl_term_forward_char; +#endif + +static void update_line PARAMS((char *, char *, int, int, int, int)); +static void space_to_eol PARAMS((int)); +static void delete_chars PARAMS((int)); +static void insert_some_chars PARAMS((char *, int, int)); +static void cr PARAMS((void)); + +#if defined (HANDLE_MULTIBYTE) +static int _rl_col_width PARAMS((char *, int, int)); +static int *_rl_wrapped_line; +#else +# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s)) +#endif + +static int *inv_lbreaks, *vis_lbreaks; +static int inv_lbsize, vis_lbsize; + +/* Heuristic used to decide whether it is faster to move from CUR to NEW + by backing up or outputting a carriage return and moving forward. */ +#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new))) + +/* **************************************************************** */ +/* */ +/* Display stuff */ +/* */ +/* **************************************************************** */ + +/* This is the stuff that is hard for me. I never seem to write good + display routines in C. Let's see how I do this time. */ + +/* (PWP) Well... Good for a simple line updater, but totally ignores + the problems of input lines longer than the screen width. + + update_line and the code that calls it makes a multiple line, + automatically wrapping line update. Careful attention needs + to be paid to the vertical position variables. */ + +/* Keep two buffers; one which reflects the current contents of the + screen, and the other to draw what we think the new contents should + be. Then compare the buffers, and make whatever changes to the + screen itself that we should. Finally, make the buffer that we + just drew into be the one which reflects the current contents of the + screen, and place the cursor where it belongs. + + Commands that want to can fix the display themselves, and then let + this function know that the display has been fixed by setting the + RL_DISPLAY_FIXED variable. This is good for efficiency. */ + +/* Application-specific redisplay function. */ +rl_voidfunc_t *rl_redisplay_function = rl_redisplay; + +/* Global variables declared here. */ +/* What YOU turn on when you have handled all redisplay yourself. */ +int rl_display_fixed = 0; + +int _rl_suppress_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. */ +int _rl_last_c_pos = 0; +int _rl_last_v_pos = 0; + +/* Number of lines currently on screen minus 1. */ +int _rl_vis_botlin = 0; + +/* Variables used only in this file. */ +/* The last left edge of text that was displayed. This is used when + doing horizontal scrolling. It shifts in thirds of a screenwidth. */ +static int last_lmargin; + +/* The line display buffers. One is the line currently displayed on + the screen. The other is the line about to be displayed. */ +static char *visible_line = (char *)NULL; +static char *invisible_line = (char *)NULL; + +/* A buffer for `modeline' messages. */ +static char msg_buf[128]; + +/* Non-zero forces the redisplay even if we thought it was unnecessary. */ +static int forced_display; + +/* Default and initial buffer size. Can grow. */ +static int line_size = 1024; + +/* Variables to keep track of the expanded prompt string, which may + include invisible characters. */ + +static char *local_prompt, *local_prompt_prefix; +static int prompt_visible_length, prompt_prefix_length; + +/* The number of invisible characters in the line currently being + displayed on the screen. */ +static int visible_wrap_offset; + +/* The number of invisible characters in the prompt string. Static so it + can be shared between rl_redisplay and update_line */ +static int wrap_offset; + +/* The index of the last invisible character in the prompt string. */ +static int prompt_last_invisible; + +/* The length (buffer offset) of the first line of the last (possibly + multi-line) buffer displayed on the screen. */ +static int visible_first_line_len; + +/* Number of invisible characters on the first physical line of the prompt. + Only valid when the number of physical characters in the prompt exceeds + (or is equal to) _rl_screenwidth. */ +static int prompt_invis_chars_first_line; + +static int prompt_last_screen_line; + +/* 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. */ + +/* Current implementation: + \001 (^A) start non-visible characters + \002 (^B) end non-visible characters + all characters except \001 and \002 (following a \001) are copied to + the returned string; all characters except those between \001 and + \002 are assumed to be `visible'. */ + +static char * +expand_prompt (pmt, lp, lip, niflp) + char *pmt; + int *lp, *lip, *niflp; +{ + char *r, *ret, *p; + int l, rl, last, ignoring, ninvis, invfl; + + /* Short-circuit if we can. */ + if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0) + { + r = savestring (pmt); + if (lp) + *lp = strlen (r); + return r; + } + + l = strlen (pmt); + r = ret = (char *)xmalloc (l + 1); + + invfl = 0; /* invisible chars in first line of prompt */ + + for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++) + { + /* This code strips the invisible character string markers + RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */ + if (*p == RL_PROMPT_START_IGNORE) + { + ignoring++; + continue; + } + else if (ignoring && *p == RL_PROMPT_END_IGNORE) + { + ignoring = 0; + last = r - ret - 1; + continue; + } + else + { + *r++ = *p; + if (!ignoring) + rl++; + else + ninvis++; + if (rl == _rl_screenwidth) + invfl = ninvis; + } + } + + if (rl < _rl_screenwidth) + invfl = ninvis; + + *r = '\0'; + if (lp) + *lp = rl; + if (lip) + *lip = last; + if (niflp) + *niflp = invfl; + return ret; +} + +/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from + PMT and return the rest of PMT. */ +char * +_rl_strip_prompt (pmt) + char *pmt; +{ + char *ret; + + ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL); + return ret; +} + +/* + * Expand the prompt string into the various display components, if + * necessary. + * + * local_prompt = expanded last line of string in rl_display_prompt + * (portion after the final newline) + * local_prompt_prefix = portion before last newline of rl_display_prompt, + * expanded via expand_prompt + * prompt_visible_length = number of visible characters in local_prompt + * prompt_prefix_length = number of visible characters in local_prompt_prefix + * + * This function is called once per call to readline(). It may also be + * called arbitrarily to expand the primary prompt. + * + * The return value is the number of visible characters on the last line + * of the (possibly multi-line) prompt. + */ +int +rl_expand_prompt (prompt) + char *prompt; +{ + char *p, *t; + int c; + + /* Clear out any saved values. */ + FREE (local_prompt); + FREE (local_prompt_prefix); + + local_prompt = local_prompt_prefix = (char *)0; + prompt_last_invisible = prompt_visible_length = 0; + + if (prompt == 0 || *prompt == 0) + return (0); + + p = strrchr (prompt, '\n'); + if (!p) + { + /* 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); + local_prompt_prefix = (char *)0; + return (prompt_visible_length); + } + else + { + /* The prompt spans multiple lines. */ + t = ++p; + local_prompt = expand_prompt (p, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line); + 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); + *t = c; + return (prompt_prefix_length); + } +} + +/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated + arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE + and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is + increased. If the lines have already been allocated, this ensures that + they can hold at least MINSIZE characters. */ +static void +init_line_structures (minsize) + int minsize; +{ + register int n; + + if (invisible_line == 0) /* initialize it */ + { + if (line_size < minsize) + line_size = minsize; + visible_line = (char *)xmalloc (line_size); + invisible_line = (char *)xmalloc (line_size); + } + else if (line_size < minsize) /* ensure it can hold MINSIZE chars */ + { + line_size *= 2; + if (line_size < minsize) + line_size = minsize; + visible_line = (char *)xrealloc (visible_line, line_size); + invisible_line = (char *)xrealloc (invisible_line, line_size); + } + + for (n = minsize; n < line_size; n++) + { + visible_line[n] = 0; + invisible_line[n] = 1; + } + + if (vis_lbreaks == 0) + { + /* should be enough. */ + inv_lbsize = vis_lbsize = 256; + inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int)); + vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int)); +#if defined (HANDLE_MULTIBYTE) + _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int)); +#endif + inv_lbreaks[0] = vis_lbreaks[0] = 0; + } +} + +/* Basic redisplay algorithm. */ +void +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; + char *prompt_this_line; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; + size_t wc_bytes; + int wc_width; + mbstate_t ps; + int _rl_wrapped_multicolumn = 0; +#endif + + if (!readline_echoing_p) + return; + + if (!rl_display_prompt) + rl_display_prompt = ""; + + if (invisible_line == 0) + { + init_line_structures (0); + rl_on_new_line (); + } + + /* Draw the line into the buffer. */ + c_pos = -1; + + line = invisible_line; + out = inv_botlin = 0; + + /* Mark the line as modified or not. We only do this for history + lines. */ + if (_rl_mark_modified_lines && current_history () && rl_undo_list) + { + line[out++] = '*'; + line[out] = '\0'; + } + + /* If someone thought that the redisplay was handled, but the currently + visible line has a different modification state than the one about + to become visible, then correct the caller's misconception. */ + if (visible_line[0] != invisible_line[0]) + rl_display_fixed = 0; + + /* If the prompt to be displayed is the `primary' readline prompt (the + one passed to readline()), use the values we have already expanded. + If not, use what's already in rl_display_prompt. WRAP_OFFSET is the + number of non-visible characters in the prompt string. */ + if (rl_display_prompt == rl_prompt || local_prompt) + { + int local_len = local_prompt ? strlen (local_prompt) : 0; + if (local_prompt_prefix && forced_display) + _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); + + if (local_len > 0) + { + temp = local_len + out + 2; + if (temp >= line_size) + { + line_size = (temp + 1024) - (temp % 1024); + visible_line = (char *)xrealloc (visible_line, line_size); + line = invisible_line = (char *)xrealloc (invisible_line, line_size); + } + strncpy (line + out, local_prompt, local_len); + out += local_len; + } + line[out] = '\0'; + wrap_offset = local_len - prompt_visible_length; + } + else + { + int pmtlen; + prompt_this_line = strrchr (rl_display_prompt, '\n'); + if (!prompt_this_line) + prompt_this_line = rl_display_prompt; + else + { + prompt_this_line++; + pmtlen = prompt_this_line - rl_display_prompt; /* temp var */ + if (forced_display) + { + _rl_output_some_chars (rl_display_prompt, pmtlen); + /* Make sure we are at column zero even after a newline, + regardless of the state of terminal output processing. */ + if (pmtlen < 2 || prompt_this_line[-2] != '\r') + cr (); + } + } + + pmtlen = strlen (prompt_this_line); + temp = pmtlen + out + 2; + if (temp >= line_size) + { + line_size = (temp + 1024) - (temp % 1024); + visible_line = (char *)xrealloc (visible_line, line_size); + line = invisible_line = (char *)xrealloc (invisible_line, line_size); + } + strncpy (line + out, prompt_this_line, pmtlen); + out += pmtlen; + line[out] = '\0'; + wrap_offset = prompt_invis_chars_first_line = 0; + } + +#define CHECK_INV_LBREAKS() \ + do { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + } while (0) + +#if defined (HANDLE_MULTIBYTE) +#define CHECK_LPOS() \ + do { \ + lpos++; \ + if (lpos >= _rl_screenwidth) \ + { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ + } \ + inv_lbreaks[++newlines] = out; \ + _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \ + lpos = 0; \ + } \ + } while (0) +#else +#define CHECK_LPOS() \ + do { \ + lpos++; \ + if (lpos >= _rl_screenwidth) \ + { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + inv_lbreaks[++newlines] = out; \ + lpos = 0; \ + } \ + } while (0) +#endif + + /* inv_lbreaks[i] is where line i starts in the buffer. */ + inv_lbreaks[newlines = 0] = 0; + lpos = out - wrap_offset; +#if defined (HANDLE_MULTIBYTE) + memset (_rl_wrapped_line, 0, vis_lbsize); +#endif + + /* prompt_invis_chars_first_line is the number of invisible characters in + the first physical line of the prompt. + wrap_offset - prompt_invis_chars_first_line is the number of invis + chars on the second line. */ + + /* what if lpos is already >= _rl_screenwidth before we start drawing the + contents of the command line? */ + while (lpos >= _rl_screenwidth) + { + /* fix from Darin Johnson for prompt string with + invisible characters that is longer than the screen width. The + 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) + +#else + ((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) + +#endif + ((newlines == 1) ? wrap_offset : 0); + + inv_lbreaks[++newlines] = temp; + lpos -= _rl_screenwidth; + } + + prompt_last_screen_line = newlines; + + /* Draw the rest of the line (after the prompt) into invisible_line, keeping + track of where the cursor is (c_pos), the number of the line containing + the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin). + It maintains an array of line breaks for display (inv_lbreaks). + This handles expanding tabs for display and displaying meta characters. */ + lb_linenum = 0; +#if defined (HANDLE_MULTIBYTE) + in = 0; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + memset (&ps, 0, sizeof (mbstate_t)); + wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); + } + else + wc_bytes = 1; + while (in < rl_end) +#else + for (in = 0; in < rl_end; in++) +#endif + { + c = (unsigned char)rl_line_buffer[in]; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2) + { + /* Byte sequence is invalid or shortened. Assume that the + first byte represents a character. */ + wc_bytes = 1; + /* Assume that a character occupies a single column. */ + wc_width = 1; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (wc_bytes == (size_t)0) + break; /* Found '\0' */ + else + { + temp = wcwidth (wc); + wc_width = (temp < 0) ? 1 : temp; + } + } +#endif + + if (out + 8 >= line_size) /* XXX - 8 for \t */ + { + line_size *= 2; + visible_line = (char *)xrealloc (visible_line, line_size); + invisible_line = (char *)xrealloc (invisible_line, line_size); + line = invisible_line; + } + + if (in == rl_point) + { + c_pos = out; + lb_linenum = newlines; + } + +#if defined (HANDLE_MULTIBYTE) + if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */ +#else + if (META_CHAR (c)) +#endif + { + if (_rl_output_meta_chars == 0) + { + sprintf (line + out, "\\%o", c); + + if (lpos + 4 >= _rl_screenwidth) + { + temp = _rl_screenwidth - lpos; + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out + temp; + lpos = 4 - temp; + } + else + lpos += 4; + + out += 4; + } + else + { + line[out++] = c; + CHECK_LPOS(); + } + } +#if defined (DISPLAY_TABS) + else if (c == '\t') + { + register int newout; + +#if 0 + newout = (out | (int)7) + 1; +#else + newout = out + 8 - lpos % 8; +#endif + temp = newout - out; + if (lpos + temp >= _rl_screenwidth) + { + register int temp2; + temp2 = _rl_screenwidth - lpos; + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out + temp2; + lpos = temp - temp2; + while (out < newout) + line[out++] = ' '; + } + else + { + while (out < newout) + line[out++] = ' '; + lpos += temp; + } + } +#endif + else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) + { + line[out++] = '\0'; /* XXX - sentinel */ + CHECK_INV_LBREAKS (); + inv_lbreaks[++newlines] = out; + lpos = 0; + } + else if (CTRL_CHAR (c) || c == RUBOUT) + { + line[out++] = '^'; + CHECK_LPOS(); + line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?'; + CHECK_LPOS(); + } + else + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + register int i; + + _rl_wrapped_multicolumn = 0; + + if (_rl_screenwidth < lpos + wc_width) + for (i = lpos; i < _rl_screenwidth; i++) + { + /* The space will be removed in update_line() */ + line[out++] = ' '; + _rl_wrapped_multicolumn++; + CHECK_LPOS(); + } + if (in == rl_point) + { + c_pos = out; + lb_linenum = newlines; + } + for (i = in; i < in+wc_bytes; i++) + line[out++] = rl_line_buffer[i]; + for (i = 0; i < wc_width; i++) + CHECK_LPOS(); + } + else + { + line[out++] = c; + CHECK_LPOS(); + } +#else + line[out++] = c; + CHECK_LPOS(); +#endif + } + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + in += wc_bytes; + wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); + } + else + in++; +#endif + + } + line[out] = '\0'; + if (c_pos < 0) + { + c_pos = out; + lb_linenum = newlines; + } + + inv_botlin = lb_botlin = newlines; + CHECK_INV_LBREAKS (); + inv_lbreaks[newlines+1] = out; + cursor_linenum = lb_linenum; + + /* C_POS == position in buffer where cursor should be placed. + CURSOR_LINENUM == line number where the cursor should be placed. */ + + /* PWP: now is when things get a bit hairy. The visible and invisible + line buffers are really multiple lines, which would wrap every + (screenwidth - 1) characters. Go through each in turn, finding + the changed region and updating it. The line order is top to bottom. */ + + /* If we can move the cursor up and down, then use multiple lines, + otherwise, let long lines display in a single terminal line, and + horizontally scroll it. */ + + if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up) + { + int nleft, pos, changed_screen_line; + + if (!rl_display_fixed || forced_display) + { + forced_display = 0; + + /* If we have more than a screenful of material to display, then + only display a screenful. We should display the last screen, + not the first. */ + if (out >= _rl_screenchars) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY); + else + out = _rl_screenchars - 1; + } + + /* The first line is at character position 0 in the buffer. The + second and subsequent lines start at inv_lbreaks[N], offset by + OFFSET (which has already been calculated above). */ + +#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) +#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) +#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l]) +#define VIS_CHARS(line) (visible_line + vis_lbreaks[line]) +#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line) +#define INV_LINE(line) (invisible_line + inv_lbreaks[line]) + + /* For each line in the buffer, do the updating display. */ + for (linenum = 0; linenum <= inv_botlin; linenum++) + { + update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, + VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin); + + /* 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 + implies that we completely overwrite the old visible line) + and the new line is shorter than the old. Make sure we are + at the end of the new line before clearing. */ + if (linenum == 0 && + inv_botlin == 0 && _rl_last_c_pos == out && + (wrap_offset > visible_wrap_offset) && + (_rl_last_c_pos < visible_first_line_len)) + { + nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos; + if (nleft) + _rl_clear_to_eol (nleft); + } + + /* Since the new first line is now visible, save its length. */ + if (linenum == 0) + visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset; + } + + /* We may have deleted some lines. If so, clear the left over + blank ones at the bottom out. */ + if (_rl_vis_botlin > inv_botlin) + { + char *tt; + for (; linenum <= _rl_vis_botlin; linenum++) + { + tt = VIS_CHARS (linenum); + _rl_move_vert (linenum); + _rl_move_cursor_relative (0, tt); + _rl_clear_to_eol + ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth); + } + } + _rl_vis_botlin = inv_botlin; + + /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a + different screen line during this redisplay. */ + changed_screen_line = _rl_last_v_pos != cursor_linenum; + if (changed_screen_line) + { + _rl_move_vert (cursor_linenum); + /* If we moved up to the line with the prompt using _rl_term_up, + 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) + _rl_last_c_pos += wrap_offset; + } + + /* We have to reprint the prompt if it contains invisible + characters, since it's not generally OK to just reprint + the characters from the current cursor position. But we + only need to reprint it if the cursor is before the last + invisible character in the prompt string. */ + nleft = prompt_visible_length + wrap_offset; + if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && + _rl_last_c_pos <= prompt_last_invisible && local_prompt) + { +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + if (_rl_term_cr) + tputs (_rl_term_cr, 1, _rl_output_character_function); +#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); + else + _rl_last_c_pos = nleft; + } + + /* Where on that line? And where does that line start + in the buffer? */ + pos = inv_lbreaks[cursor_linenum]; + /* nleft == number of characters in the line buffer between the + start of the line and the cursor position. */ + nleft = c_pos - pos; + + /* 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); + else + _rl_last_c_pos = nleft; + } + + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + _rl_move_cursor_relative (nleft, &invisible_line[pos]); + else if (nleft != _rl_last_c_pos) + _rl_move_cursor_relative (nleft, &invisible_line[pos]); + } + } + else /* Do horizontal scrolling. */ + { +#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) + int lmargin, ndisp, nleft, phys_c_pos, t; + + /* Always at top line. */ + _rl_last_v_pos = 0; + + /* Compute where in the buffer the displayed line should start. This + will be LMARGIN. */ + + /* The number of characters that will be displayed before the cursor. */ + ndisp = c_pos - wrap_offset; + nleft = prompt_visible_length + wrap_offset; + /* Where the new cursor position will be on the screen. This can be + longer than SCREENWIDTH; if it is, lmargin will be adjusted. */ + phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset); + t = _rl_screenwidth / 3; + + /* If the number of characters had already exceeded the screenwidth, + last_lmargin will be > 0. */ + + /* If the number of characters to be displayed is more than the screen + width, compute the starting offset so that the cursor is about + two-thirds of the way across the screen. */ + if (phys_c_pos > _rl_screenwidth - 2) + { + lmargin = c_pos - (2 * t); + if (lmargin < 0) + lmargin = 0; + /* If the left margin would be in the middle of a prompt with + invisible characters, don't display the prompt at all. */ + if (wrap_offset && lmargin > 0 && lmargin < nleft) + lmargin = nleft; + } + else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */ + lmargin = 0; + else if (phys_c_pos < 1) + { + /* If we are moving back towards the beginning of the line and + the last margin is no longer correct, compute a new one. */ + lmargin = ((c_pos - 1) / t) * t; /* XXX */ + if (wrap_offset && lmargin > 0 && lmargin < nleft) + lmargin = nleft; + } + else + lmargin = last_lmargin; + + /* If the first character on the screen isn't the first character + in the display line, indicate this with a special character. */ + if (lmargin > 0) + line[lmargin] = '<'; + + /* If SCREENWIDTH characters starting at LMARGIN do not encompass + the whole line, indicate that with a special character at the + right edge of the screen. If LMARGIN is 0, we need to take the + wrap offset into account. */ + t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; + if (t < out) + line[t - 1] = '>'; + + if (!rl_display_fixed || forced_display || lmargin != last_lmargin) + { + forced_display = 0; + update_line (&visible_line[last_lmargin], + &invisible_line[lmargin], + 0, + _rl_screenwidth + visible_wrap_offset, + _rl_screenwidth + (lmargin ? 0 : wrap_offset), + 0); + + /* If the visible new line is shorter than the old, but the number + of invisible characters is greater, and we are at the end of + the new line, we need to clear to eol. */ + t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset); + if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) && + (_rl_last_c_pos == out) && + t < visible_first_line_len) + { + nleft = _rl_screenwidth - t; + _rl_clear_to_eol (nleft); + } + visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset); + if (visible_first_line_len > _rl_screenwidth) + visible_first_line_len = _rl_screenwidth; + + _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]); + last_lmargin = lmargin; + } + } + fflush (rl_outstream); + + /* Swap visible and non-visible lines. */ + { + char *vtemp = visible_line; + int *itemp = vis_lbreaks, ntemp = vis_lbsize; + + visible_line = invisible_line; + invisible_line = vtemp; + + vis_lbreaks = inv_lbreaks; + inv_lbreaks = itemp; + + vis_lbsize = inv_lbsize; + inv_lbsize = ntemp; + + rl_display_fixed = 0; + /* If we are displaying on a single line, and last_lmargin is > 0, we + are not displaying any invisible characters, so set visible_wrap_offset + to 0. */ + if (_rl_horizontal_scroll_mode && last_lmargin) + visible_wrap_offset = 0; + else + visible_wrap_offset = wrap_offset; + } +} + +/* PWP: update_line() is based on finding the middle difference of each + line on the screen; vis: + + /old first difference + /beginning of line | /old last same /old EOL + v v v v +old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as +new: eddie> Oh, my little buggy says to me, as lurgid as + ^ ^ ^ ^ + \beginning of line | \new last same \new end of line + \new first difference + + All are character pointers for the sake of speed. Special cases for + no differences, as well as for end of line additions must be handled. + + Could be made even smarter, but this works well enough */ +static void +update_line (old, new, current_line, omax, nmax, inv_botlin) + register char *old, *new; + int current_line, omax, nmax, inv_botlin; +{ + register char *ofd, *ols, *oe, *nfd, *nls, *ne; + int temp, lendiff, wsatend, od, nd; + int current_invis_chars; + int col_lendiff, col_temp; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps_new, ps_old; + int new_offset, old_offset, tmp; +#endif + + /* If we're at the right edge of a terminal that supports xn, we're + ready to wrap around, so do so. This fixes problems with knowing + 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 (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode + && _rl_last_v_pos == current_line - 1) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + wchar_t wc; + mbstate_t ps; + int tempwidth, bytes; + size_t ret; + + /* This fixes only double-column characters, but if the wrapped + character comsumes more than three columns, spaces will be + inserted in the string buffer. */ + if (_rl_wrapped_line[current_line] > 0) + _rl_clear_to_eol (_rl_wrapped_line[current_line]); + + memset (&ps, 0, sizeof (mbstate_t)); + ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps); + if (ret == (size_t)-1 || ret == (size_t)-2) + { + tempwidth = 1; + ret = 1; + } + else if (ret == 0) + tempwidth = 0; + else + tempwidth = wcwidth (wc); + + if (tempwidth > 0) + { + int count; + bytes = ret; + for (count = 0; count < bytes; count++) + putc (new[count], rl_outstream); + _rl_last_c_pos = tempwidth; + _rl_last_v_pos++; + memset (&ps, 0, sizeof (mbstate_t)); + ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps); + if (ret != 0 && bytes != 0) + { + if (ret == (size_t)-1 || ret == (size_t)-2) + memmove (old+bytes, old+1, strlen (old+1)); + else + memmove (old+bytes, old+ret, strlen (old+ret)); + memcpy (old, new, bytes); + } + } + else + { + putc (' ', rl_outstream); + _rl_last_c_pos = 1; + _rl_last_v_pos++; + if (old[0] && new[0]) + old[0] = new[0]; + } + } + else +#endif + { + if (new[0]) + putc (new[0], rl_outstream); + else + putc (' ', rl_outstream); + _rl_last_c_pos = 1; /* XXX */ + _rl_last_v_pos++; + if (old[0] && new[0]) + old[0] = new[0]; + } + } + + + /* Find first difference. */ +#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); ) + { + 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 +#endif + for (ofd = old, nfd = new; + (ofd - old < omax) && *ofd && (*ofd == *nfd); + ofd++, nfd++) + ; + + /* Move to the end of the screen line. ND and OD are used to keep track + of the distance between ne and new and oe and old, respectively, to + move a subtraction out of each loop. */ + for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++); + for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++); + + /* If no difference, continue to next line. */ + if (ofd == oe && nfd == ne) + return; + + wsatend = 1; /* flag for trailing whitespace */ + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); + nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY); + while ((ols > ofd) && (nls > nfd)) + { + memset (&ps_old, 0, sizeof (mbstate_t)); + memset (&ps_new, 0, sizeof (mbstate_t)); + + _rl_adjust_point (old, ols - old, &ps_old); + _rl_adjust_point (new, nls - new, &ps_new); + + if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0) + break; + + if (*ols == ' ') + wsatend = 0; + + ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY); + nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY); + } + } + else + { +#endif /* HANDLE_MULTIBYTE */ + ols = oe - 1; /* find last same */ + nls = ne - 1; + while ((ols > ofd) && (nls > nfd) && (*ols == *nls)) + { + if (*ols != ' ') + wsatend = 0; + ols--; + nls--; + } +#if defined (HANDLE_MULTIBYTE) + } +#endif + + if (wsatend) + { + ols = oe; + nls = ne; + } +#if defined (HANDLE_MULTIBYTE) + /* This may not work for stateful encoding, but who cares? To handle + stateful encoding properly, we have to scan each string from the + beginning and compare. */ + else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0) +#else + else if (*ols != *nls) +#endif + { + if (*ols) /* don't step past the NUL */ + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY); + else + ols++; + } + if (*nls) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY); + else + nls++; + } + } + + /* count of invisible characters in the current invisible line. */ + current_invis_chars = W_OFFSET (current_line, wrap_offset); + if (_rl_last_v_pos != current_line) + { + _rl_move_vert (current_line); + if (current_line == 0 && visible_wrap_offset) + _rl_last_c_pos += visible_wrap_offset; + } + + /* If this is the first line and there are invisible characters in the + prompt string, and the prompt string has not changed, and the current + cursor position is before the last invisible character in the prompt, + and the index of the character to move to is past the end of the prompt + string, then redraw the entire prompt string. We can only do this + reliably if the terminal supports a `cr' capability. + + This is not an efficiency hack -- there is a problem with redrawing + portions of the prompt string if they contain terminal escape + sequences (like drawing the `unbold' sequence without a corresponding + `bold') that manifests itself on certain terminals. */ + + lendiff = local_prompt ? strlen (local_prompt) : 0; + od = ofd - old; /* index of first difference in visible line */ + if (current_line == 0 && !_rl_horizontal_scroll_mode && + _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 && + od >= lendiff && _rl_last_c_pos <= prompt_last_invisible) + { +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#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); + else + _rl_last_c_pos = lendiff; + } + + _rl_move_cursor_relative (od, old); + + /* if (len (new) > len (old)) + lendiff == difference in buffer + col_lendiff == difference on screen + When not using multibyte characters, these are equal */ + lendiff = (nls - nfd) - (ols - ofd); + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old); + else + col_lendiff = lendiff; + + /* If we are changing the number of invisible characters in a line, and + the spot of first difference is before the end of the invisible chars, + lendiff needs to be adjusted. */ + if (current_line == 0 && !_rl_horizontal_scroll_mode && + current_invis_chars != visible_wrap_offset) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + lendiff += visible_wrap_offset - current_invis_chars; + col_lendiff += visible_wrap_offset - current_invis_chars; + } + else + { + lendiff += visible_wrap_offset - current_invis_chars; + col_lendiff = lendiff; + } + } + + /* Insert (diff (len (old), len (new)) ch. */ + temp = ne - nfd; + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + col_temp = _rl_col_width (new, nfd - new, ne - new); + else + col_temp = temp; + + if (col_lendiff > 0) /* XXX - was lendiff */ + { + /* Non-zero if we're increasing the number of lines. */ + int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; + /* Sometimes it is cheaper to print the characters rather than + use the terminal's capabilities. If we're growing the number + of lines, make sure we actually cause the new line to wrap + around on auto-wrapping terminals. */ + if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl)) + { + /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and + _rl_horizontal_scroll_mode == 1, inserting the characters with + _rl_term_IC or _rl_term_ic will screw up the screen because of the + invisible characters. We need to just draw them. */ + if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 || + lendiff <= prompt_visible_length || !current_invis_chars)) + { + insert_some_chars (nfd, lendiff, col_lendiff); + _rl_last_c_pos += col_lendiff; + } + else if (*ols == 0) + { + /* At the end of a line the characters do not have to + be "inserted". They can just be placed on the screen. */ + /* However, this screws up the rest of this block, which + assumes you've done the insert because you can. */ + _rl_output_some_chars (nfd, lendiff); + _rl_last_c_pos += col_lendiff; + } + else + { + /* We have horizontal scrolling and we are not inserting at + the end. We have invisible characters in this line. This + is a dumb update. */ + _rl_output_some_chars (nfd, temp); + _rl_last_c_pos += col_temp; + return; + } + /* Copy (new) chars to screen from first diff to last match. */ + temp = nls - nfd; + if ((temp - lendiff) > 0) + { + _rl_output_some_chars (nfd + lendiff, temp - lendiff); +#if 0 + _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff; +#else + _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); +#endif + } + } + else + { + /* cannot insert chars, write to EOL */ + _rl_output_some_chars (nfd, temp); + _rl_last_c_pos += col_temp; + } + } + else /* Delete characters from line. */ + { + /* If possible and inexpensive to use terminal deletion, then do so. */ + if (_rl_term_dc && (2 * col_temp) >= -col_lendiff) + { + /* If all we're doing is erasing the invisible characters in the + prompt string, don't bother. It screws up the assumptions + about what's on the screen. */ + if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 && + -lendiff == visible_wrap_offset) + col_lendiff = 0; + + if (col_lendiff) + delete_chars (-col_lendiff); /* delete (diff) characters */ + + /* Copy (new) chars to screen from first diff to last match */ + temp = nls - nfd; + if (temp > 0) + { + _rl_output_some_chars (nfd, temp); + _rl_last_c_pos += _rl_col_width (nfd, 0, temp);; + } + } + /* Otherwise, print over the existing material. */ + else + { + if (temp > 0) + { + _rl_output_some_chars (nfd, temp); + _rl_last_c_pos += col_temp; + } + lendiff = (oe - old) - (ne - new); + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new); + else + col_lendiff = lendiff; + + if (col_lendiff) + { + if (_rl_term_autowrap && current_line < inv_botlin) + space_to_eol (col_lendiff); + else + _rl_clear_to_eol (col_lendiff); + } + } + } +} + +/* Tell the update routines that we have moved onto a new (empty) line. */ +int +rl_on_new_line () +{ + if (visible_line) + visible_line[0] = '\0'; + + _rl_last_c_pos = _rl_last_v_pos = 0; + _rl_vis_botlin = last_lmargin = 0; + if (vis_lbreaks) + vis_lbreaks[0] = vis_lbreaks[1] = 0; + visible_wrap_offset = 0; + return 0; +} + +/* 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. */ +int +rl_on_new_line_with_prompt () +{ + int prompt_size, i, l, real_screenwidth, newlines; + char *prompt_last_line; + + /* Initialize visible_line and invisible_line to ensure that they can hold + the already-displayed prompt. */ + prompt_size = strlen (rl_prompt) + 1; + init_line_structures (prompt_size); + + /* Make sure the line structures hold the already-displayed prompt for + redisplay. */ + strcpy (visible_line, rl_prompt); + strcpy (invisible_line, rl_prompt); + + /* If the prompt contains newlines, take the last tail. */ + prompt_last_line = strrchr (rl_prompt, '\n'); + if (!prompt_last_line) + prompt_last_line = rl_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); + else + _rl_last_c_pos = l; + + /* Dissect prompt_last_line into screen lines. Note that here we have + to use the real screenwidth. Readline's notion of screenwidth might be + one less, see terminal.c. */ + real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1); + _rl_last_v_pos = l / real_screenwidth; + /* If the prompt length is a multiple of real_screenwidth, we don't know + whether the cursor is at the end of the last line, or already at the + beginning of the next line. Output a newline just to be safe. */ + if (l > 0 && (l % real_screenwidth) == 0) + _rl_output_some_chars ("\n", 1); + last_lmargin = 0; + + newlines = 0; i = 0; + while (i <= l) + { + _rl_vis_botlin = newlines; + vis_lbreaks[newlines++] = i; + i += real_screenwidth; + } + vis_lbreaks[newlines] = l; + visible_wrap_offset = 0; + + return 0; +} + +/* Actually update the display, period. */ +int +rl_forced_update_display () +{ + if (visible_line) + { + register char *temp = visible_line; + + while (*temp) + *temp++ = '\0'; + } + rl_on_new_line (); + forced_display++; + (*rl_redisplay_function) (); + return 0; +} + +/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices. + DATA is the contents of the screen line of interest; i.e., where + the movement is being done. */ +void +_rl_move_cursor_relative (new, data) + int new; + const char *data; +{ + register int i; + + /* If we don't have to do anything, then return. */ +#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. */ + if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return; +#else + if (_rl_last_c_pos == new) return; +#endif + + /* 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 (new == 0 || CR_FASTER (new, _rl_last_c_pos) || + (_rl_term_autowrap && i == _rl_screenwidth)) + { +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif /* !__MSDOS__ */ + _rl_last_c_pos = 0; + } + + if (_rl_last_c_pos < new) + { + /* Move the cursor forward. We do it by printing the command + to move the cursor forward if there is one, else print that + portion of the output buffer again. Which is cheaper? */ + + /* The above comment is left here for posterity. It is faster + to print one character (non-control) than to print a control + sequence telling the terminal to move forward one character. + That kind of control is for people who don't know what the + data is underneath the cursor. */ +#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); + } + else + for (i = _rl_last_c_pos; i < new; i++) + putc (data[i], rl_outstream); + +#else /* !HACK_TERMCAP_MOTION */ + + 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); + } + else + for (i = _rl_last_c_pos; 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) + { + tputs (_rl_term_cr, 1, _rl_output_character_function); + for (i = 0; i < new; i++) + putc (data[i], rl_outstream); + } + else + _rl_backspace (_rl_last_c_pos - new); + } + + 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; +} + +/* PWP: move the cursor up or down. */ +void +_rl_move_vert (to) + int to; +{ + register int delta, i; + + if (_rl_last_v_pos == to || to > _rl_screenheight) + return; + + if ((delta = to - _rl_last_v_pos) > 0) + { + for (i = 0; i < delta; i++) + putc ('\n', rl_outstream); +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif + _rl_last_c_pos = 0; + } + else + { /* delta < 0 */ + if (_rl_term_up && *_rl_term_up) + for (i = 0; i < -delta; i++) + tputs (_rl_term_up, 1, _rl_output_character_function); + } + + _rl_last_v_pos = to; /* Now TO is here */ +} + +/* Physically print C on rl_outstream. This is for functions which know + how to optimize the display. Return the number of characters output. */ +int +rl_show_char (c) + int c; +{ + int n = 1; + if (META_CHAR (c) && (_rl_output_meta_chars == 0)) + { + fprintf (rl_outstream, "M-"); + n += 2; + c = UNMETA (c); + } + +#if defined (DISPLAY_TABS) + if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT) +#else + if (CTRL_CHAR (c) || c == RUBOUT) +#endif /* !DISPLAY_TABS */ + { + fprintf (rl_outstream, "C-"); + n += 2; + c = CTRL_CHAR (c) ? UNCTRL (c) : '?'; + } + + putc (c, rl_outstream); + fflush (rl_outstream); + return n; +} + +int +rl_character_len (c, pos) + register int c, pos; +{ + unsigned char uc; + + uc = (unsigned char)c; + + if (META_CHAR (uc)) + return ((_rl_output_meta_chars == 0) ? 4 : 1); + + if (uc == '\t') + { +#if defined (DISPLAY_TABS) + return (((pos | 7) + 1) - pos); +#else + return (2); +#endif /* !DISPLAY_TABS */ + } + + if (CTRL_CHAR (c) || c == RUBOUT) + return (2); + + return ((ISPRINT (uc)) ? 1 : 2); +} + +/* How to print things in the "echo-area". The prompt is treated as a + mini-modeline. */ + +#if defined (USE_VARARGS) +int +#if defined (PREFER_STDARG) +rl_message (const char *format, ...) +#else +rl_message (va_alist) + va_dcl +#endif +{ + va_list args; +#if defined (PREFER_VARARGS) + char *format; +#endif + +#if defined (PREFER_STDARG) + va_start (args, format); +#else + va_start (args); + format = va_arg (args, char *); +#endif + +#if defined (HAVE_VSNPRINTF) + vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args); +#else + vsprintf (msg_buf, format, args); + msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */ +#endif + va_end (args); + + rl_display_prompt = msg_buf; + (*rl_redisplay_function) (); + return 0; +} +#else /* !USE_VARARGS */ +int +rl_message (format, arg1, arg2) + char *format; +{ + sprintf (msg_buf, format, arg1, arg2); + msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */ + rl_display_prompt = msg_buf; + (*rl_redisplay_function) (); + return 0; +} +#endif /* !USE_VARARGS */ + +/* How to clear things from the "echo-area". */ +int +rl_clear_message () +{ + rl_display_prompt = rl_prompt; + (*rl_redisplay_function) (); + return 0; +} + +int +rl_reset_line_state () +{ + rl_on_new_line (); + + rl_display_prompt = rl_prompt ? rl_prompt : ""; + forced_display = 1; + 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_last_invisible = prompt_last_invisible; + saved_visible_length = prompt_visible_length; + + local_prompt = local_prompt_prefix = (char *)0; + prompt_last_invisible = prompt_visible_length = 0; +} + +void +rl_restore_prompt () +{ + FREE (local_prompt); + FREE (local_prompt_prefix); + + local_prompt = saved_local_prompt; + local_prompt_prefix = saved_local_prefix; + prompt_last_invisible = saved_last_invisible; + prompt_visible_length = saved_visible_length; +} + +char * +_rl_make_prompt_for_search (pchar) + int pchar; +{ + int len; + char *pmt; + + rl_save_prompt (); + + if (saved_local_prompt == 0) + { + len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; + pmt = (char *)xmalloc (len + 2); + if (len) + strcpy (pmt, rl_prompt); + pmt[len] = pchar; + pmt[len+1] = '\0'; + } + else + { + len = *saved_local_prompt ? strlen (saved_local_prompt) : 0; + pmt = (char *)xmalloc (len + 2); + if (len) + strcpy (pmt, saved_local_prompt); + pmt[len] = pchar; + pmt[len+1] = '\0'; + local_prompt = savestring (pmt); + prompt_last_invisible = saved_last_invisible; + prompt_visible_length = saved_visible_length + 1; + } + return pmt; +} + +/* Quick redisplay hack when erasing characters at the end of the line. */ +void +_rl_erase_at_end_of_line (l) + int l; +{ + register int i; + + _rl_backspace (l); + for (i = 0; i < l; i++) + putc (' ', rl_outstream); + _rl_backspace (l); + for (i = 0; i < l; i++) + visible_line[--_rl_last_c_pos] = '\0'; + rl_display_fixed++; +} + +/* Clear to the end of the line. COUNT is the minimum + number of character spaces to clear, */ +void +_rl_clear_to_eol (count) + int count; +{ + if (_rl_term_clreol) + tputs (_rl_term_clreol, 1, _rl_output_character_function); + else if (count) + space_to_eol (count); +} + +/* Clear to the end of the line using spaces. COUNT is the minimum + number of character spaces to clear, */ +static void +space_to_eol (count) + int count; +{ + register int i; + + for (i = 0; i < count; i++) + putc (' ', rl_outstream); + + _rl_last_c_pos += count; +} + +void +_rl_clear_screen () +{ + if (_rl_term_clrpag) + tputs (_rl_term_clrpag, 1, _rl_output_character_function); + else + rl_crlf (); +} + +/* Insert COUNT characters from STRING to the output stream at column COL. */ +static void +insert_some_chars (string, count, col) + char *string; + int count, col; +{ + /* DEBUGGING */ + if (MB_CUR_MAX == 1 || rl_byte_oriented) + if (count != col) + fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col); + + /* If IC is defined, then we do not have to "enter" insert mode. */ + if (_rl_term_IC) + { + char *buffer; + + buffer = tgoto (_rl_term_IC, 0, col); + tputs (buffer, 1, _rl_output_character_function); + _rl_output_some_chars (string, count); + } + else + { + register int i; + + /* If we have to turn on insert-mode, then do so. */ + if (_rl_term_im && *_rl_term_im) + tputs (_rl_term_im, 1, _rl_output_character_function); + + /* If there is a special command for inserting characters, then + use that first to open up the space. */ + if (_rl_term_ic && *_rl_term_ic) + { + for (i = col; i--; ) + tputs (_rl_term_ic, 1, _rl_output_character_function); + } + + /* Print the text. */ + _rl_output_some_chars (string, count); + + /* If there is a string to turn off insert mode, we had best use + it now. */ + if (_rl_term_ei && *_rl_term_ei) + tputs (_rl_term_ei, 1, _rl_output_character_function); + } +} + +/* Delete COUNT characters from the display line. */ +static void +delete_chars (count) + int count; +{ + if (count > _rl_screenwidth) /* XXX */ + return; + + if (_rl_term_DC && *_rl_term_DC) + { + char *buffer; + buffer = tgoto (_rl_term_DC, count, count); + tputs (buffer, count, _rl_output_character_function); + } + else + { + if (_rl_term_dc && *_rl_term_dc) + while (count--) + tputs (_rl_term_dc, 1, _rl_output_character_function); + } +} + +void +_rl_update_final () +{ + int full_lines; + + full_lines = 0; + /* If the cursor is the only thing on an otherwise-blank last line, + compensate so we don't print an extra CRLF. */ + if (_rl_vis_botlin && _rl_last_c_pos == 0 && + visible_line[vis_lbreaks[_rl_vis_botlin]] == 0) + { + _rl_vis_botlin--; + full_lines = 1; + } + _rl_move_vert (_rl_vis_botlin); + /* If we've wrapped lines, remove the final xterm line-wrap flag. */ + if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth)) + { + char *last_line; + + last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; + _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); + _rl_clear_to_eol (0); + putc (last_line[_rl_screenwidth - 1], rl_outstream); + } + _rl_vis_botlin = 0; + rl_crlf (); + fflush (rl_outstream); + rl_display_fixed++; +} + +/* Move to the start of the current line. */ +static void +cr () +{ + if (_rl_term_cr) + { +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif + _rl_last_c_pos = 0; + } +} + +/* Redraw the last line of a multi-line prompt that may possibly contain + terminal escape sequences. Called with the cursor at column 0 of the + line to draw the prompt on. */ +static void +redraw_prompt (t) + char *t; +{ + char *oldp, *oldl, *oldlprefix; + int oldlen, oldlast, oldplen, oldninvis; + + /* 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_display_prompt = t; + local_prompt = expand_prompt (t, &prompt_visible_length, + &prompt_last_invisible, + &prompt_invis_chars_first_line); + 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; +} + +/* Redisplay the current line after a SIGWINCH is received. */ +void +_rl_redisplay_after_sigwinch () +{ + char *t; + + /* Clear the current line and put the cursor at column 0. Make sure + the right thing happens if we have wrapped to a new screen line. */ + if (_rl_term_cr) + { +#if defined (__MSDOS__) + putc ('\r', rl_outstream); +#else + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif + _rl_last_c_pos = 0; +#if defined (__MSDOS__) + space_to_eol (_rl_screenwidth); + putc ('\r', rl_outstream); +#else + if (_rl_term_clreol) + tputs (_rl_term_clreol, 1, _rl_output_character_function); + else + { + space_to_eol (_rl_screenwidth); + tputs (_rl_term_cr, 1, _rl_output_character_function); + } +#endif + if (_rl_last_v_pos > 0) + _rl_move_vert (0); + } + else + rl_crlf (); + + /* Redraw only the last line of a multi-line prompt. */ + t = strrchr (rl_display_prompt, '\n'); + if (t) + redraw_prompt (++t); + else + rl_forced_update_display (); +} + +void +_rl_clean_up_for_exit () +{ + if (readline_echoing_p) + { + _rl_move_vert (_rl_vis_botlin); + _rl_vis_botlin = 0; + fflush (rl_outstream); + rl_restart_output (1, 0); + } +} + +void +_rl_erase_entire_line () +{ + cr (); + _rl_clear_to_eol (0); + cr (); + fflush (rl_outstream); +} + +/* return the `current display line' of the cursor -- the number of lines to + move up to get to the first screen line of the current readline line. */ +int +_rl_current_display_line () +{ + int ret, nleft; + + /* Find out whether or not there might be invisible characters in the + editing buffer. */ + if (rl_display_prompt == rl_prompt) + nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length; + else + nleft = _rl_last_c_pos - _rl_screenwidth; + + if (nleft > 0) + ret = 1 + nleft / _rl_screenwidth; + else + ret = 0; + + return ret; +} + +#if defined (HANDLE_MULTIBYTE) +/* Calculate the number of screen columns occupied by STR from START to END. + In the case of multibyte characters with stateful encoding, we have to + scan from the beginning of the string to take the state into account. */ +static int +_rl_col_width (str, start, end) + char *str; + int start, end; +{ + wchar_t wc; + mbstate_t ps = {0}; + int tmp, point, width, max; + + if (end <= start) + return 0; + + point = 0; + max = end; + + while (point < start) + { + tmp = mbrlen (str + point, max, &ps); + if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) + { + /* In this case, the bytes are invalid or too short to compose a + multibyte character, so we assume that the first byte represents + a single character. */ + point++; + max--; + + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (tmp == 0) + break; /* Found '\0' */ + else + { + point += tmp; + max -= tmp; + } + } + + /* If START is not a byte that starts a character, then POINT will be + greater than START. In this case, assume that (POINT - START) gives + a byte count that is the number of columns of difference. */ + width = point - start; + + while (point < end) + { + tmp = mbrtowc (&wc, str + point, max, &ps); + if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) + { + /* In this case, the bytes are invalid or too short to compose a + multibyte character, so we assume that the first byte represents + a single character. */ + point++; + max--; + + /* and assume that the byte occupies a single column. */ + width++; + + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (tmp == 0) + break; /* Found '\0' */ + else + { + point += tmp; + max -= tmp; + tmp = wcwidth(wc); + width += (tmp >= 0) ? tmp : 1; + } + } + + width += point - end; + + return width; +} +#endif /* HANDLE_MULTIBYTE */ + diff --git a/readline-4.3/doc/Makefile.in b/readline-4.3/doc/Makefile.in new file mode 100644 index 0000000..8a85ae1 --- /dev/null +++ b/readline-4.3/doc/Makefile.in @@ -0,0 +1,234 @@ +# This makefile for Readline library documentation is in -*- text -*- mode. +# Emacs likes it that way. + +# Copyright (C) 1996 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 USA. + +topdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = .:@srcdir@ + +prefix = @prefix@ +infodir = @infodir@ + +mandir = @mandir@ +manpfx = man + +man1ext = .1 +man1dir = $(mandir)/$(manpfx)1 +man3ext = .3 +man3dir = $(mandir)/$(manpfx)3 + +# set this to a value to have the HTML documentation installed +htmldir = + +# Support an alternate destination root directory for package building +DESTDIR = + +SHELL = @MAKE_SHELL@ +RM = rm -f + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +BUILD_DIR = @BUILD_DIR@ +TEXINPUTDIR = $(srcdir) + +MAKEINFO = LANGUAGE= makeinfo +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 +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 + +# This should be a program that converts troff to an ascii-readable format +NROFF = groff -Tascii + +# This should be a program that converts troff to postscript +GROFF = groff + +DVIOBJ = readline.dvi history.dvi rluserman.dvi +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 + +INTERMEDIATE_OBJ = rlman.dvi hist.dvi rluserman.dvi + +DIST_DOCS = $(DVIOBJ) $(PSOBJ) $(HTMLOBJ) $(INFOOBJ) $(TEXTOBJ) + +.SUFFIXES: .0 .3 .ps .txt .dvi + +.3.0: + $(RM) $@ + -${NROFF} -man $< > $@ + +all: info dvi html ps text +nodvi: info html text + +readline.dvi: $(RLSRC) + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texinfo + mv rlman.dvi readline.dvi + +readline.info: $(RLSRC) + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texinfo + +rluserman.dvi: $(RLSRC) + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texinfo + +rluserman.info: $(RLSRC) + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texinfo + +history.dvi: ${HISTSRC} + TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/hist.texinfo + mv hist.dvi history.dvi + +history.info: ${HISTSRC} + $(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/hist.texinfo + +readline.ps: readline.dvi + $(RM) $@ + $(DVIPS) readline.dvi + +rluserman.ps: rluserman.dvi + $(RM) $@ + $(DVIPS) rluserman.dvi + +history.ps: history.dvi + $(RM) $@ + $(DVIPS) 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 + sed -e 's:rlman.html:readline.html:g' rlman.html > readline.html + +rluserman.html: ${RLSRC} + $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texinfo + +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) + +readline.0: readline.3 + +readline_3.ps: readline.3 + ${RM} $@ + ${GROFF} -man < $(srcdir)/readline.3 > $@ + +history.0: history.3 + +history_3.ps: history.3 + ${RM} $@ + ${GROFF} -man < $(srcdir)/history.3 > $@ + +clean: + $(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \ + *.fns *.kys *.tps *.vrs *.bt *.bts *.o core *.core + +mostlyclean: clean + +distclean: clean maybe-clean + $(RM) $(INTERMEDIATE_OBJ) + $(RM) Makefile + +maybe-clean: + -if test "X$(topdir)" != "X$(BUILD_DIR)"; then \ + $(RM) $(DIST_DOCS); \ + fi + +maintainer-clean: clean + $(RM) $(DIST_DOCS) + $(RM) $(INTERMEDIATE_OBJ) + $(RM) Makefile + +installdirs: $(topdir)/support/mkdirs + -$(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) + -if test -n "${htmldir}" ; then \ + $(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(htmldir) ; \ + fi + +install: installdirs + if test -f readline.info; then \ + ${INSTALL_DATA} readline.info $(DESTDIR)$(infodir)/readline.info; \ + else \ + ${INSTALL_DATA} $(srcdir)/readline.info $(DESTDIR)$(infodir)/readline.info; \ + fi + if test -f rluserman.info; then \ + ${INSTALL_DATA} rluserman.info $(DESTDIR)$(infodir)/rluserman.info; \ + else \ + ${INSTALL_DATA} $(srcdir)/rluserman.info $(DESTDIR)$(infodir)/rluserman.info; \ + fi + if test -f history.info; then \ + ${INSTALL_DATA} history.info $(DESTDIR)$(infodir)/history.info; \ + else \ + ${INSTALL_DATA} $(srcdir)/history.info $(DESTDIR)$(infodir)/history.info; \ + fi + -if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ + install-info --dir-file=$(DESTDIR)$(infodir)/dir \ + $(DESTDIR)$(infodir)/readline.info ; \ + install-info --dir-file=$(DESTDIR)$(infodir)/dir \ + $(DESTDIR)$(infodir)/history.info ; \ + install-info --dir-file=$(DESTDIR)$(infodir)/dir \ + $(DESTDIR)$(infodir)/rluserman.info ; \ + else true; fi + -${INSTALL_DATA} $(srcdir)/readline.3 $(DESTDIR)$(man3dir)/readline$(man3ext) + -${INSTALL_DATA} $(srcdir)/history.3 $(DESTDIR)$(man3dir)/history$(man3ext) + -if test -n "${htmldir}" ; then \ + if test -f readline.html; then \ + ${INSTALL_DATA} readline.html $(DESTDIR)$(htmldir)/readline.html; \ + else \ + ${INSTALL_DATA} $(srcdir)/readline.html $(DESTDIR)$(htmldir)/readline.html; \ + fi ; \ + if test -f history.html; then \ + ${INSTALL_DATA} history.html $(DESTDIR)$(htmldir)/history.html; \ + else \ + ${INSTALL_DATA} $(srcdir)/history.html $(DESTDIR)$(htmldir)/history.html; \ + fi ; \ + if test -f rluserman.html; then \ + ${INSTALL_DATA} rluserman.html $(DESTDIR)$(htmldir)/rluserman.html; \ + else \ + ${INSTALL_DATA} $(srcdir)/rluserman.html $(DESTDIR)$(htmldir)/rluserman.html; \ + fi ; \ + fi + +uninstall: + $(RM) $(DESTDIR)$(infodir)/readline.info + $(RM) $(DESTDIR)$(infodir)/rluserman.info + $(RM) $(DESTDIR)$(infodir)/history.info + $(RM) $(DESTDIR)$(man3dir)/readline$(man3ext) + $(RM) $(DESTDIR)$(man3dir)/history$(man3ext) + -if test -n "${htmldir}" ; then \ + $(RM) $(DESTDIR)$(htmldir)/readline.html ; \ + $(RM) $(DESTDIR)$(htmldir)/rluserman.html ; \ + $(RM) $(DESTDIR)$(htmldir)/history.html ; \ + fi diff --git a/readline-4.3/doc/hist.texinfo b/readline-4.3/doc/hist.texinfo new file mode 100644 index 0000000..63ceb16 --- /dev/null +++ b/readline-4.3/doc/hist.texinfo @@ -0,0 +1,110 @@ +\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-4.3/doc/history.3 b/readline-4.3/doc/history.3 new file mode 100644 index 0000000..ed0cb9f --- /dev/null +++ b/readline-4.3/doc/history.3 @@ -0,0 +1,640 @@ +.\" +.\" MAN PAGE COMMENTS to +.\" +.\" Chet Ramey +.\" Information Network Services +.\" Case Western Reserve University +.\" chet@ins.CWRU.Edu +.\" +.\" Last Change: Thu Jan 31 16:08:07 EST 2002 +.\" +.TH HISTORY 3 "2002 January 31" "GNU History 4.3" +.\" +.\" File Name macro. This used to be `.PN', for Path Name, +.\" but Sun doesn't seem to like that very much. +.\" +.de FN +\fI\|\\$1\|\fP +.. +.ds lp \fR\|(\fP +.ds rp \fR\|)\fP +.\" FnN return-value fun-name N arguments +.de Fn1 +\fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3\fP\\*(rp +.br +.. +.de Fn2 +.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4\fP\\*(rp +.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4\fP\\*(rp +.br +.. +.de Fn3 +.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4,\|\\$5\fP\|\\*(rp +.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4, \\$5\fP\\*(rp +.br +.. +.de Vb +\fI\\$1\fP \fB\\$2\fP +.br +.. +.SH NAME +history \- GNU History Library +.SH COPYRIGHT +.if t The GNU History Library is Copyright \(co 1989-2002 by the Free Software Foundation, Inc. +.if n The GNU History Library is Copyright (C) 1989-2002 by the Free Software Foundation, Inc. +.SH DESCRIPTION +Many programs read input from the user a line at a time. The 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. +.PP +.SH "HISTORY EXPANSION" +.PP +The history library supports a history expansion feature that +is identical to the history expansion in +.BR bash. +This section describes what syntax features are available. +.PP +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. +.PP +History expansion is usually performed immediately after a complete line +is read. +It takes place in two parts. +The first is to determine which line from the history list +to use during substitution. +The second is to select portions of that line for inclusion into +the current one. +The line selected from the history is the \fIevent\fP, +and the portions of that line that are acted upon are \fIwords\fP. +Various \fImodifiers\fP are available to manipulate the selected words. +The line is broken into words in the same fashion as \fBbash\fP +does when reading input, +so that several words that would otherwise be separated +are considered one word when surrounded by quotes (see the +description of \fBhistory_tokenize()\fP below). +History expansions are introduced by the appearance of the +history expansion character, which is \^\fB!\fP\^ by default. +Only backslash (\^\fB\e\fP\^) and single quotes can quote +the history expansion character. +.SS Event Designators +.PP +An event designator is a reference to a command line entry in the +history list. +.PP +.PD 0 +.TP +.B ! +Start a history substitution, except when followed by a +.BR blank , +newline, = or (. +.TP +.B !\fIn\fR +Refer to command line +.IR n . +.TP +.B !\-\fIn\fR +Refer to the current command line minus +.IR n . +.TP +.B !! +Refer to the previous command. This is a synonym for `!\-1'. +.TP +.B !\fIstring\fR +Refer to the most recent command starting with +.IR string . +.TP +.B !?\fIstring\fR\fB[?]\fR +Refer to the most recent command containing +.IR string . +The trailing \fB?\fP may be omitted if +.I string +is followed immediately by a newline. +.TP +.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u +Quick substitution. Repeat the last command, replacing +.I string1 +with +.IR string2 . +Equivalent to +``!!:s/\fIstring1\fP/\fIstring2\fP/'' +(see \fBModifiers\fP below). +.TP +.B !# +The entire command line typed so far. +.PD +.SS Word Designators +.PP +Word designators are used to select desired words from the event. +A +.B : +separates the event specification from the word designator. +It may be omitted if the word designator begins with a +.BR ^ , +.BR $ , +.BR * , +.BR \- , +or +.BR % . +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. +.PP +.PD 0 +.TP +.B 0 (zero) +The zeroth word. For the shell, this is the command +word. +.TP +.I n +The \fIn\fRth word. +.TP +.B ^ +The first argument. That is, word 1. +.TP +.B $ +The last argument. +.TP +.B % +The word matched by the most recent `?\fIstring\fR?' search. +.TP +.I x\fB\-\fPy +A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'. +.TP +.B * +All of the words but the zeroth. This is a synonym +for `\fI1\-$\fP'. It is not an error to use +.B * +if there is just one +word in the event; the empty string is returned in that case. +.TP +.B x* +Abbreviates \fIx\-$\fP. +.TP +.B x\- +Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word. +.PD +.PP +If a word designator is supplied without an event specification, the +previous command is used as the event. +.SS Modifiers +.PP +After the optional word designator, there may appear a sequence of +one or more of the following modifiers, each preceded by a `:'. +.PP +.PD 0 +.PP +.TP +.B h +Remove a trailing file name component, leaving only the head. +.TP +.B t +Remove all leading file name components, leaving the tail. +.TP +.B r +Remove a trailing suffix of the form \fI.xxx\fP, leaving the +basename. +.TP +.B e +Remove all but the trailing suffix. +.TP +.B p +Print the new command but do not execute it. +.TP +.B q +Quote the substituted words, escaping further substitutions. +.TP +.B x +Quote the substituted words as with +.BR q , +but break into words at +.B blanks +and newlines. +.TP +.B s/\fIold\fP/\fInew\fP/ +Substitute +.I new +for the first occurrence of +.I old +in the event line. Any delimiter can be used in place of /. The +final delimiter is optional if it is the last character of the +event line. The delimiter may be quoted in +.I old +and +.I new +with a single backslash. If & appears in +.IR new , +it is replaced by +.IR old . +A single backslash will quote the &. If +.I old +is null, it is set to the last +.I old +substituted, or, if no previous history substitutions took place, +the last +.I string +in a +.B !?\fIstring\fR\fB[?]\fR +search. +.TP +.B & +Repeat the previous substitution. +.TP +.B g +Cause changes to be applied over the entire event line. This is +used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR') +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. +.PD +.SH "PROGRAMMING WITH HISTORY FUNCTIONS" +This section describes how to use the History library in other programs. +.SS Introduction to History +.PP +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 \fIexpansion\fP function +is available which provides for a consistent user interface across +different programs. +.PP +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 +identical to +the history substitution provided by \fBbash\fP. +.PP +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. +.PP +Before declaring any functions using any functionality the History +library provides in other code, an application writer should include +the file +.FN +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. + +.SS History Storage +.PP +The history list is an array of history entries. A history entry is +declared as follows: +.PP +.Vb "typedef void *" histdata_t; +.PP +.nf +typedef struct _hist_entry { + char *line; + histdata_t data; +} HIST_ENTRY; +.fi +.PP +The history list itself might therefore be declared as +.PP +.Vb "HIST_ENTRY **" the_history_list; +.PP +The state of the History library is encapsulated into a single structure: +.PP +.nf +/* + * 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; +.fi +.PP +If the flags member includes \fBHS_STIFLED\fP, the history has been +stifled. +.SH "History Functions" +.PP +This section describes the calling sequence for the various functions +exported by the GNU History library. +.SS 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. + +.Fn1 void using_history void +Begin a session in which the history functions might be used. This +initializes the interactive variables. + +.Fn1 "HISTORY_STATE *" history_get_history_state void +Return a structure describing the current state of the input history. + +.Fn1 void history_set_history_state "HISTORY_STATE *state" +Set the state of the history list according to \fIstate\fP. + +.SS History List Management + +These functions manage individual entries on the history list, or set +parameters managing the list itself. + +.Fn1 void add_history "const char *string" +Place \fIstring\fP at the end of the history list. The associated data +field (if any) is set to \fBNULL\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. + +.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 +of an invalid \fIwhich\fP, a \fBNULL\fP pointer is returned. + +.Fn1 void clear_history "void" +Clear the history list by deleting all the entries. + +.Fn1 void stifle_history "int max" +Stifle the history list, remembering only the last \fImax\fP entries. + +.Fn1 int unstifle_history "void" +Stop stifling the history. This returns the previously-set +maximum number of history entries (as set by \fBstifle_history()\fP). +history was stifled. The value is positive if the history was +stifled, negative if it wasn't. + +.Fn1 int history_is_stifled "void" +Returns non-zero if the history is stifled, zero if it is not. + +.SS Information About the History List + +These functions return information about the entire history list or +individual list entries. + +.Fn1 "HIST_ENTRY **" history_list "void" +Return a \fBNULL\fP terminated array of \fIHIST_ENTRY *\fP which is the +current input history. Element 0 of this list is the beginning of time. +If there is no history, return \fBNULL\fP. + +.Fn1 int where_history "void" +Returns the offset of the current history element. + +.Fn1 "HIST_ENTRY *" current_history "void" +Return the history entry at the current position, as determined by +\fBwhere_history()\fP. If there is no entry there, return a \fBNULL\fP +pointer. + +.Fn1 "HIST_ENTRY *" history_get "int offset" +Return the history entry at position \fIoffset\fP, starting from +\fBhistory_base\fP. +If there is no entry there, or if \fIoffset\fP +is greater than the history length, return a \fBNULL\fP pointer. + +.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 +history. + +.SS Moving Around the History List + +These functions allow the current index into the history list to be +set or changed. + +.Fn1 int history_set_pos "int pos" +Set the current history offset to \fIpos\fP, an absolute index +into the list. +Returns 1 on success, 0 if \fIpos\fP is less than zero or greater +than the number of history entries. + +.Fn1 "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 \fBNULL\fP pointer. + +.Fn1 "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 \fBNULL\fP pointer. + +.SS Searching the History List + +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 \fIanchored\fP, +meaning that the string must match at the beginning of the history entry. + +.Fn2 int history_search "const char *string" "int direction" +Search the history for \fIstring\fP, starting at the current history offset. +If \fIdirection\fP is less than 0, then the search is through +previous entries, otherwise through subsequent entries. +If \fIstring\fP 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 +\fIstring\fP was found. Otherwise, nothing is changed, and a -1 is +returned. + +.Fn2 int history_search_prefix "const char *string" "int direction" +Search the history for \fIstring\fP, starting at the current history +offset. The search is anchored: matching lines must begin with +\fIstring\fP. If \fIdirection\fP is less than 0, then the search is +through previous entries, otherwise through subsequent entries. +If \fIstring\fP 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. + +.Fn3 int history_search_pos "const char *string" "int direction" "int pos" +Search for \fIstring\fP in the history list, starting at \fIpos\fP, an +absolute index into the list. If \fIdirection\fP is negative, the search +proceeds backward from \fIpos\fP, otherwise forward. Returns the absolute +index of the history element where \fIstring\fP was found, or -1 otherwise. + +.SS 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. + +.Fn1 int read_history "const char *filename" +Add the contents of \fIfilename\fP to the history list, a line at a time. +If \fIfilename\fP is \fBNULL\fP, then read from \fI~/.history\fP. +Returns 0 if successful, or \fBerrno\fP if not. + +.Fn3 int read_history_range "const char *filename" "int from" "int to" +Read a range of lines from \fIfilename\fP, adding them to the history list. +Start reading at line \fIfrom\fP and end at \fIto\fP. +If \fIfrom\fP is zero, start at the beginning. If \fIto\fP is less than +\fIfrom\fP, then read until the end of the file. If \fIfilename\fP is +\fBNULL\fP, then read from \fI~/.history\fP. Returns 0 if successful, +or \fBerrno\fP if not. + +.Fn1 int write_history "const char *filename" +Write the current history to \fIfilename\fP, overwriting \fIfilename\fP +if necessary. +If \fIfilename\fP is \fBNULL\fP, then write the history list to \fI~/.history\fP. +Returns 0 on success, or \fBerrno\fP on a read or write error. + + +.Fn2 int append_history "int nelements" "const char *filename" +Append the last \fInelements\fP of the history list to \fIfilename\fP. +If \fIfilename\fP is \fBNULL\fP, then append to \fI~/.history\fP. +Returns 0 on success, or \fBerrno\fP on a read or write error. + +.Fn2 int history_truncate_file "const char *filename" "int nlines" +Truncate the history file \fIfilename\fP, leaving only the last +\fInlines\fP lines. +If \fIfilename\fP is \fBNULL\fP, then \fI~/.history\fP is truncated. +Returns 0 on success, or \fBerrno\fP on failure. + +.SS History Expansion + +These functions implement history expansion. + +.Fn2 int history_expand "char *string" "char **output" +Expand \fIstring\fP, placing the result into \fIoutput\fP, a pointer +to a string. Returns: +.RS +.PD 0 +.TP +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); +.TP +1 +if expansions did take place; +.TP +-1 +if there was an error in expansion; +.TP +2 +if the returned line should be displayed, but not executed, +as with the \fB:p\fP modifier. +.PD +.RE +If an error ocurred in expansion, then \fIoutput\fP contains a descriptive +error message. + +.Fn3 "char *" get_history_event "const char *string" "int *cindex" "int qchar" +Returns the text of the history event beginning at \fIstring\fP + +\fI*cindex\fP. \fI*cindex\fP is modified to point to after the event +specifier. At function entry, \fIcindex\fP points to the index into +\fIstring\fP where the history event specification begins. \fIqchar\fP +is a character that is allowed to end the event specification in addition +to the ``normal'' terminating characters. + +.Fn1 "char **" history_tokenize "const char *string" +Return an array of tokens parsed out of \fIstring\fP, much as the +shell might. +The tokens are split on the characters in the +\fBhistory_word_delimiters\fP variable, +and shell quoting conventions are obeyed. + +.Fn3 "char *" history_arg_extract "int first" "int last" "const char *string" +Extract a string segment consisting of the \fIfirst\fP through \fIlast\fP +arguments present in \fIstring\fP. Arguments are split using +\fBhistory_tokenize()\fP. + +.SS History Variables + +This section describes the externally-visible variables exported by +the GNU History Library. + +.Vb int history_base +The logical offset of the first entry in the history list. + +.Vb int history_length +The number of entries currently stored in the history list. + +.Vb int history_max_entries +The maximum number of history entries. This must be changed using +\fBstifle_history()\fP. + +.Vb char history_expansion_char +The character that introduces a history event. The default is \fB!\fP. +Setting this to 0 inhibits history expansion. + +.Vb char history_subst_char +The character that invokes word substitution if found at the start of +a line. The default is \fB^\fP. + +.Vb 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. + +.Vb "char *" history_word_delimiters +The characters that separate tokens for \fBhistory_tokenize()\fP. +The default value is \fB"\ \et\en()<>;&|"\fP. + +.Vb "char *" history_no_expand_chars +The list of characters which inhibit history expansion if found immediately +following \fBhistory_expansion_char\fP. The default is space, tab, newline, +\fB\er\fP, and \fB=\fP. + +.Vb "char *" history_search_delimiter_chars +The list of additional characters which can delimit a history search +string, in addition to space, tab, \fI:\fP and \fI?\fP in the case of +a substring search. The default is empty. + +.Vb int history_quotes_inhibit_expansion +If non-zero, single-quoted words are not scanned for the history expansion +character. The default value is 0. + +.Vb "rl_linebuf_func_t *" history_inhibit_expansion_function +This should be set to the address of a function that takes two arguments: +a \fBchar *\fP (\fIstring\fP) +and an \fBint\fP index into that string (\fIi\fP). +It should return a non-zero value if the history expansion starting at +\fIstring[i]\fP should not be performed; zero if the expansion should +be done. +It is intended for use by applications like \fBbash\fP that use the history +expansion character for additional purposes. +By default, this variable is set to \fBNULL\fP. +.SH FILES +.PD 0 +.TP +.FN ~/.history +Default filename for reading and writing saved history +.PD +.SH "SEE ALSO" +.PD 0 +.TP +\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey +.TP +\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey +.TP +\fIbash\fP(1) +.TP +\fIreadline\fP(3) +.PD +.SH AUTHORS +Brian Fox, Free Software Foundation +.br +bfox@gnu.org +.PP +Chet Ramey, Case Western Reserve University +.br +chet@ins.CWRU.Edu +.SH BUG REPORTS +If you find a bug in the +.B history +library, you should report it. But first, you should +make sure that it really is a bug, and that it appears in the latest +version of the +.B history +library that you have. +.PP +Once you have determined that a bug actually exists, mail a +bug report to \fIbug\-readline\fP@\fIgnu.org\fP. +If you have a fix, you are welcome to mail that +as well! Suggestions and `philosophical' bug reports may be mailed +to \fPbug-readline\fP@\fIgnu.org\fP or posted to the Usenet +newsgroup +.BR gnu.bash.bug . +.PP +Comments and bug reports concerning +this manual page should be directed to +.IR chet@ins.CWRU.Edu . diff --git a/readline-4.3/doc/hstech.texinfo b/readline-4.3/doc/hstech.texinfo new file mode 100644 index 0000000..9494446 --- /dev/null +++ b/readline-4.3/doc/hstech.texinfo @@ -0,0 +1,550 @@ +@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{} 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 +#include + +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-4.3/doc/hsuser.texinfo b/readline-4.3/doc/hsuser.texinfo new file mode 100644 index 0000000..418bfa8 --- /dev/null +++ b/readline-4.3/doc/hsuser.texinfo @@ -0,0 +1,437 @@ +@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-4.3/doc/manvers.texinfo b/readline-4.3/doc/manvers.texinfo new file mode 100644 index 0000000..1206cf0 --- /dev/null +++ b/readline-4.3/doc/manvers.texinfo @@ -0,0 +1,10 @@ +@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-4.3/doc/readline.3 b/readline-4.3/doc/readline.3 new file mode 100644 index 0000000..afd6ba2 --- /dev/null +++ b/readline-4.3/doc/readline.3 @@ -0,0 +1,1272 @@ +.\" +.\" MAN PAGE COMMENTS to +.\" +.\" Chet Ramey +.\" Information Network Services +.\" Case Western Reserve University +.\" chet@ins.CWRU.Edu +.\" +.\" Last Change: Tue Jan 22 09:18:25 EST 2002 +.\" +.TH READLINE 3 "2002 January 22" "GNU Readline 4.3" +.\" +.\" File Name macro. This used to be `.PN', for Path Name, +.\" but Sun doesn't seem to like that very much. +.\" +.de FN +\fI\|\\$1\|\fP +.. +.SH NAME +readline \- get a line from a user with editing +.SH SYNOPSIS +.LP +.nf +.ft B +#include +#include +#include +.ft +.fi +.LP +.nf +\fIchar *\fP +.br +\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. +.SH DESCRIPTION +.LP +.B readline +will read a line from the terminal +and return it, using +.B prompt +as a prompt. If +.B prompt +is \fBNULL\fP or the empty string, no prompt is issued. +The line returned is allocated with +.IR malloc (3); +the caller must free it when finished. The line returned +has the final newline removed, so only the text of the line +remains. +.LP +.B readline +offers editing capabilities while the user is entering the +line. +By default, the line editing commands +are similar to those of emacs. +A vi\-style line editing interface is also available. +.LP +This manual page describes only the most basic use of \fBreadline\fP. +Much more functionality is available; see +\fIThe GNU Readline Library\fP and \fIThe GNU History Library\fP +for additional information. +.SH RETURN VALUE +.LP +.B readline +returns the text of the line read. A blank line +returns the empty string. If +.B EOF +is encountered while reading a line, and the line is empty, +.B NULL +is returned. If an +.B EOF +is read with a non\-empty line, it is +treated as a newline. +.SH NOTATION +.LP +An emacs-style notation is used to denote +keystrokes. Control keys are denoted by C\-\fIkey\fR, e.g., C\-n +means Control\-N. Similarly, +.I meta +keys are denoted by M\-\fIkey\fR, so M\-x means Meta\-X. (On keyboards +without a +.I meta +key, M\-\fIx\fP means ESC \fIx\fP, i.e., press the Escape key +then the +.I x +key. This makes ESC the \fImeta prefix\fP. +The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP, +or press the Escape key +then hold the Control key while pressing the +.I x +key.) +.PP +Readline commands may be given numeric +.IR arguments , +which normally act as a repeat count. Sometimes, however, it is the +sign of the argument that is significant. Passing a negative argument +to a command that acts in the forward direction (e.g., \fBkill\-line\fP) +causes that command to act in a backward direction. Commands whose +behavior with arguments deviates from this are noted. +.PP +When a command is described as \fIkilling\fP text, the text +deleted is saved for possible future retrieval +(\fIyanking\fP). The killed text is saved in a +\fIkill ring\fP. Consecutive kills cause the text to be +accumulated into one unit, which can be yanked all at once. +Commands which do not kill text separate the chunks of text +on the kill ring. +.SH INITIALIZATION FILE +.LP +Readline is customized by putting commands in an initialization +file (the \fIinputrc\fP file). +The name of this file is taken from the value of the +.B INPUTRC +environment variable. If that variable is unset, the default is +.IR ~/.inputrc . +When a program which uses the readline library starts up, the +init file is read, and the key bindings and variables are set. +There are only a few basic constructs allowed in the +readline init file. Blank lines are ignored. +Lines beginning with a \fB#\fP are comments. +Lines beginning with a \fB$\fP indicate conditional constructs. +Other lines denote key bindings and variable settings. +Each program using this library may add its own commands +and bindings. +.PP +For example, placing +.RS +.PP +M\-Control\-u: universal\-argument +.RE +or +.RS +C\-Meta\-u: universal\-argument +.RE +.sp +into the +.I inputrc +would make M\-C\-u execute the readline command +.IR universal\-argument . +.PP +The following symbolic character names are recognized while +processing key bindings: +.IR DEL , +.IR ESC , +.IR ESCAPE , +.IR LFD , +.IR NEWLINE , +.IR RET , +.IR RETURN , +.IR RUBOUT , +.IR SPACE , +.IR SPC , +and +.IR TAB . +.PP +In addition to command names, readline allows keys to be bound +to a string that is inserted when the key is pressed (a \fImacro\fP). +.PP +.SS Key Bindings +.PP +The syntax for controlling key bindings in the +.I inputrc +file is simple. All that is required is the name of the +command or the text of a macro and a key sequence to which +it should be bound. The name may be specified in one of two ways: +as a symbolic key name, possibly with \fIMeta\-\fP or \fIControl\-\fP +prefixes, or as a key sequence. +.PP +When using the form \fBkeyname\fP:\^\fIfunction-name\fP or \fImacro\fP, +.I keyname +is the name of a key spelled out in English. For example: +.sp +.RS +Control\-u: universal\-argument +.br +Meta\-Rubout: backward\-kill\-word +.br +Control\-o: "> output" +.RE +.LP +In the above example, +.I C\-u +is bound to the function +.BR universal\-argument , +.I M-DEL +is bound to the function +.BR backward\-kill\-word , +and +.I C\-o +is bound to run the macro +expressed on the right hand side (that is, to insert the text +.if t \f(CW> output\fP +.if n ``> output'' +into the line). +.PP +In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP, +.B keyseq +differs from +.B keyname +above in that strings denoting +an entire key sequence may be specified by placing the sequence +within double quotes. Some GNU Emacs style key escapes can be +used, as in the following example, but the symbolic character names +are not recognized. +.sp +.RS +"\eC\-u": universal\-argument +.br +"\eC\-x\eC\-r": re\-read\-init\-file +.br +"\ee[11~": "Function Key 1" +.RE +.PP +In this example, +.I C-u +is again bound to the function +.BR universal\-argument . +.I "C-x C-r" +is bound to the function +.BR re\-read\-init\-file , +and +.I "ESC [ 1 1 ~" +is bound to insert the text +.if t \f(CWFunction Key 1\fP. +.if n ``Function Key 1''. +.PP +The full set of GNU Emacs style escape sequences available when specifying +key sequences is +.RS +.PD 0 +.TP +.B \eC\- +control prefix +.TP +.B \eM\- +meta prefix +.TP +.B \ee +an escape character +.TP +.B \e\e +backslash +.TP +.B \e" +literal ", a double quote +.TP +.B \e' +literal ', a single quote +.RE +.PD +.PP +In addition to the GNU Emacs style escape sequences, a second +set of backslash escapes is available: +.RS +.PD 0 +.TP +.B \ea +alert (bell) +.TP +.B \eb +backspace +.TP +.B \ed +delete +.TP +.B \ef +form feed +.TP +.B \en +newline +.TP +.B \er +carriage return +.TP +.B \et +horizontal tab +.TP +.B \ev +vertical tab +.TP +.B \e\fInnn\fP +the eight-bit character whose value is the octal value \fInnn\fP +(one to three digits) +.TP +.B \ex\fIHH\fP +the eight-bit character whose value is the hexadecimal value \fIHH\fP +(one or two hex digits) +.RE +.PD +.PP +When entering the text of a macro, single or double quotes should +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 " and '. +.PP +.B Bash +allows the current readline key bindings to be displayed or modified +with the +.B bind +builtin command. The editing mode may be switched during interactive +use by using the +.B \-o +option to the +.B set +builtin command. Other programs using this library provide +similar mechanisms. The +.I inputrc +file may be edited and re-read if a program does not provide +any other means to incorporate new bindings. +.SS Variables +.PP +Readline has variables that can be used to further customize its +behavior. A variable may be set in the +.I inputrc +file with a statement of the form +.RS +.PP +\fBset\fP \fIvariable\-name\fP \fIvalue\fP +.RE +.PP +Except where noted, readline variables can take the values +.B On +or +.B Off +(without regard to case). +The variables and their default values are: +.PP +.PD 0 +.TP +.B bell\-style (audible) +Controls what happens when readline wants to ring the terminal bell. +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 comment\-begin (``#'') +The string that is inserted in \fBvi\fP mode when the +.B insert\-comment +command is executed. +This command is bound to +.B M\-# +in emacs mode and to +.B # +in vi command mode. +.TP +.B completion\-ignore\-case (Off) +If set to \fBOn\fP, readline performs filename matching and completion +in a case\-insensitive fashion. +.TP +.B completion\-query\-items (100) +This determines when the user is queried about viewing +the number of possible completions +generated by the \fBpossible\-completions\fP command. +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. +.TP +.B convert\-meta (On) +If set to \fBOn\fP, readline will convert characters with the +eighth bit set to an ASCII key sequence +by stripping the eighth bit and prefixing it with an +escape character (in effect, using escape as the \fImeta prefix\fP). +.TP +.B disable\-completion (Off) +If set to \fBOn\fP, readline will inhibit word completion. Completion +characters will be inserted into the line as if they had been +mapped to \fBself-insert\fP. +.TP +.B editing\-mode (emacs) +Controls whether readline begins with a set of key bindings similar +to emacs or vi. +.B editing\-mode +can be set to either +.B emacs +or +.BR vi . +.TP +.B enable\-keypad (Off) +When set to \fBOn\fP, readline will try to enable the application +keypad when it is called. Some systems need this to enable the +arrow keys. +.TP +.B expand\-tilde (Off) +If set to \fBon\fP, tilde expansion is performed when readline +attempts word completion. +.TP +.B history-preserve-point +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 +or \fBnext-history\fP. +.TP +.B horizontal\-scroll\-mode (Off) +When set to \fBOn\fP, makes readline use a single line for display, +scrolling the input horizontally on a single screen line when it +becomes longer than the screen width rather than wrapping to a new line. +.TP +.B input\-meta (Off) +If set to \fBOn\fP, readline will enable eight-bit input (that is, +it will not clear the eighth bit in the characters it reads), +regardless of what the terminal claims it can support. The name +.B meta\-flag +is a synonym for this variable. +.TP +.B isearch\-terminators (``C\-[ C\-J'') +The string of characters that should terminate an incremental +search without subsequently executing the character as a command. +If this variable has not been given a value, the characters +\fIESC\fP and \fIC\-J\fP will terminate an incremental search. +.TP +.B keymap (emacs) +Set the current readline keymap. The set of legal keymap names is +\fIemacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, +vi-command\fP, and +.IR vi-insert . +\fIvi\fP is equivalent to \fIvi-command\fP; \fIemacs\fP is +equivalent to \fIemacs-standard\fP. The default value is +.IR emacs . +The value of +.B editing\-mode +also affects the default keymap. +.TP +.B mark\-directories (On) +If set to \fBOn\fP, completed directory names have a slash +appended. +.TP +.B mark\-modified\-lines (Off) +If set to \fBOn\fP, history lines that have been modified are displayed +with a preceding asterisk (\fB*\fP). +.TP +.B mark\-symlinked\-directories (Off) +If set to \fBOn\fP, completed names which are symbolic links to directories +have a slash appended (subject to the value of +\fBmark\-directories\fP). +.TP +.B match\-hidden\-files (On) +This variable, when set to \fBOn\fP, causes readline to match files whose +names begin with a `.' (hidden files) when performing filename +completion, unless the leading `.' is +supplied by the user in the filename to be completed. +.TP +.B output\-meta (Off) +If set to \fBOn\fP, readline will display characters with the +eighth bit set directly rather than as a meta-prefixed escape +sequence. +.TP +.B page\-completions (On) +If set to \fBOn\fP, readline uses an internal \fImore\fP-like pager +to display a screenful of possible completions at a time. +.TP +.B print\-completions\-horizontally (Off) +If set to \fBOn\fP, readline will display completions with matches +sorted horizontally in alphabetical order, rather than down the screen. +.TP +.B show\-all\-if\-ambiguous (Off) +This alters the default behavior of the completion functions. If +set to +.BR on , +words which have more than one possible completion 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 +completions. +.PD +.SS Conditional Constructs +.PP +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. +.IP \fB$if\fP +The +.B $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. +.RS +.IP \fBmode\fP +The \fBmode=\fP form of the \fB$if\fP directive is used to test +whether readline is in emacs or vi mode. +This may be used in conjunction +with the \fBset keymap\fP command, for instance, to set bindings in +the \fIemacs-standard\fP and \fIemacs-ctlx\fP keymaps only if +readline is starting out in emacs mode. +.IP \fBterm\fP +The \fBterm=\fP 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 +.B = +is tested against the full name of the terminal and the portion +of the terminal name before the first \fB\-\fP. This allows +.I sun +to match both +.I sun +and +.IR sun\-cmd , +for instance. +.IP \fBapplication\fP +The \fBapplication\fP construct is used to include +application-specific settings. Each program using the readline +library sets the \fIapplication name\fP, and an initialization +file 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: +.sp 1 +.RS +.nf +\fB$if\fP Bash +# Quote the current or previous word +"\eC-xq": "\eeb\e"\eef\e"" +\fB$endif\fP +.fi +.RE +.RE +.IP \fB$endif\fP +This command, as seen in the previous example, terminates an +\fB$if\fP command. +.IP \fB$else\fP +Commands in this branch of the \fB$if\fP directive are executed if +the test fails. +.IP \fB$include\fP +This directive takes a single filename as an argument and reads commands +and bindings from that file. For example, the following directive +would read \fI/etc/inputrc\fP: +.sp 1 +.RS +.nf +\fB$include\fP \^ \fI/etc/inputrc\fP +.fi +.RE +.SH SEARCHING +.PP +Readline provides commands for searching through the command history +for lines containing a specified string. +There are two search modes: +.I incremental +and +.IR non-incremental . +.PP +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 +\fBC\-r\fP. Typing \fBC\-s\fP searches forward through the history. +The characters present in the value of the \fBisearch-terminators\fP +variable are used to terminate an incremental search. +If that variable has not been assigned a value the \fIEscape\fP and +\fBC\-J\fP characters will terminate an incremental search. +\fBC\-G\fP 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. +.PP +To find other matching entries in the history list, type \fBC\-s\fP or +\fBC\-r\fP as appropriate. +This will search backward or forward in the history for the next +line 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 newline 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. +.PP +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. +.SH EDITING COMMANDS +.PP +The following is a list of the names of the commands and the default +key sequences to which they are bound. +Command names without an accompanying key sequence are unbound by default. +.PP +In the following descriptions, \fIpoint\fP refers to the current cursor +position, and \fImark\fP refers to a cursor position saved by the +\fBset\-mark\fP command. +The text between the point and mark is referred to as the \fIregion\fP. +.SS Commands for Moving +.PP +.PD 0 +.TP +.B beginning\-of\-line (C\-a) +Move to the start of the current line. +.TP +.B end\-of\-line (C\-e) +Move to the end of the line. +.TP +.B forward\-char (C\-f) +Move forward a character. +.TP +.B backward\-char (C\-b) +Move back a character. +.TP +.B forward\-word (M\-f) +Move forward to the end of the next word. Words are composed of +alphanumeric characters (letters and digits). +.TP +.B backward\-word (M\-b) +Move back to the start of the current or previous word. Words are +composed of alphanumeric characters (letters and digits). +.TP +.B clear\-screen (C\-l) +Clear the screen leaving the current line at the top of the screen. +With an argument, refresh the current line without clearing the +screen. +.TP +.B redraw\-current\-line +Refresh the current line. +.PD +.SS Commands for Manipulating the History +.PP +.PD 0 +.TP +.B accept\-line (Newline, Return) +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 +\fBadd_history()\fP. +If the line is a modified history line, the history line is restored to its original state. +.TP +.B previous\-history (C\-p) +Fetch the previous command from the history list, moving back in +the list. +.TP +.B next\-history (C\-n) +Fetch the next command from the history list, moving forward in the +list. +.TP +.B beginning\-of\-history (M\-<) +Move to the first line in the history. +.TP +.B end\-of\-history (M\->) +Move to the end of the input history, i.e., the line currently being +entered. +.TP +.B 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. +.TP +.B forward\-search\-history (C\-s) +Search forward starting at the current line and moving `down' through +the history as necessary. This is an incremental search. +.TP +.B non\-incremental\-reverse\-search\-history (M\-p) +Search backward through the history starting at the current line +using a non-incremental search for a string supplied by the user. +.TP +.B non\-incremental\-forward\-search\-history (M\-n) +Search forward through the history using a non-incremental search +for a string supplied by the user. +.TP +.B history\-search\-forward +Search forward through the history for the string of characters +between the start of the current line and the current cursor +position (the \fIpoint\fP). +This is a non-incremental search. +.TP +.B 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. +.TP +.B 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 +.IR n , +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. +.TP +.B +yank\-last\-arg (M\-.\^, M\-_\^) +Insert the last argument to the previous command (the last word of +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. +.PD +.SS Commands for Changing Text +.PP +.PD 0 +.TP +.B 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 \fBdelete\-char\fP, then return +.SM +.BR EOF . +.TP +.B backward\-delete\-char (Rubout) +Delete the character behind the cursor. When given a numeric argument, +save the deleted text on the kill ring. +.TP +.B 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. +.TP +.B quoted\-insert (C\-q, C\-v) +Add the next character that you type to the line verbatim. This is +how to insert characters like \fBC\-q\fP, for example. +.TP +.B tab\-insert (M-TAB) +Insert a tab character. +.TP +.B self\-insert (a,\ b,\ A,\ 1,\ !,\ ...) +Insert the character typed. +.TP +.B transpose\-chars (C\-t) +Drag the character before point forward over the character at point, +moving point forward as well. +If point is at the end of the line, then this transposes +the two characters before point. +Negative arguments have no effect. +.TP +.B transpose\-words (M\-t) +Drag the word before point past the word after point, +moving point over that word as well. +If point is at the end of the line, this transposes +the last two words on the line. +.TP +.B upcase\-word (M\-u) +Uppercase the current (or following) word. With a negative argument, +uppercase the previous word, but do not move point. +.TP +.B downcase\-word (M\-l) +Lowercase the current (or following) word. With a negative argument, +lowercase the previous word, but do not move point. +.TP +.B capitalize\-word (M\-c) +Capitalize the current (or following) word. With a negative argument, +capitalize the previous word, but do not move point. +.TP +.B 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 +\fBemacs\fP mode; \fBvi\fP mode does overwrite differently. +Each call to \fIreadline()\fP starts in insert mode. +In overwrite mode, characters bound to \fBself\-insert\fP replace +the text at point rather than pushing the text to the right. +Characters bound to \fBbackward\-delete\-char\fP replace the character +before point with a space. By default, this command is unbound. +.PD +.SS Killing and Yanking +.PP +.PD 0 +.TP +.B kill\-line (C\-k) +Kill the text from point to the end of the line. +.TP +.B backward\-kill\-line (C\-x Rubout) +Kill backward to the beginning of the line. +.TP +.B unix\-line\-discard (C\-u) +Kill backward from point to the beginning of the line. +The killed text is saved on the kill-ring. +.\" There is no real difference between this and backward-kill-line +.TP +.B kill\-whole\-line +Kill all characters on the current line, no matter where point is. +.TP +.B kill\-word (M\-d) +Kill from point 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 \fBforward\-word\fP. +.TP +.B backward\-kill\-word (M\-Rubout) +Kill the word behind point. +Word boundaries are the same as those used by \fBbackward\-word\fP. +.TP +.B 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. +.TP +.B delete\-horizontal\-space (M\-\e) +Delete all spaces and tabs around point. +.TP +.B kill\-region +Kill the text between the point and \fImark\fP (saved cursor position). +This text is referred to as the \fIregion\fP. +.TP +.B copy\-region\-as\-kill +Copy the text in the region to the kill buffer. +.TP +.B copy\-backward\-word +Copy the word before point to the kill buffer. +The word boundaries are the same as \fBbackward\-word\fP. +.TP +.B copy\-forward\-word +Copy the word following point to the kill buffer. +The word boundaries are the same as \fBforward\-word\fP. +.TP +.B yank (C\-y) +Yank the top of the kill ring into the buffer at point. +.TP +.B yank\-pop (M\-y) +Rotate the kill ring, and yank the new top. Only works following +.B yank +or +.BR yank\-pop . +.PD +.SS Numeric Arguments +.PP +.PD 0 +.TP +.B digit\-argument (M\-0, M\-1, ..., M\-\-) +Add this digit to the argument already accumulating, or start a new +argument. M\-\- starts a negative argument. +.TP +.B 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 +.B 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. +.PD +.SS Completing +.PP +.PD 0 +.TP +.B complete (TAB) +Attempt to perform completion on the text before point. +The actual completion performed is application-specific. +.BR Bash , +for instance, attempts completion treating the text as a variable +(if the text begins with \fB$\fP), username (if the text begins with +\fB~\fP), hostname (if the text begins with \fB@\fP), or +command (including aliases and functions) in turn. If none +of these produces a match, filename completion is attempted. +.BR Gdb , +on the other hand, +allows completion of program functions and variables, and +only attempts filename completion under certain circumstances. +.TP +.B possible\-completions (M\-?) +List the possible completions of the text before point. +.TP +.B insert\-completions (M\-*) +Insert all completions of the text before point +that would have been generated by +\fBpossible\-completions\fP. +.TP +.B menu\-complete +Similar to \fBcomplete\fP, but replaces the word to be completed +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) +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 +through the list. +This command is intended to be bound to \fBTAB\fP, but is unbound +by default. +.TP +.B delete\-char\-or\-list +Deletes the character under the cursor if not at the beginning or +end of the line (like \fBdelete-char\fP). +If at the end of the line, behaves identically to +\fBpossible-completions\fP. +.PD +.SS Keyboard Macros +.PP +.PD 0 +.TP +.B start\-kbd\-macro (C\-x (\^) +Begin saving the characters typed into the current keyboard macro. +.TP +.B end\-kbd\-macro (C\-x )\^) +Stop saving the characters typed into the current keyboard macro +and store the definition. +.TP +.B 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. +.PD +.SS Miscellaneous +.PP +.PD 0 +.TP +.B re\-read\-init\-file (C\-x C\-r) +Read in the contents of the \fIinputrc\fP file, and incorporate +any bindings or variable assignments found there. +.TP +.B abort (C\-g) +Abort the current editing command and +ring the terminal's bell (subject to the setting of +.BR bell\-style ). +.TP +.B do\-uppercase\-version (M\-a, M\-b, M\-\fIx\fP, ...) +If the metafied character \fIx\fP is lowercase, run the command +that is bound to the corresponding uppercase character. +.TP +.B prefix\-meta (ESC) +Metafy the next character typed. +.SM +.B ESC +.B f +is equivalent to +.BR Meta\-f . +.TP +.B undo (C\-_, C\-x C\-u) +Incremental undo, separately remembered for each line. +.TP +.B revert\-line (M\-r) +Undo all changes made to this line. This is like executing the +.B undo +command enough times to return the line to its initial state. +.TP +.B tilde\-expand (M\-&) +Perform tilde expansion on the current word. +.TP +.B set\-mark (C\-@, M\-) +Set the mark to the point. If a +numeric argument is supplied, the mark is set to that position. +.TP +.B 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. +.TP +.B 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. +.TP +.B 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. +.TP +.B insert\-comment (M\-#) +Without a numeric argument, the value of the readline +.B 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 \fBcomment\-begin\fP, the value is inserted, otherwise +the characters in \fBcomment-begin\fP are deleted from the beginning of +the line. +In either case, the line is accepted as if a newline had been typed. +The default value of +.B comment\-begin +makes 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. +.TP +.B 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 \fIinputrc\fP file. +.TP +.B 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 \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, +the output is formatted in such a way that it can be made part +of an \fIinputrc\fP file. +.TP +.B emacs\-editing\-mode (C\-e) +When in +.B vi +command mode, this causes a switch to +.B emacs +editing mode. +.TP +.B vi\-editing\-mode (M\-C\-j) +When in +.B emacs +editing mode, this causes a switch to +.B vi +editing mode. +.PD +.SH DEFAULT KEY BINDINGS +.LP +The following is a list of the default emacs and vi bindings. +Characters with the eighth bit set are written as M\-, and +are referred to as +.I metafied +characters. +The printable ASCII characters not mentioned in the list of emacs +standard bindings are bound to the +.B self\-insert +function, which just inserts the given character into the input line. +In vi insertion mode, all characters not specifically mentioned are +bound to +.BR self\-insert . +Characters assigned to signal generation by +.IR stty (1) +or the terminal driver, such as C-Z or C-C, +retain that function. +Upper and lower case metafied characters are bound to the same function in +the emacs mode meta keymap. +The remaining characters are unbound, which causes readline +to ring the bell (subject to the setting of the +.B bell\-style +variable). +.SS Emacs Mode +.RS +.6i +.nf +.ta 2.5i +.sp +Emacs Standard bindings +.sp +"C-@" set-mark +"C-A" beginning-of-line +"C-B" backward-char +"C-D" delete-char +"C-E" end-of-line +"C-F" forward-char +"C-G" abort +"C-H" backward-delete-char +"C-I" complete +"C-J" accept-line +"C-K" kill-line +"C-L" clear-screen +"C-M" accept-line +"C-N" next-history +"C-P" previous-history +"C-Q" quoted-insert +"C-R" reverse-search-history +"C-S" forward-search-history +"C-T" transpose-chars +"C-U" unix-line-discard +"C-V" quoted-insert +"C-W" unix-word-rubout +"C-Y" yank +"C-]" character-search +"C-_" undo +"\^ " to "/" self-insert +"0" to "9" self-insert +":" to "~" self-insert +"C-?" backward-delete-char +.PP +Emacs Meta bindings +.sp +"M-C-G" abort +"M-C-H" backward-kill-word +"M-C-I" tab-insert +"M-C-J" vi-editing-mode +"M-C-M" vi-editing-mode +"M-C-R" revert-line +"M-C-Y" yank-nth-arg +"M-C-[" complete +"M-C-]" character-search-backward +"M-space" set-mark +"M-#" insert-comment +"M-&" tilde-expand +"M-*" insert-completions +"M--" digit-argument +"M-." yank-last-arg +"M-0" digit-argument +"M-1" digit-argument +"M-2" digit-argument +"M-3" digit-argument +"M-4" digit-argument +"M-5" digit-argument +"M-6" digit-argument +"M-7" digit-argument +"M-8" digit-argument +"M-9" digit-argument +"M-<" beginning-of-history +"M-=" possible-completions +"M->" end-of-history +"M-?" possible-completions +"M-B" backward-word +"M-C" capitalize-word +"M-D" kill-word +"M-F" forward-word +"M-L" downcase-word +"M-N" non-incremental-forward-search-history +"M-P" non-incremental-reverse-search-history +"M-R" revert-line +"M-T" transpose-words +"M-U" upcase-word +"M-Y" yank-pop +"M-\e" delete-horizontal-space +"M-~" tilde-expand +"M-C-?" backward-kill-word +"M-_" yank-last-arg +.PP +Emacs Control-X bindings +.sp +"C-XC-G" abort +"C-XC-R" re-read-init-file +"C-XC-U" undo +"C-XC-X" exchange-point-and-mark +"C-X(" start-kbd-macro +"C-X)" end-kbd-macro +"C-XE" call-last-kbd-macro +"C-XC-?" backward-kill-line +.sp +.RE +.SS VI Mode bindings +.RS +.6i +.nf +.ta 2.5i +.sp +.PP +VI Insert Mode functions +.sp +"C-D" vi-eof-maybe +"C-H" backward-delete-char +"C-I" complete +"C-J" accept-line +"C-M" accept-line +"C-R" reverse-search-history +"C-S" forward-search-history +"C-T" transpose-chars +"C-U" unix-line-discard +"C-V" quoted-insert +"C-W" unix-word-rubout +"C-Y" yank +"C-[" vi-movement-mode +"C-_" undo +"\^ " to "~" self-insert +"C-?" backward-delete-char +.PP +VI Command Mode functions +.sp +"C-D" vi-eof-maybe +"C-E" emacs-editing-mode +"C-G" abort +"C-H" backward-char +"C-J" accept-line +"C-K" kill-line +"C-L" clear-screen +"C-M" accept-line +"C-N" next-history +"C-P" previous-history +"C-Q" quoted-insert +"C-R" reverse-search-history +"C-S" forward-search-history +"C-T" transpose-chars +"C-U" unix-line-discard +"C-V" quoted-insert +"C-W" unix-word-rubout +"C-Y" yank +"C-_" vi-undo +"\^ " forward-char +"#" insert-comment +"$" end-of-line +"%" vi-match +"&" vi-tilde-expand +"*" vi-complete +"+" next-history +"," vi-char-search +"-" previous-history +"." vi-redo +"/" vi-search +"0" beginning-of-line +"1" to "9" vi-arg-digit +";" vi-char-search +"=" vi-complete +"?" vi-search +"A" vi-append-eol +"B" vi-prev-word +"C" vi-change-to +"D" vi-delete-to +"E" vi-end-word +"F" vi-char-search +"G" vi-fetch-history +"I" vi-insert-beg +"N" vi-search-again +"P" vi-put +"R" vi-replace +"S" vi-subst +"T" vi-char-search +"U" revert-line +"W" vi-next-word +"X" backward-delete-char +"Y" vi-yank-to +"\e" vi-complete +"^" vi-first-print +"_" vi-yank-arg +"`" vi-goto-mark +"a" vi-append-mode +"b" vi-prev-word +"c" vi-change-to +"d" vi-delete-to +"e" vi-end-word +"f" vi-char-search +"h" backward-char +"i" vi-insertion-mode +"j" next-history +"k" prev-history +"l" forward-char +"m" vi-set-mark +"n" vi-search-again +"p" vi-put +"r" vi-change-char +"s" vi-subst +"t" vi-char-search +"u" vi-undo +"w" vi-next-word +"x" vi-delete +"y" vi-yank-to +"|" vi-column +"~" vi-change-case +.RE +.SH "SEE ALSO" +.PD 0 +.TP +\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey +.TP +\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey +.TP +\fIbash\fP(1) +.PD +.SH FILES +.PD 0 +.TP +.FN ~/.inputrc +Individual \fBreadline\fP initialization file +.PD +.SH AUTHORS +Brian Fox, Free Software Foundation +.br +bfox@gnu.org +.PP +Chet Ramey, Case Western Reserve University +.br +chet@ins.CWRU.Edu +.SH BUG REPORTS +If you find a bug in +.B readline, +you should report it. But first, you should +make sure that it really is a bug, and that it appears in the latest +version of the +.B readline +library that you have. +.PP +Once you have determined that a bug actually exists, mail a +bug report to \fIbug\-readline\fP@\fIgnu.org\fP. +If you have a fix, you are welcome to mail that +as well! Suggestions and `philosophical' bug reports may be mailed +to \fPbug-readline\fP@\fIgnu.org\fP or posted to the Usenet +newsgroup +.BR gnu.bash.bug . +.PP +Comments and bug reports concerning +this manual page should be directed to +.IR chet@ins.CWRU.Edu . +.SH BUGS +.PP +It's too big and too slow. diff --git a/readline-4.3/doc/rlman.texinfo b/readline-4.3/doc/rlman.texinfo new file mode 100644 index 0000000..1ffebad --- /dev/null +++ b/readline-4.3/doc/rlman.texinfo @@ -0,0 +1,108 @@ +\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-4.3/doc/rltech.texinfo b/readline-4.3/doc/rltech.texinfo new file mode 100644 index 0000000..037e824 --- /dev/null +++ b/readline-4.3/doc/rltech.texinfo @@ -0,0 +1,2165 @@ +@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{} +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{} 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 +#include +#include +#include +#include + +#include +#include + +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-4.3/doc/rluser.texinfo b/readline-4.3/doc/rluser.texinfo new file mode 100644 index 0000000..94f851e --- /dev/null +++ b/readline-4.3/doc/rluser.texinfo @@ -0,0 +1,1796 @@ +@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-4.3/doc/rluserman.texinfo b/readline-4.3/doc/rluserman.texinfo new file mode 100644 index 0000000..89abe31 --- /dev/null +++ b/readline-4.3/doc/rluserman.texinfo @@ -0,0 +1,94 @@ +\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-4.3/doc/texi2dvi b/readline-4.3/doc/texi2dvi new file mode 100755 index 0000000..c186848 --- /dev/null +++ b/readline-4.3/doc/texi2dvi @@ -0,0 +1,568 @@ +#! /bin/sh +# 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. +# +# 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, you can either send email to this +# program's maintainer or write to: The Free Software Foundation, +# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. +# +# Original author: Noah Friedman . +# +# Please send bug reports, etc. to bug-texinfo@gnu.org. +# If possible, please send a copy of the output of the script called with +# the `--debug' option when making a bug report. + +# This string is expanded by rcs automatically when this file is checked out. +rcs_revision='$Revision$' +rcs_version=`set - $rcs_revision; echo $2` +program=`echo $0 | sed -e 's!.*/!!'` +version="texi2dvi (GNU Texinfo 4.0) $rcs_version + +Copyright (C) 1999 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." + +usage="Usage: $program [OPTION]... FILE... + +Run each Texinfo or LaTeX FILE through TeX in turn until all +cross-references are resolved, building all indices. The directory +containing each FILE is searched for included files. The suffix of FILE +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. + +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 , +general questions and discussion to ." + +# 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= +expand= # t for expansion via makeinfo +oformat=dvi +set_language= +miincludes= # makeinfo include path +textra= +tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems. +txincludes= # TEXINPUTS extensions +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` + +# Systems which define $COMSPEC or $ComSpec use semicolons to separate +# directories in TEXINPUTS. +if test -n "$COMSPEC$ComSpec"; then + path_sep=";" +else + path_sep=":" +fi + +# Save this so we can construct a new TEXINPUTS path for each file. +TEXINPUTS_orig="$TEXINPUTS" +# Unfortunately makeindex does not read TEXINPUTS. +INDEXSTYLE_orig="$INDEXSTYLE" +export TEXINPUTS INDEXSTYLE + +# Push a token among the arguments that will be used to notice when we +# ended options/arguments parsing. +# Use "set dummy ...; shift" rather than 'set - ..." because on +# Solaris set - turns off set -x (but keeps set -e). +# Use ${1+"$@"} rather than "$@" because Digital Unix and Ultrix 4.3 +# still expand "$@" to a single argument (the empty string) rather +# than nothing at all. +arg_sep="$$--$$" +set dummy ${1+"$@"} "$arg_sep"; shift + +# +# Parse command line arguments. +while test x"$1" != x"$arg_sep"; do + + # Handle --option=value by splitting apart and putting back on argv. + case "$1" in + --*=*) + opt=`echo "$1" | sed -e 's/=.*//'` + val=`echo "$1" | sed -e 's/[^=]*=//'` + shift + set dummy "$opt" "$val" ${1+"$@"}; shift + ;; + esac + + # This recognizes --quark as --quiet. So what. + case "$1" in + -@ ) escape=@;; + # Silently and without documentation accept -b and --b[atch] as synonyms. + -b | --b*) batch=eval;; + -q | -s | --q* | --s*) quiet=t; batch=eval;; + -c | --c*) clean=t;; + -D | --d*) debug=t;; + -e | --e*) expand=t;; + -h | --h*) echo "$usage"; exit 0;; + -I | --I*) + shift + miincludes="$miincludes -I $1" + txincludes="$txincludes$path_sep$1" + ;; + -l | --l*) shift; set_language=$1;; + -p | --p*) oformat=pdf;; + -t | --t*) shift; textra="$textra\\ +$1";; + -v | --vers*) echo "$version"; exit 0;; + -V | --verb*) verbose=echo;; + --) # What remains are not options. + shift + while test x"$1" != x"$arg_sep"; do + set dummy ${1+"$@"} "$1"; shift + shift + done + break;; + -*) + echo "$0: Unknown or ambiguous option \`$1'." >&2 + echo "$0: Try \`--help' for more information." >&2 + exit 1;; + *) set dummy ${1+"$@"} "$1"; shift;; + esac + shift +done +# Pop the token +shift + +# Interpret remaining command line args as filenames. +if test $# = 0; then + echo "$0: Missing file arguments." >&2 + echo "$0: Try \`--help' for more information." >&2 + exit 2 +fi + +# Prepare the temporary directory. Remove it at exit, unless debugging. +if test -z "$debug"; then + trap "cd / && rm -rf $tmpdir" 0 1 2 15 +fi + +# Create the temporary directory with strict rights +(umask 077 && mkdir $tmpdir) || exit 1 + +# Prepare the tools we might need. This may be extra work in some +# cases, but improves the readibility of the script. +utildir=$tmpdir/utils +mkdir $utildir || exit 1 + +# A sed script that preprocesses Texinfo sources in order to keep the +# iftex sections only. We want to remove non TeX sections, and +# comment (with `@c texi2dvi') TeX sections so that makeinfo does not +# try to parse them. Nevertheless, while commenting TeX sections, +# don't comment @macro/@end macro so that makeinfo does propagate +# them. Unfortunately makeinfo --iftex --no-ifhtml --no-ifinfo +# doesn't work well enough (yet) to use that, so work around with sed. +comment_iftex_sed=$utildir/comment.sed +cat <$comment_iftex_sed +/^@tex/,/^@end tex/{ + s/^/@c texi2dvi/ +} +/^@iftex/,/^@end iftex/{ + s/^/@c texi2dvi/ + /^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{ + s/^@c texi2dvi// + } +} +/^@html/,/^@end html/d +/^@ifhtml/,/^@end ifhtml/d +/^@ifnottex/,/^@end ifnottex/d +/^@ifinfo/,/^@end ifinfo/{ + /^@node/p + /^@menu/,/^@end menu/p + d +} +EOF +# Uncommenting is simple: Remove any leading `@c texi2dvi'. +uncomment_iftex_sed=$utildir/uncomment.sed +cat <$uncomment_iftex_sed +s/^@c texi2dvi// +EOF + +# A shell script that computes the list of xref files. +# Takes the filename (without extension) of which we look for xref +# files as argument. The index files must be reported last. +get_xref_files=$utildir/get_xref.sh +cat <<\EOF >$get_xref_files +#! /bin/sh + +# 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. +for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do + # If file is empty, skip it. + test -s "$this_file" || continue + # If the file is not suitable to be an index or xref file, don't + # process it. The file can't be if its first character is not a + # backslash or single quote. + first_character=`sed -n '1s/^\(.\).*$/\1/p;q' $this_file` + if test "x$first_character" = "x\\" \ + || test "x$first_character" = "x'"; then + xref_files="$xref_files ./$this_file" + fi +done +echo "$xref_files" +EOF +chmod 500 $get_xref_files + +# File descriptor usage: +# 0 standard input +# 1 standard output (--verbose messages) +# 2 standard error +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 tools output (turned off by --quiet) + +# Tools' output. If quiet, discard, else redirect to the message flow. +if test "$quiet" = t; then + exec 5>/dev/null +else + exec 5>&1 +fi + +# Enable tracing +test "$debug" = t && set -x + +# +# TeXify files. + +for command_line_filename in ${1+"$@"}; do + $verbose "Processing $command_line_filename ..." + + # 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 \ + || command_line_filename="./$command_line_filename" + + # See if the file exists. If it doesn't we're in trouble since, even + # though the user may be able to reenter a valid filename at the tex + # prompt (assuming they're attending the terminal), this script won't + # be able to find the right xref files and so forth. + if test ! -r "$command_line_filename"; then + echo "$0: Could not read $command_line_filename, skipping." >&2 + continue + fi + + # Get the name of the current directory. We want the full path + # because in clean mode we are in tmp, in which case a relative + # path has no meaning. + filename_dir=`echo $command_line_filename | sed 's!/[^/]*$!!;s!^$!.!'` + filename_dir=`cd "$filename_dir" >/dev/null && pwd` + + # Strip directory part but leave extension. + filename_ext=`basename "$command_line_filename"` + # Strip extension. + filename_noext=`echo "$filename_ext" | sed 's/\.[^.]*$//'` + ext=`echo "$filename_ext" | sed 's/^.*\.//'` + + # _src. Use same basename since we want to generate aux files with + # the same basename as the manual. If --expand, then output the + # macro-expanded file to here, else copy the original file. + tmpdir_src=$tmpdir/src + filename_src=$tmpdir_src/$filename_noext.$ext + + # _xtr. The file with the user's extra commands. + tmpdir_xtr=$tmpdir/xtr + filename_xtr=$tmpdir_xtr/$filename_noext.$ext + + # _bak. Copies of the previous xref files (another round is run if + # they differ from the new one). + tmpdir_bak=$tmpdir/bak + + # 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, + # 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" + TEXINPUTS="$common$TEXINPUTS_orig" + INDEXSTYLE="$common$INDEXSTYLE_orig" + + # 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 + language=texinfo + else + language= + fi + + # Get the type of the file (latex or texinfo) from the given language + # we just guessed, or from the file extension if not set yet. + case ${language:-$filename_ext} in + [lL]a[tT]e[xX] | *.ltx | *.tex) + # Assume a LaTeX file. LaTeX needs bibtex and uses latex for + # compilation. No makeinfo. + bibtex=${BIBTEX:-bibtex} + makeinfo= # no point in running makeinfo on latex source. + texindex=${MAKEINDEX:-makeindex} + if test $oformat = dvi; then + tex=${LATEX:-latex} + else + tex=${PDFLATEX:-pdflatex} + fi + ;; + + *) + # Assume a Texinfo file. Texinfo files need makeinfo, texindex and tex. + bibtex= + texindex=${TEXINDEX:-texindex} + if test $oformat = dvi; then + tex=${TEX:-tex} + else + tex=${PDFTEX:-pdftex} + fi + # Unless required by the user, makeinfo expansion is wanted only + # if texinfo.tex is too old. + if test "$expand" = t; then + makeinfo=${MAKEINFO:-makeinfo} + else + # Check if texinfo.tex performs macro expansion by looking for + # its version. The version is a date of the form YEAR-MO-DA. + # We don't need to use [0-9] to match the digits since anyway + # the comparison with $txiprereq, a number, will fail with non + # digits. + 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'` + $verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..." + if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then + makeinfo= + else + makeinfo=${MAKEINFO:-makeinfo} + fi + # As long as we had to run TeX, offer the user this convenience + if test "$txiformat" = Texinfo; then + escape=@ + fi + fi + ;; + esac + + # Expand macro commands in the original source file using Makeinfo. + # Always use `end' footnote style, since the `separate' style + # generates different output (arguably this is a bug in -E). + # Discard main info output, the user asked to run TeX, not makeinfo. + if test -n "$makeinfo"; then + $verbose "Macro-expanding $command_line_filename to $filename_src ..." + sed -f $comment_iftex_sed "$command_line_filename" \ + | $makeinfo --footnote-style=end -I "$filename_dir" $miincludes \ + -o /dev/null --macro-expand=- \ + | sed -f $uncomment_iftex_sed >"$filename_src" + filename_input=$filename_src + fi + + # If makeinfo failed (or was not even run), use the original file as input. + if test $? -ne 0 \ + || test ! -r "$filename_src"; then + $verbose "Reverting to $command_line_filename ..." + filename_input=$filename_dir/$filename_ext + fi + + # Used most commonly for @finalout, @smallbook, etc. + if test -n "$textra"; then + $verbose "Inserting extra commands: $textra" + sed '/^@setfilename/a\ +'"$textra" "$filename_input" >$filename_xtr + filename_input=$filename_xtr + fi + + # If clean mode was specified, then move to the temporary directory. + if test "$clean" = t; then + $verbose "cd $tmpdir_src" + cd "$tmpdir_src" || exit 1 + fi + + while :; do # will break out of loop below + orig_xref_files=`$get_xref_files "$filename_noext"` + + # Save copies of originals for later comparison. + if test -n "$orig_xref_files"; then + $verbose "Backing up xref files: `echo $orig_xref_files | sed 's|\./||g'`" + cp $orig_xref_files $tmpdir_bak + fi + + # Run bibtex on current file. + # - If its input (AUX) exists. + # - If AUX contains both `\bibdata' and `\bibstyle'. + # - If some citations are missing (LOG contains `Citation'). + # or the LOG complains of a missing .bbl + # + # We run bibtex first, because I can see reasons for the indexes + # to change after bibtex is run, but I see no reason for the + # converse. + # + # Don't try to be too smart. Running bibtex only if the bbl file + # exists and is older than the LaTeX file is wrong, since the + # document might include files that have changed. Because there + # can be several AUX (if there are \include's), but a single LOG, + # looking for missing citations in LOG is easier, though we take + # the risk to match false messages. + if test -n "$bibtex" \ + && test -r "$filename_noext.aux" \ + && test -r "$filename_noext.log" \ + && (grep '^\\bibdata[{]' "$filename_noext.aux" \ + && grep '^\\bibstyle[{]' "$filename_noext.aux" \ + && (grep 'Warning:.*Citation.*undefined' "$filename_noext.log" \ + || grep 'No file .*\.bbl\.' "$filename_noext.log")) \ + >/dev/null 2>&1; \ + then + $verbose "Running $bibtex $filename_noext ..." + if $bibtex "$filename_noext" >&5; then :; else + echo "$0: $bibtex exited with bad status, quitting." >&2 + exit 1 + fi + fi + + # 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?. + index_files=`echo "$orig_xref_files" \ + | sed "s!.*\.aux!!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 + # files don't change, then there's no reason to run TeX again. + # But we won't know that if the index files are out of date or + # nonexistent. + if test -n "$texindex" && test -n "$index_files"; then + $verbose "Running $texindex $index_files ..." + if $texindex $index_files 2>&5 1>&2; then :; else + echo "$0: $texindex exited with bad status, quitting." >&2 + exit 1 + fi + fi + + # Finally, run TeX. + # 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" + if $cmd >&5; then :; else + echo "$0: $tex exited with bad status, quitting." >&2 + echo "$0: see $filename_noext.log for errors." >&2 + test "$clean" = t \ + && cp "$filename_noext.log" "$orig_pwd" + exit 1 + fi + + + # Decide if looping again is needed. + finished=t + + # LaTeX (and the package changebar) report in the LOG file if it + # should be rerun. This is needed for files included from + # 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 + finished= + fi + + # Check if xref files changed. + new_xref_files=`$get_xref_files "$filename_noext"` + $verbose "Original xref files = `echo $orig_xref_files | sed 's|\./||g'`" + $verbose "New xref files = `echo $new_xref_files | sed 's|\./||g'`" + + # If old and new lists don't at least have the same file list, + # then one file or another has definitely changed. + test "x$orig_xref_files" != "x$new_xref_files" && finished= + + # File list is the same. We must compare each file until we find + # a difference. + if test -n "$finished"; then + for this_file in $new_xref_files; do + $verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..." + # cmp -s returns nonzero exit status if files differ. + if cmp -s "$this_file" "$tmpdir_bak/$this_file"; then :; else + # We only need to keep comparing until we find one that + # differs, because we'll have to run texindex & tex again no + # matter how many more there might be. + finished= + $verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..." + test "$debug" = t && diff -c "$tmpdir_bak/$this_file" "$this_file" + break + fi + done + fi + + # If finished, exit the loop, else rerun the loop. + test -n "$finished" && break + done + + # If we were in clean mode, compilation was in a tmp directory. + # Copy the DVI (or PDF) file into the directory where the compilation + # has been done. (The temp dir is about to get removed anyway.) + # We also return to the original directory so that + # - 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" + cd / # in case $orig_pwd is on a different drive (for DOS) + cd $orig_pwd || exit 1 + fi + + # Remove temporary files. + if test "x$debug" = "x"; then + $verbose "Removing $tmpdir_src $tmpdir_xtr $tmpdir_bak ..." + cd / + rm -rf $tmpdir_src $tmpdir_xtr $tmpdir_bak + fi +done + +$verbose "$0 done." +exit 0 # exit successfully, not however we ended the loop. diff --git a/readline-4.3/doc/texi2html b/readline-4.3/doc/texi2html new file mode 100755 index 0000000..7bb8493 --- /dev/null +++ b/readline-4.3/doc/texi2html @@ -0,0 +1,5429 @@ +#! /usr/bin/perl +'di '; +'ig 00 '; +#+############################################################################## +# +# texi2html: Program to transform Texinfo documents to HTML +# +# Copyright (C) 1999, 2000 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 +# +#-############################################################################## + +# This requires perl version 5 or higher +require 5.0; + +#++############################################################################## +# +# NOTE FOR DEBUGGING THIS SCRIPT: +# You can run 'perl texi2html.pl' directly, provided you have +# the environment variable T2H_HOME set to the directory containing +# the texi2html.init file +# +#--############################################################################## + +# CVS version: +# $Id$ + +# Homepage: +$T2H_HOMEPAGE = < (original author) + Karl Berry + Olaf Bachmann + and many others. +Maintained by: Olaf Bachmann +Send bugs and suggestions to +EOT + +# Version: set in configure.in +$THISVERSION = '1.64'; +$THISPROG = "texi2html $THISVERSION"; # program name and version + +# The man page for this program is included at the end of this file and can be +# viewed using the command 'nroff -man texi2html'. + +# Identity: + +$T2H_TODAY = &pretty_date; # like "20 September 1993" +# the eval prevents this from breaking on system which do not have +# a proper getpwuid implemented +eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i + +#+++############################################################################ +# # +# Initialization # +# Pasted content of File $(srcdir)/texi2html.init: Default initializations # +# # +#---############################################################################ + +# leave this within comments, and keep the require statement +# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init +# exists. + +# +# -*-perl-*- +###################################################################### +# File: texi2html.init +# +# Sets default values for command-line arguments and for various customizable +# procedures +# +# A copy of this file is pasted into the beginning of texi2html by +# 'make texi2html' +# +# Copy this file and make changes to it, if you like. +# Afterwards, either, load it with command-line option -init_file +# +# $Id$ + +###################################################################### +# stuff which can also be set by command-line options +# +# +# Note: values set here, overwrite values set by the command-line +# options before -init_file and might still be overwritten by +# command-line arguments following the -init_file option +# + +# T2H_OPTIONS is a hash whose keys are the (long) names of valid +# command-line options and whose values are a hash with the following keys: +# type ==> one of !|=i|:i|=s|:s (see GetOpt::Long for more info) +# linkage ==> ref to scalar, array, or subroutine (see GetOpt::Long for more info) +# verbose ==> short description of option (displayed by -h) +# noHelp ==> if 1 -> for "not so important options": only print description on -h 1 +# 2 -> for obsolete options: only print description on -h 2 + +$T2H_DEBUG = 0; +$T2H_OPTIONS -> {debug} = +{ + type => '=i', + linkage => \$main::T2H_DEBUG, + verbose => 'output HTML with debuging information', +}; + +$T2H_DOCTYPE = ''; +$T2H_OPTIONS -> {doctype} = +{ + type => '=s', + linkage => \$main::T2H_DOCTYPE, + verbose => 'document type which is output in header of HTML files', + noHelp => 1 +}; + +$T2H_CHECK = 0; +$T2H_OPTIONS -> {check} = +{ + type => '!', + linkage => \$main::T2H_CHECK, + verbose => 'if set, only check files and output all things that may be Texinfo commands', + noHelp => 1 +}; + +# -expand +# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections +# else, neither expand @iftex, @tex, nor @ifinfo sections +$T2H_EXPAND = "info"; +$T2H_OPTIONS -> {expand} = +{ + type => '=s', + linkage => \$T2H_EXPAND, + verbose => 'Expand info|tex|none section of texinfo source', +}; + +# - glossary +#if set, uses section named `Footnotes' for glossary +$T2H_USE_GLOSSARY = 0; +T2H_OPTIONS -> {glossary} = +{ + type => '!', + linkage => \$T2H_USE_GLOSSARY, + verbose => "if set, uses section named `Footnotes' for glossary", + noHelp => 1, +}; + + +# -invisible +# $T2H_INVISIBLE_MARK is the text used to create invisible destination +# anchors for index links (you can for instance use the invisible.xbm +# file shipped with this program). This is a workaround for a known +# bug of many WWW browsers, including netscape. +# For me, it works fine without it -- on the contrary: if there, it +# inserts space between headers and start of text (obachman 3/99) +$T2H_INVISIBLE_MARK = ''; +# $T2H_INVISIBLE_MARK = ' '; +$T2H_OPTIONS -> {invisible} = +{ + type => '=s', + linkage => \$T2H_INVISIBLE_MARK, + verbose => 'use text in invisble anchot', + noHelp => 1, +}; + +# -iso +# if set, ISO8879 characters are used for special symbols (like copyright, etc) +$T2H_USE_ISO = 0; +$T2H_OPTIONS -> {iso} = +{ + type => 'iso', + linkage => \$T2H_USE_ISO, + verbose => 'if set, ISO8879 characters are used for special symbols (like copyright, etc)', + noHelp => 1, +}; + +# -I +# list directories where @include files are searched for (besides the +# directory of the doc file) additional '-I' args add to this list +@T2H_INCLUDE_DIRS = ("."); +$T2H_OPTIONS -> {I} = +{ + type => '=s', + linkage => \@T2H_INCLUDE_DIRS, + verbose => 'append $s to the @include search path', +}; + +# -top_file +# uses file of this name for top-level file +# extension is manipulated appropriately, if necessary. +# If empty, .html is used +# Typically, you would set this to "index.html". +$T2H_TOP_FILE = ''; +$T2H_OPTIONS -> {top_file} = +{ + type => '=s', + linkage => \$T2H_TOP_FILE, + verbose => 'use $s as top file, instead of .html', +}; + + +# -toc_file +# uses file of this name for table of contents file +# extension is manipulated appropriately, if necessary. +# If empty, _toc.html is used +$T2H_TOC_FILE = ''; +$T2H_OPTIONS -> {toc_file} = +{ + type => '=s', + linkage => \$T2H_TOC_FILE, + verbose => 'use $s as ToC file, instead of _toc.html', +}; + +# -frames +# if set, output two additional files which use HTML 4.0 "frames". +$T2H_FRAMES = 0; +$T2H_OPTIONS -> {frames} = +{ + type => '!', + linkage => \$T2H_FRAMES, + verbose => 'output files which use HTML 4.0 frames (experimental)', + noHelp => 1, +}; + + +# -menu | -nomenu +# if set, show the Texinfo menus +$T2H_SHOW_MENU = 1; +$T2H_OPTIONS -> {menu} = +{ + type => '!', + linkage => \$T2H_SHOW_MENU, + verbose => 'ouput Texinfo menus', +}; + +# -number | -nonumber +# if set, number sections and show section names and numbers in references +# and menus +$T2H_NUMBER_SECTIONS = 1; +$T2H_OPTIONS -> {number} = +{ + type => '!', + linkage => \$T2H_NUMBER_SECTIONS, + verbose => 'use numbered sections' +}; + +# if set, and T2H_NUMBER_SECTIONS is set, then use node names in menu +# entries, instead of section names +$T2H_NODE_NAME_IN_MENU = 0; + +# if set and menu entry equals menu descr, then do not print menu descr. +# Likewise, if node name equals entry name, do not print entry name. +$T2H_AVOID_MENU_REDUNDANCY = 1; + +# -split section|chapter|none +# if set to 'section' (resp. 'chapter') create one html file per (sub)section +# (resp. chapter) and separate pages for Top, ToC, Overview, Index, +# Glossary, About. +# otherwise, create monolithic html file which contains whole document +#$T2H_SPLIT = 'section'; +$T2H_SPLIT = ''; +$T2H_OPTIONS -> {split} = +{ + type => '=s', + linkage => \$T2H_SPLIT, + verbose => 'split document on section|chapter else no splitting', +}; + +# -section_navigation|-no-section_navigation +# if set, then navigation panels are printed at the beginning of each section +# and, possibly at the end (depending on whether or not there were more than +# $T2H_WORDS_IN_PAGE words on page +# This is most useful if you do not want to have section navigation +# on -split chapter +$T2H_SECTION_NAVIGATION = 1; +$T2H_OPTIONS -> {sec_nav} = +{ + type => '!', + linkage => \$T2H_SECTION_NAVIGATION, + verbose => 'output navigation panels for each section', +}; + +# -subdir +# if set put result files in this directory +# if not set result files are put into current directory +#$T2H_SUBDIR = 'html'; +$T2H_SUBDIR = ''; +$T2H_OPTIONS -> {subdir} = +{ + type => '=s', + linkage => \$T2H_SUBDIR, + verbose => 'put HTML files in directory $s, instead of $cwd', +}; + +# -short_extn +# If this is set all HTML file will have extension ".htm" instead of +# ".html". This is helpful when shipping the document to PC systems. +$T2H_SHORTEXTN = 0; +$T2H_OPTIONS -> {short_ext} = +{ + type => '!', + linkage => \$T2H_SHORTEXTN, + verbose => 'use "htm" extension for output HTML files', +}; + + +# -prefix +# Set the output file prefix, prepended to all .html, .gif and .pl files. +# By default, this is the basename of the document +$T2H_PREFIX = ''; +$T2H_OPTIONS -> {prefix} = +{ + type => '=s', + linkage => \$T2H_PREFIX, + verbose => 'use as prefix for output files, instead of ', +}; + +# -o filename +# If set, generate monolithic document output html into $filename +$T2H_OUT = ''; +$T2H_OPTIONS -> {out_file} = +{ + type => '=s', + linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, + verbose => 'if set, all HTML output goes into file $s', +}; + +# -short_ref +#if set cross-references are given without section numbers +$T2H_SHORT_REF = ''; +$T2H_OPTIONS -> {short_ref} = +{ + type => '!', + linkage => \$T2H_SHORT_REF, + verbose => 'if set, references are without section numbers', +}; + +# -idx_sum +# if value is set, then for each @prinindex $what +# $docu_name_$what.idx is created which contains lines of the form +# $key\t$ref sorted alphabetically (case matters) +$T2H_IDX_SUMMARY = 0; +$T2H_OPTIONS -> {idx_sum} = +{ + type => '!', + linkage => \$T2H_IDX_SUMMARY, + verbose => 'if set, also output index summary', + noHelp => 1, +}; + +# -verbose +# if set, chatter about what we are doing +$T2H_VERBOSE = ''; +$T2H_OPTIONS -> {Verbose} = +{ + type => '!', + linkage => \$T2H_VERBOSE, + verbose => 'print progress info to stdout', +}; + +# -lang +# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title. +# To add a new language, supply list of titles (see $T2H_WORDS below). +# and use ISO 639 language codes (see e.g. perl module Locale-Codes-1.02 +# for definitions) +# Default's to 'en' if not set or no @documentlanguage is specified +$T2H_LANG = ''; +$T2H_OPTIONS -> {lang} = +{ + type => '=s', + linkage => sub {SetDocumentLanguage($_[1])}, + verbose => 'use $s as document language (ISO 639 encoding)', +}; + +# -l2h +# if set, uses latex2html for generation of math content +$T2H_L2H = ''; +$T2H_OPTIONS -> {l2h} = +{ + type => '!', + linkage => \$T2H_L2H, + verbose => 'if set, uses latex2html for @math and @tex', +}; + +###################### +# The following options are only relevant if $T2H_L2H is set +# +# -l2h_l2h +# name/location of latex2html progam +$T2H_L2H_L2H = "latex2html"; +$T2H_OPTIONS -> {l2h_l2h} = +{ + type => '=s', + linkage => \$T2H_L2H_L2H, + verbose => 'program to use for latex2html translation', + noHelp => 1, +}; + +# -l2h_skip +# if set, skips actual call to latex2html tries to reuse previously generated +# content, instead +$T2H_L2H_SKIP = ''; +$T2H_OPTIONS -> {l2h_skip} = +{ + type => '!', + linkage => \$T2H_L2H_SKIP, + verbose => 'if set, tries to reuse previously latex2html output', + noHelp => 1, +}; + +# -l2h_tmp +# if set, l2h uses this directory for temporarary files. The path +# leading to this directory may not contain a dot (i.e., a "."), +# otherwise, l2h will fail +$T2H_L2H_TMP = ''; +$T2H_OPTIONS -> {l2h_tmp} = +{ + type => '=s', + linkage => \$T2H_L2H_TMP, + verbose => 'if set, uses $s as temporary latex2html directory', + noHelp => 1, +}; + +# if set, cleans intermediate files (they all have the prefix $doc_l2h_) +# of l2h +$T2H_L2H_CLEAN = 1; +$T2H_OPTIONS -> {l2h_clean} = +{ + type => '!', + linkage => \$T2H_L2H_CLEAN, + verbose => 'if set, do not keep intermediate latex2html files for later reuse', + noHelp => 1, +}; + +$T2H_OPTIONS -> {D} = +{ + type => '=s', + linkage => sub {$main::value{@_[1]} = 1;}, + verbose => 'equivalent to Texinfo "@set $s 1"', + noHelp => 1, +}; + +$T2H_OPTIONS -> {init_file} = +{ + type => '=s', + linkage => \&LoadInitFile, + verbose => 'load init file $s' +}; + + +############################################################################## +# +# The following can only be set in the init file +# +############################################################################## + +# if set, center @image by default +# otherwise, do not center by default +$T2H_CENTER_IMAGE = 1; + +# used as identation for block enclosing command @example, etc +# If not empty, must be enclosed in +$T2H_EXAMPLE_INDENT_CELL = ''; +# same as above, only for @small +$T2H_SMALL_EXAMPLE_INDENT_CELL = ''; +# font size for @small +$T2H_SMALL_FONT_SIZE = '-1'; + +# if non-empty, and no @..heading appeared in Top node, then +# use this as header for top node/section, otherwise use value of +# @settitle or @shorttitle (in that order) +$T2H_TOP_HEADING = ''; + +# if set, use this chapter for 'Index' button, else +# use first chapter whose name matches 'index' (case insensitive) +$T2H_INDEX_CHAPTER = ''; + +# if set and $T2H_SPLIT is set, then split index pages at the next letter +# after they have more than that many entries +$T2H_SPLIT_INDEX = 100; + +# if set (e.g., to index.html) replace hrefs to this file +# (i.e., to index.html) by ./ +$T2H_HREF_DIR_INSTEAD_FILE = ''; + +######################################################################## +# Language dependencies: +# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash +# To redefine one word, simply do: +# $T2H_WORDS->{}->{} = 'whatever' in your personal init file. +# +$T2H_WORDS_EN = +{ + # titles of pages + 'ToC_Title' => 'Table of Contents', + 'Overview_Title' => 'Short Table of Contents', + 'Index_Title' => 'Index', + 'About_Title' => 'About this document', + 'Footnotes_Title' => 'Footnotes', + 'See' => 'See', + 'see' => 'see', + 'section' => 'section', +# If necessary, we could extend this as follows: +# # text for buttons +# 'Top_Button' => 'Top', +# 'ToC_Button' => 'Contents', +# 'Overview_Button' => 'Overview', +# 'Index_button' => 'Index', +# 'Back_Button' => 'Back', +# 'FastBack_Button' => 'FastBack', +# 'Prev_Button' => 'Prev', +# 'Up_Button' => 'Up', +# 'Next_Button' => 'Next', +# 'Forward_Button' =>'Forward', +# 'FastWorward_Button' => 'FastForward', +# 'First_Button' => 'First', +# 'Last_Button' => 'Last', +# 'About_Button' => 'About' +}; + +$T2H_WORD_DE = +{ + 'ToC_Title' => 'Inhaltsverzeichniss', + 'Overview_Title' => 'Kurzes Inhaltsverzeichniss', + 'Index_Title' => 'Index', + 'About_Title' => 'Über dieses Dokument', + 'Footnotes_Title' => 'Fußnoten', + 'See' => 'Siehe', + 'see' => 'siehe', + 'section' => 'Abschnitt', +}; + +$T2H_WORD_NL = +{ + 'ToC_Title' => 'Inhoudsopgave', + 'Overview_Title' => 'Korte inhoudsopgave', + 'Index_Title' => 'Index', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'No translation available!', #No translation available! + 'See' => 'Zie', + 'see' => 'zie', + 'section' => 'sectie', +}; + +$T2H_WORD_ES = +{ + 'ToC_Title' => 'índice General', + 'Overview_Title' => 'Resumen del Contenido', + 'Index_Title' => 'Index', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'Fußnoten', + 'See' => 'Véase', + 'see' => 'véase', + 'section' => 'sección', +}; + +$T2H_WORD_NO = +{ + 'ToC_Title' => 'Innholdsfortegnelse', + 'Overview_Title' => 'Kort innholdsfortegnelse', + 'Index_Title' => 'Indeks', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'No translation available!', + 'See' => 'Se', + 'see' => 'se', + 'section' => 'avsnitt', +}; + +$T2H_WORD_PT = +{ + 'ToC_Title' => 'Sumário', + 'Overview_Title' => 'Breve Sumário', + 'Index_Title' => 'Índice', #Not sure ;-) + 'About_Title' => 'No translation available!', #No translation available! + 'Footnotes_Title' => 'No translation available!', + 'See' => 'Veja', + 'see' => 'veja', + 'section' => 'Seção', +}; + +$T2H_WORDS = +{ + 'en' => $T2H_WORDS_EN, + 'de' => $T2H_WORDS_DE, + 'nl' => $T2H_WORDS_NL, + 'es' => $T2H_WORDS_ES, + 'no' => $T2H_WORDS_NO, + 'pt' => $T2H_WORDS_PT +}; + +@MONTH_NAMES_EN = +( + 'January', 'February', 'March', 'April', 'May', + 'June', 'July', 'August', 'September', 'October', + 'November', 'December' +); + +@MONTH_NAMES_DE = +( + 'Januar', 'Februar', 'März', 'April', 'Mai', + 'Juni', 'Juli', 'August', 'September', 'Oktober', + 'November', 'Dezember' +); + +@MONTH_NAMES_NL = +( + 'Januari', 'Februari', 'Maart', 'April', 'Mei', + 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', + 'November', 'December' +); + +@MONTH_NAMES_ES = +( + 'enero', 'febrero', 'marzo', 'abril', 'mayo', + 'junio', 'julio', 'agosto', 'septiembre', 'octubre', + 'noviembre', 'diciembre' +); + +@MONTH_NAMES_NO = +( + + 'januar', 'februar', 'mars', 'april', 'mai', + 'juni', 'juli', 'august', 'september', 'oktober', + 'november', 'desember' +); + +@MONTH_NAMES_PT = +( + 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', + 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', + 'Novembro', 'Dezembro' +); + + +$MONTH_NAMES = +{ + 'en' => \@MONTH_NAMES_EN, + 'de' => \@MONTH_NAMES_DE, + 'es' => \@MONTH_NAMES_ES, + 'nl' => \@MONTH_NAMES_NL, + 'no' => \@MONTH_NAMES_NO, + 'pt' => \@MONTH_NAMES_PT +}; +######################################################################## +# Control of Page layout: +# You can make changes of the Page layout at two levels: +# 1.) For small changes, it is often enough to change the value of +# some global string/hash/array variables +# 2.) For larger changes, reimplement one of the T2H_DEFAULT_* routines, +# give them another name, and assign them to the respective +# $T2H_ variable. + +# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold +# href, html-name, node-name of +# This -- current section (resp. html page) +# Top -- top page ($T2H_TOP_FILE) +# Contents -- Table of contents +# Overview -- Short table of contents +# Index -- Index page +# About -- page which explain "navigation buttons" +# First -- first node +# Last -- last node +# +# Whether or not the following hash values are set, depends on the context +# (all values are w.r.t. 'This' section) +# Next -- next node of texinfo +# Prev -- previous node of texinfo +# Up -- up node of texinfo +# Forward -- next node in reading order +# Back -- previous node in reading order +# FastForward -- if leave node, up and next, else next node +# FastBackward-- if leave node, up and prev, else prev node +# +# Furthermore, the following global variabels are set: +# $T2H_THISDOC{title} -- title as set by @setttile +# $T2H_THISDOC{fulltitle} -- full title as set by @title... +# $T2H_THISDOC{subtitle} -- subtitle as set by @subtitle +# $T2H_THISDOC{author} -- author as set by @author +# +# and pointer to arrays of lines which need to be printed by t2h_print_lines +# $T2H_OVERVIEW -- lines of short table of contents +# $T2H_TOC -- lines of table of contents +# $T2H_TOP -- lines of Top texinfo node +# $T2H_THIS_SECTION -- lines of 'This' section + +# +# There are the following subs which control the layout: +# +$T2H_print_section = \&T2H_DEFAULT_print_section; +$T2H_print_Top_header = \&T2H_DEFAULT_print_Top_header; +$T2H_print_Top_footer = \&T2H_DEFAULT_print_Top_footer; +$T2H_print_Top = \&T2H_DEFAULT_print_Top; +$T2H_print_Toc = \&T2H_DEFAULT_print_Toc; +$T2H_print_Overview = \&T2H_DEFAULT_print_Overview; +$T2H_print_Footnotes = \&T2H_DEFAULT_print_Footnotes; +$T2H_print_About = \&T2H_DEFAULT_print_About; +$T2H_print_misc_header = \&T2H_DEFAULT_print_misc_header; +$T2H_print_misc_footer = \&T2H_DEFAULT_print_misc_footer; +$T2H_print_misc = \&T2H_DEFAULT_print_misc; +$T2H_print_chapter_header = \&T2H_DEFAULT_print_chapter_header; +$T2H_print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; +$T2H_print_page_head = \&T2H_DEFAULT_print_page_head; +$T2H_print_page_foot = \&T2H_DEFAULT_print_page_foot; +$T2H_print_head_navigation = \&T2H_DEFAULT_print_head_navigation; +$T2H_print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; +$T2H_button_icon_img = \&T2H_DEFAULT_button_icon_img; +$T2H_print_navigation = \&T2H_DEFAULT_print_navigation; +$T2H_about_body = \&T2H_DEFAULT_about_body; +$T2H_print_frame = \&T2H_DEFAULT_print_frame; +$T2H_print_toc_frame = \&T2H_DEFAULT_print_toc_frame; + +######################################################################## +# Layout for html for every sections +# +sub T2H_DEFAULT_print_section +{ + my $fh = shift; + local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS; + &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION; + my $nw = t2h_print_lines($fh); + if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION) + { + &$T2H_print_foot_navigation($fh, $nw); + } + else + { + print $fh '
    ' . "\n"; + } +} + +################################################################### +# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, +# @html within the Top texinfo node to specify content of top-level +# page. +# +# If you enclose everything in @ifnothtml, then title, subtitle, +# author and overview is printed +# T2H_HREF of Next, Prev, Up, Forward, Back are not defined +# if $T2H_SPLIT then Top page is in its own html file +sub T2H_DEFAULT_print_Top_header +{ + &$T2H_print_page_head(@_) if $T2H_SPLIT; + t2h_print_label(@_); # this needs to be called, otherwise no label set + &$T2H_print_head_navigation(@_); +} +sub T2H_DEFAULT_print_Top_footer +{ + &$T2H_print_foot_navigation(@_); + &$T2H_print_page_foot(@_) if $T2H_SPLIT; +} +sub T2H_DEFAULT_print_Top +{ + my $fh = shift; + + # for redefining navigation buttons use: + # local $T2H_BUTTONS = [...]; + # as it is, 'Top', 'Contents', 'Index', 'About' are printed + local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; + &$T2H_print_Top_header($fh); + if ($T2H_THIS_SECTION) + { + # if top-level node has content, then print it with extra header + print $fh "

    $T2H_NAME{Top}

    " + unless ($T2H_HAS_TOP_HEADING); + t2h_print_lines($fh, $T2H_THIS_SECTION) + } + else + { + # top-level node is fully enclosed in @ifnothtml + # print fulltitle, subtitle, author, Overview + print $fh + "
    \n

    " . + join("

    \n

    ", split(/\n/, $T2H_THISDOC{fulltitle})) . + "

    \n"; + print $fh "

    $T2H_THISDOC{subtitle}

    \n" if $T2H_THISDOC{subtitle}; + print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author}; + print $fh < +
    +

    +

    Overview:

    +
    +EOT + t2h_print_lines($fh, $T2H_OVERVIEW); + print $fh "
    \n"; + } + &$T2H_print_Top_footer($fh); +} + +################################################################### +# Layout of Toc, Overview, and Footnotes pages +# By default, we use "normal" layout +# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined +# use: local $T2H_BUTTONS = [...] to redefine navigation buttons +sub T2H_DEFAULT_print_Toc +{ + return &$T2H_print_misc(@_); +} +sub T2H_DEFAULT_print_Overview +{ + return &$T2H_print_misc(@_); +} +sub T2H_DEFAULT_print_Footnotes +{ + return &$T2H_print_misc(@_); +} +sub T2H_DEFAULT_print_About +{ + return &$T2H_print_misc(@_); +} + +sub T2H_DEFAULT_print_misc_header +{ + &$T2H_print_page_head(@_) if $T2H_SPLIT; + # this needs to be called, otherwise, no labels are set + t2h_print_label(@_); + &$T2H_print_head_navigation(@_); +} +sub T2H_DEFAULT_print_misc_footer +{ + &$T2H_print_foot_navigation(@_); + &$T2H_print_page_foot(@_) if $T2H_SPLIT; +} +sub T2H_DEFAULT_print_misc +{ + my $fh = shift; + local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; + &$T2H_print_misc_header($fh); + print $fh "

    $T2H_NAME{This}

    \n"; + t2h_print_lines($fh); + &$T2H_print_misc_footer($fh); +} + +################################################################### +# chapter_header and chapter_footer are only called if +# T2H_SPLIT eq 'chapter' +# chapter_header: after print_page_header, before print_section +# chapter_footer: after print_section of last section, before print_page_footer +# +# If you want to get rid of navigation stuff after each section, +# redefine print_section such that it does not call print_navigation, +# and put print_navigation into print_chapter_header +@T2H_CHAPTER_BUTTONS = + ( + 'FastBack', 'FastForward', ' ', + ' ', ' ', ' ', ' ', + 'Top', 'Contents', 'Index', 'About', + ); + +sub T2H_DEFAULT_print_chapter_header +{ + # nothing to do there, by default + if (! $T2H_SECTION_NAVIGATION) + { + my $fh = shift; + local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; + &$T2H_print_navigation($fh); + print $fh "\n
    \n"; + } +} + +sub T2H_DEFAULT_print_chapter_footer +{ + local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; + &$T2H_print_navigation(@_); +} +################################################################### +$T2H_TODAY = &pretty_date; # like "20 September 1993" + +sub pretty_date { + local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); + + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + $year += ($year < 70) ? 2000 : 1900; + # obachman: Let's do it as the Americans do + return($MONTH_NAMES->{$T2H_LANG}[$mon] . ", " . $mday . " " . $year); +} + + +################################################################### +# Layout of standard header and footer +# + +# Set the default body text, inserted between +###$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; +$T2H_BODYTEXT = 'LANG="' . $T2H_LANG . '" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; +# text inserted after +$T2H_AFTER_BODY_OPEN = ''; +#text inserted before +$T2H_PRE_BODY_CLOSE = ''; +# this is used in footer +$T2H_ADDRESS = "by $T2H_USER " if $T2H_USER; +$T2H_ADDRESS .= "on $T2H_TODAY"; +# this is added inside after and some META NAME stuff +# can be used for <style> <script>, <meta> tags +$T2H_EXTRA_HEAD = ''; + +sub T2H_DEFAULT_print_page_head +{ + my $fh = shift; + my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}"; + print $fh <<EOT; +<HTML> +$T2H_DOCTYPE +<!-- Created on $T2H_TODAY by $THISPROG --> +<!-- +$T2H_AUTHORS +--> +<HEAD> +<TITLE>$longtitle + + + + + + +$T2H_EXTRA_HEAD + + + +$T2H_AFTER_BODY_OPEN +EOT +} + +sub T2H_DEFAULT_print_page_foot +{ + my $fh = shift; + print $fh < + +This document was generated +$T2H_ADDRESS +using texi2html +$T2H_PRE_BODY_CLOSE + + +EOT +} + +################################################################### +# Layout of navigation panel + +# if this is set, then a vertical navigation panel is used +$T2H_VERTICAL_HEAD_NAVIGATION = 0; +sub T2H_DEFAULT_print_head_navigation +{ + my $fh = shift; + if ($T2H_VERTICAL_HEAD_NAVIGATION) + { + print $fh < +
    + +
    ' . + &t2h_anchor('', $href, $entry) . + '  ' . + $descr . + "
    ' . + $entry . + '' . $descr . + "
      
    +EOT + } + &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION); + if ($T2H_VERTICAL_HEAD_NAVIGATION) + { + print $fh < + +EOT + } + elsif ($T2H_SPLIT eq 'section') + { + print $fh "
    \n"; + } +} + +# Specifies the minimum page length required before a navigation panel +# is placed at the bottom of a page (the default is that of latex2html) +# T2H_THIS_WORDS_IN_PAGE holds number of words of current page +$T2H_WORDS_IN_PAGE = 300; +sub T2H_DEFAULT_print_foot_navigation +{ + my $fh = shift; + my $nwords = shift; + if ($T2H_VERTICAL_HEAD_NAVIGATION) + { + print $fh < +
    +EOT + } + print $fh "
    \n"; + &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE) +} + +###################################################################### +# navigation panel +# +# specify in this array which "buttons" should appear in which order +# in the navigation panel for sections; use ' ' for empty buttons (space) +@T2H_SECTION_BUTTONS = + ( + 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', + ' ', ' ', ' ', ' ', + 'Top', 'Contents', 'Index', 'About', + ); + +# buttons for misc stuff +@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); + +# insert here name of icon images for buttons +# Icons are used, if $T2H_ICONS and resp. value are set +%T2H_ACTIVE_ICONS = + ( + 'Top', '', + 'Contents', '', + 'Overview', '', + 'Index', '', + 'Back', '', + 'FastBack', '', + 'Prev', '', + 'Up', '', + 'Next', '', + 'Forward', '', + 'FastForward', '', + 'About' , '', + 'First', '', + 'Last', '', + ' ', '' + ); + +# insert here name of icon images for these, if button is inactive +%T2H_PASSIVE_ICONS = + ( + 'Top', '', + 'Contents', '', + 'Overview', '', + 'Index', '', + 'Back', '', + 'FastBack', '', + 'Prev', '', + 'Up', '', + 'Next', '', + 'Forward', '', + 'FastForward', '', + 'About', '', + 'First', '', + 'Last', '', + ); + +# how to create IMG tag +sub T2H_DEFAULT_button_icon_img +{ + my $button = shift; + my $icon = shift; + my $name = shift; + return qq{$button: $name}; +} + +# Names of text as alternative for icons +%T2H_NAVIGATION_TEXT = + ( + 'Top', 'Top', + 'Contents', 'Contents', + 'Overview', 'Overview', + 'Index', 'Index', + ' ', '   ', + 'Back', ' < ', + 'FastBack', ' << ', + 'Prev', 'Prev', + 'Up', ' Up ', + 'Next', 'Next', + 'Forward', ' > ', + 'FastForward', ' >> ', + 'About', ' ? ', + 'First', ' |< ', + 'Last', ' >| ' + ); + +sub T2H_DEFAULT_print_navigation +{ + my $fh = shift; + my $vertical = shift; + my $spacing = 1; + print $fh "\n"; + + print $fh "" unless $vertical; + for $button (@$T2H_BUTTONS) + { + print $fh qq{\n} if $vertical; + print $fh qq{\n"; + print $fh "\n" if $vertical; + } + print $fh "" unless $vertical; + print $fh "
    }; + + if (ref($button) eq 'CODE') + { + &$button($fh, $vertical); + } + elsif ($button eq ' ') + { # handle space button + print $fh + $T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ? + &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) : + $T2H_NAVIGATION_TEXT{' '}; + next; + } + elsif ($T2H_HREF{$button}) + { # button is active + print $fh + $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ? + t2h_anchor('', $T2H_HREF{$button}, # yes + &$T2H_button_icon_img($button, + $T2H_ACTIVE_ICONS{$button}, + $T2H_NAME{$button})) + : # use text + "[" . + t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) . + "]"; + } + else + { # button is passive + print $fh + $T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ? + &$T2H_button_icon_img($button, + $T2H_PASSIVE_ICONS{$button}, + $T2H_NAME{$button}) : + + "[" . $T2H_NAVIGATION_TEXT{$button} . "]"; + } + print $fh "
    \n"; +} + +###################################################################### +# Frames: this is from "Richard Y. Kim" +# Should be improved to be more conforming to other _print* functions + +sub T2H_DEFAULT_print_frame +{ + my $fh = shift; + print $fh < +$T2H_THISDOC{title} + + + + + +EOT +} + +sub T2H_DEFAULT_print_toc_frame +{ + my $fh = shift; + &$T2H_print_page_head($fh); + print $fh <Content +EOT + print $fh map {s/HREF=/target=\"main\" HREF=/; $_;} @stoc_lines; + print $fh "\n"; +} + +###################################################################### +# About page +# + +# T2H_PRE_ABOUT might be a function +$T2H_PRE_ABOUT = <texi2html +

    +EOT +$T2H_AFTER_ABOUT = ''; + +sub T2H_DEFAULT_about_body +{ + my $about; + if (ref($T2H_PRE_ABOUT) eq 'CODE') + { + $about = &$T2H_PRE_ABOUT(); + } + else + { + $about = $T2H_PRE_ABOUT; + } + $about .= <

    + + + + + + + +EOT + + for $button (@T2H_SECTION_BUTTONS) + { + next if $button eq ' ' || ref($button) eq 'CODE'; + $about .= < + + + + +EOT + } + + $about .= < +

    +where the Example assumes that the current position +is at Subsubsection One-Two-Three of a document of +the following structure: +
      +
    • 1. Section One
    • +
        +
      • 1.1 Subsection One-One
      • +
          +
        • ...
        • +
        +
      • 1.2 Subsection One-Two
      • +
          +
        • 1.2.1 Subsubsection One-Two-One +
        • 1.2.2 Subsubsection One-Two-Two +
        • 1.2.3 Subsubsection One-Two-Three     +<== Current Position +
        • 1.2.4 Subsubsection One-Two-Four +
        +
      • 1.3 Subsection One-Three
      • +
          +
        • ...
        • +
        +
      • 1.4 Subsection One-Four
      • +
      +
    +$T2H_AFTER_ABOUT +EOT + return $about; +} + + +%T2H_BUTTONS_GOTO = + ( + 'Top', 'cover (top) of document', + 'Contents', 'table of contents', + 'Overview', 'short table of contents', + 'Index', 'concept index', + 'Back', 'previous section in reading order', + 'FastBack', 'previous or up-and-previous section ', + 'Prev', 'previous section same level', + 'Up', 'up section', + 'Next', 'next section same level', + 'Forward', 'next section in reading order', + 'FastForward', 'next or up-and-next section', + 'About' , 'this page', + 'First', 'first section in reading order', + 'Last', 'last section in reading order', + ); + +%T2H_BUTTONS_EXAMPLE = +( + 'Top', '   ', + 'Contents', '   ', + 'Overview', '   ', + 'Index', '   ', + 'Back', '1.2.2', + 'FastBack', '1.1', + 'Prev', '1.2.2', + 'Up', '1.2', + 'Next', '1.2.4', + 'Forward', '1.2.4', + 'FastForward', '1.3', + 'About', '   ', + 'First', '1.', + 'Last', '1.2.4', +); + + +###################################################################### +# from here on, its l2h init stuff +# + +## initialization for latex2html as for Singular manual generation +## obachman 3/99 + +# +# Options controlling Titles, File-Names, Tracing and Sectioning +# +$TITLE = ''; + +$SHORTEXTN = 0; + +$LONG_TITLES = 0; + +$DESTDIR = ''; # should be overwritten by cmd-line argument + +$NO_SUBDIR = 0;# should be overwritten by cmd-line argument + +$PREFIX = ''; # should be overwritten by cmd-line argument + +$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used + +$AUTO_LINK = 0; + +$SPLIT = 0; + +$MAX_LINK_DEPTH = 0; + +$TMP = ''; # should be overwritten by cmd-line argument + +$DEBUG = 0; + +$VERBOSE = 1; + +# +# Options controlling Extensions and Special Features +# +$HTML_VERSION = "3.2"; + +$TEXDEFS = 1; # we absolutely need that + +$EXTERNAL_FILE = ''; + +$SCALABLE_FONTS = 1; + +$NO_SIMPLE_MATH = 1; + +$LOCAL_ICONS = 1; + +$SHORT_INDEX = 0; + +$NO_FOOTNODE = 1; + +$ADDRESS = ''; + +$INFO = ''; + +# +# Switches controlling Image Generation +# +$ASCII_MODE = 0; + +$NOLATEX = 0; + +$EXTERNAL_IMAGES = 0; + +$PS_IMAGES = 0; + +$NO_IMAGES = 0; + +$IMAGES_ONLY = 0; + +$REUSE = 2; + +$ANTI_ALIAS = 1; + +$ANTI_ALIAS_TEXT = 1; + +# +#Switches controlling Navigation Panels +# +$NO_NAVIGATION = 1; +$ADDRESS = ''; +$INFO = 0; # 0 = do not make a "About this document..." section + +# +#Switches for Linking to other documents +# +# actuall -- we don't care + +$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth + +$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth + +$NOLATEX = 0; # 1 = do not pass unknown environments to Latex + +$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document + +$ASCII_MODE = 0; # 1 = do not use any icons or internal images + +# 1 = use links to external postscript images rather than inlined bitmap +# images. +$PS_IMAGES = 0; +$SHOW_SECTION_NUMBERS = 0; + +### Other global variables ############################################### +$CHILDLINE = ""; + +# This is the line width measured in pixels and it is used to right justify +# equations and equation arrays; +$LINE_WIDTH = 500; + +# Used in conjunction with AUTO_NAVIGATION +$WORDS_IN_PAGE = 300; + +# Affects ONLY the way accents are processed +$default_language = 'english'; + +# The value of this variable determines how many words to use in each +# title that is added to the navigation panel (see below) +# +$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; + +# This number will determine the size of the equations, special characters, +# and anything which will be converted into an inlined image +# *except* "image generating environments" such as "figure", "table" +# or "minipage". +# Effective values are those greater than 0. +# Sensible values are between 0.1 - 4. +$MATH_SCALE_FACTOR = 1.5; + +# This number will determine the size of +# image generating environments such as "figure", "table" or "minipage". +# Effective values are those greater than 0. +# Sensible values are between 0.1 - 4. +$FIGURE_SCALE_FACTOR = 1.6; + + +# If both of the following two variables are set then the "Up" button +# of the navigation panel in the first node/page of a converted document +# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set +# to some text which describes this external link. +$EXTERNAL_UP_LINK = ""; +$EXTERNAL_UP_TITLE = ""; + +# If this is set then the resulting HTML will look marginally better if viewed +# with Netscape. +$NETSCAPE_HTML = 1; + +# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" +# Paper sizes has no effect other than in the time it takes to create inlined +# images and in whether large images can be created at all ie +# - larger paper sizes *MAY* help with large image problems +# - smaller paper sizes are quicker to handle +$PAPERSIZE = "a4"; + +# Replace "english" with another language in order to tell LaTeX2HTML that you +# want some generated section titles (eg "Table of Contents" or "References") +# to appear in a different language. Currently only "english" and "french" +# is supported but it is very easy to add your own. See the example in the +# file "latex2html.config" +$TITLES_LANGUAGE = "english"; + +1; # This must be the last non-comment line + +# End File texi2html.init +###################################################################### + + +require "$ENV{T2H_HOME}/texi2html.init" + if ($0 =~ /\.pl$/ && + -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); + +#+++############################################################################ +# # +# Initialization # +# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing # +# # +#---############################################################################ + +# leave this within comments, and keep the require statement +# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init +# exists. + +# +package Getopt::MySimple; + +# Name: +# Getopt::MySimple. +# +# Documentation: +# POD-style (incomplete) documentation is in file MySimple.pod +# +# Tabs: +# 4 spaces || die. +# +# Author: +# Ron Savage rpsavage@ozemail.com.au. +# 1.00 19-Aug-97 Initial version. +# 1.10 13-Oct-97 Add arrays of switches (eg '=s@'). +# 1.20 3-Dec-97 Add 'Help' on a per-switch basis. +# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase. +# 1.40 10-Nov-98 Change width of help report. Restructure tests. +# 1-Jul-00 Modifications for Texi2html + +# -------------------------------------------------------------------------- +# Locally modified by obachman (Display type instead of env, order by cmp) +# $Id$ + +# use strict; +# no strict 'refs'; + +use vars qw(@EXPORT @EXPORT_OK @ISA); +use vars qw($fieldWidth $opt $VERSION); + +use Exporter(); +use Getopt::Long; + +@ISA = qw(Exporter); +@EXPORT = qw(); +@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}. + +# -------------------------------------------------------------------------- + +$fieldWidth = 20; +$VERSION = '1.41'; + +# -------------------------------------------------------------------------- + +sub byOrder +{ + my($self) = @_; + + return uc($a) cmp (uc($b)); +} + +# -------------------------------------------------------------------------- + +sub dumpOptions +{ + my($self) = @_; + + print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n"; + + for (sort byOrder keys(%{$self -> {'opt'} }) ) + { + print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n"; + } + + print "\n"; + +} # End of dumpOptions. + +# -------------------------------------------------------------------------- +# Return: +# 0 -> Error. +# 1 -> Ok. + +sub getOptions +{ + push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0. + push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1. + + my($self, $default, $helpText, $versionText, + $helpThenExit, $versionThenExit, $ignoreCase) = @_; + + $helpThenExit = 1 unless (defined($helpThenExit)); + $versionThenExit = 1 unless (defined($versionThenExit)); + $ignoreCase = 0 unless (defined($ignoreCase)); + + $self -> {'default'} = $default; + $self -> {'helpText'} = $helpText; + $self -> {'versionText'} = $versionText; + $Getopt::Long::ignorecase = $ignoreCase; + + unless (defined($self -> {'default'}{'help'})) + { + $self -> {'default'}{'help'} = + { + type => ':i', + default => '', + linkage => sub {$self->helpOptions($_[1]); exit (0) if $helpThenExit;}, + verbose => "print help and exit" + }; + } + + unless (defined($self -> {'default'}{'version'})) + { + $self -> {'default'}{'version'} = + { + type => '', + default => '', + linkage => sub {print $self->{'versionText'}; exit (0) if versionTheExit;}, + verbose => "print version and exit" + }; + } + + for (keys(%{$self -> {'default'} }) ) + { + my $type = ${$self -> {'default'} }{$_}{'type'}; + push(@{$self -> {'type'} }, "$_$type"); + $self->{'opt'}->{$_} = ${$self -> {'default'} }{$_}{'linkage'} + if ${$self -> {'default'} }{$_}{'linkage'}; + } + + my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} }); + + return $result unless $result; + + for (keys(%{$self -> {'default'} }) ) + { + if (! defined(${$self -> {'opt'} }{$_})) #{ + { + ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'}; + } + } + + $result; +} # End of getOptions. + +# -------------------------------------------------------------------------- + +sub helpOptions +{ + my($self) = shift; + my($noHelp) = shift; + $noHelp = 0 unless $noHelp; + my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) + = (10, 5, 9, 78, 4, 11); + + print "$self->{'helpText'}" if ($self -> {'helpText'}); + + print ' Option', ' ' x ($optwidth - length('Option') -1 ), + 'Type', ' ' x ($typewidth - length('Type') + 1), + 'Default', ' ' x ($defaultwidth - length('Default') ), + "Description\n"; + + for (sort byOrder keys(%{$self -> {'default'} }) ) + { + my($line, $help, $option, $val); + $option = $_; + next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp; + $line = " -$_ " . ' ' x ($optwidth - (2 + length) ) . + "${$self->{'default'} }{$_}{'type'} ". + ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); + + $val = ${$self->{'default'} }{$_}{'linkage'}; + if ($val) + { + if (ref($val) eq 'SCALAR') + { + $val = $$val; + } + else + { + $val = ''; + } + } + else + { + $val = ${$self->{'default'} }{$_}{'default'}; + } + $line .= "$val "; + $line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line)); + + if (defined(${$self -> {'default'} }{$_}{'verbose'}) && + ${$self -> {'default'} }{$_}{'verbose'} ne '') + { + $help = "${$self->{'default'} }{$_}{'verbose'}"; + } + else + { + $help = ' '; + } + if ((length("$line") + length($help)) < $maxlinewidth) + { + print $line , $help, "\n"; + } + else + { + print $line, "\n", ' ' x $valind, $help, "\n"; + } + for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}})) + { + print ' ' x ($valind + 2); + print $val, ' ', ' ' x ($valwidth - length($val) - 2); + print ${$self->{'default'}}{$option}{'values'}{$val}, "\n"; + } + } + + print <| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo) + =s | :s mandatory (or, optional) string argument + =i | :i mandatory (or, optional) integer argument +EOT +} # End of helpOptions. + +#------------------------------------------------------------------- + +sub new +{ + my($class) = @_; + my($self) = {}; + $self -> {'default'} = {}; + $self -> {'helpText'} = ''; + $self -> {'opt'} = {}; + $opt = $self -> {'opt'}; # An alias for $self -> {'opt'}. + $self -> {'type'} = (); + + return bless $self, $class; + +} # End of new. + +# -------------------------------------------------------------------------- + +1; + +# End MySimple.pm + +require "$ENV{T2H_HOME}/MySimple.pm" + if ($0 =~ /\.pl$/ && + -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); + +package main; + +#+++############################################################################ +# # +# Constants # +# # +#---############################################################################ + +$DEBUG_TOC = 1; +$DEBUG_INDEX = 2; +$DEBUG_BIB = 4; +$DEBUG_GLOSS = 8; +$DEBUG_DEF = 16; +$DEBUG_HTML = 32; +$DEBUG_USER = 64; +$DEBUG_L2H = 128; + + +$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference +$FILERE = '[\/\w.+-]+'; # RE for a file name +$VARRE = '[^\s\{\}]+'; # RE for a variable name +$NODERE = '[^,:]+'; # RE for a node name +$NODESRE = '[^:]+'; # RE for a list of node names + +$ERROR = "***"; # prefix for errors +$WARN = "**"; # prefix for warnings + + # program home page +$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections + +$CHAPTEREND = "\n"; # to know where a chpater ends +$SECTIONEND = "\n"; # to know where section ends +$TOPEND = "\n"; # to know where top ends + + + +# +# pre-defined indices +# +$index_properties = +{ + 'c' => { name => 'cp'}, + 'f' => { name => 'fn', code => 1}, + 'v' => { name => 'vr', code => 1}, + 'k' => { name => 'ky', code => 1}, + 'p' => { name => 'pg', code => 1}, + 't' => { name => 'tp', code => 1} +}; + + +%predefined_index = ( + 'cp', 'c', + 'fn', 'f', + 'vr', 'v', + 'ky', 'k', + 'pg', 'p', + 'tp', 't', + ); + +# +# valid indices +# +%valid_index = ( + 'c', 1, + 'f', 1, + 'v', 1, + 'k', 1, + 'p', 1, + 't', 1, + ); + +# +# texinfo section names to level +# +%sec2level = ( + 'top', 0, + 'chapter', 1, + 'unnumbered', 1, + 'majorheading', 1, + 'chapheading', 1, + 'appendix', 1, + 'section', 2, + 'unnumberedsec', 2, + 'heading', 2, + 'appendixsec', 2, + 'appendixsection', 2, + 'subsection', 3, + 'unnumberedsubsec', 3, + 'subheading', 3, + 'appendixsubsec', 3, + 'subsubsection', 4, + 'unnumberedsubsubsec', 4, + 'subsubheading', 4, + 'appendixsubsubsec', 4, + ); + +# +# accent map, TeX command to ISO name +# +%accent_map = ( + '"', 'uml', + '~', 'tilde', + '^', 'circ', + '`', 'grave', + '\'', 'acute', + ); + +# +# texinfo "simple things" (@foo) to HTML ones +# +%simple_map = ( + # cf. makeinfo.c + "*", "
    ", # HTML+ + " ", " ", + "\t", " ", + "-", "­", # soft hyphen + "\n", "\n", + "|", "", + 'tab', '<\/TD>
    Button Name Go to From 1.2.3 go to
    +EOT + $about .= + ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? + &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) : + " [" . $T2H_NAVIGATION_TEXT{$button} . "] "); + $about .= < + +$button + +$T2H_BUTTONS_GOTO{$button} + +$T2H_BUTTONS_EXAMPLE{$button} +
    ', + # spacing commands + ":", "", + "!", "!", + "?", "?", + ".", ".", + "-", "", + ); + +# +# texinfo "things" (@foo{}) to HTML ones +# +%things_map = ( + 'TeX', 'TeX', + 'br', '

    ', # paragraph break + 'bullet', '*', + 'copyright', '(C)', + 'dots', '...<\/small>', + 'enddots', '....<\/small>', + 'equiv', '==', + 'error', 'error-->', + 'expansion', '==>', + 'minus', '-', + 'point', '-!-', + 'print', '-|', + 'result', '=>', + 'today', $T2H_TODAY, + 'aa', 'å', + 'AA', 'Å', + 'ae', 'æ', + 'oe', 'œ', + 'AE', 'Æ', + 'OE', 'Œ', + 'o', 'ø', + 'O', 'Ø', + 'ss', 'ß', + 'l', '\/l', + 'L', '\/L', + 'exclamdown', '¡', + 'questiondown', '¿', + 'pounds', '£' + ); + +# +# texinfo styles (@foo{bar}) to HTML ones +# +%style_map = ( + 'acronym', '&do_acronym', + 'asis', '', + 'b', 'B', + 'cite', 'CITE', + 'code', 'CODE', + 'command', 'CODE', + 'ctrl', '&do_ctrl', # special case + 'dfn', 'EM', # DFN tag is illegal in the standard + 'dmn', '', # useless + 'email', '&do_email', # insert a clickable email address + 'emph', 'EM', + 'env', 'CODE', + 'file', '"TT', # will put quotes, cf. &apply_style + 'i', 'I', + 'kbd', 'KBD', + 'key', 'KBD', + 'math', '&do_math', + 'option', '"SAMP', # will put quotes, cf. &apply_style + 'r', '', # unsupported + 'samp', '"SAMP', # will put quotes, cf. &apply_style + 'sc', '&do_sc', # special case + 'strong', 'STRONG', + 't', 'TT', + 'titlefont', '', # useless + 'uref', '&do_uref', # insert a clickable URL + 'url', '&do_url', # insert a clickable URL + 'var', 'VAR', + 'w', '', # unsupported + 'H', '&do_accent', + 'dotaccent', '&do_accent', + 'ringaccent','&do_accent', + 'tieaccent', '&do_accent', + 'u','&do_accent', + 'ubaraccent','&do_accent', + 'udotaccent','&do_accent', + 'v', '&do_accent', + ',', '&do_accent', + 'dotless', '&do_accent' + ); + +# +# texinfo format (@foo/@end foo) to HTML ones +# +%format_map = ( + 'quotation', 'BLOCKQUOTE', + # lists + 'itemize', 'UL', + 'enumerate', 'OL', + # poorly supported + 'flushleft', 'PRE', + 'flushright', 'PRE', + ); + +# +# an eval of these $complex_format_map->{what}->[0] yields beginning +# an eval of these $complex_format_map->{what}->[1] yieleds end +$complex_format_map = +{ + example => + [ + q{"$T2H_EXAMPLE_INDENT_CELL
    "},
    +  q{'
    '} + ], + smallexample => + [ + q{"$T2H_SMALL_EXAMPLE_INDENT_CELL
    "},
    +  q{'
    '} + ], + display => + [ + q{"$T2H_EXAMPLE_INDENT_CELL
    '},
    +  q{'
    '} + ], + smalldisplay => + [ + q{"$T2H_SMALL_EXAMPLE_INDENT_CELL
    '},
    +  q{'
    '} + ] +}; + +$complex_format_map->{lisp} = $complex_format_map->{example}; +$complex_format_map->{smalllisp} = $complex_format_map->{smallexample}; +$complex_format_map->{format} = $complex_format_map->{display}; +$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay}; + +# +# texinfo definition shortcuts to real ones +# +%def_map = ( + # basic commands + 'deffn', 0, + 'defvr', 0, + 'deftypefn', 0, + 'deftypevr', 0, + 'defcv', 0, + 'defop', 0, + 'deftp', 0, + # basic x commands + 'deffnx', 0, + 'defvrx', 0, + 'deftypefnx', 0, + 'deftypevrx', 0, + 'defcvx', 0, + 'defopx', 0, + 'deftpx', 0, + # shortcuts + 'defun', 'deffn Function', + 'defmac', 'deffn Macro', + 'defspec', 'deffn {Special Form}', + 'defvar', 'defvr Variable', + 'defopt', 'defvr {User Option}', + 'deftypefun', 'deftypefn Function', + 'deftypevar', 'deftypevr Variable', + 'defivar', 'defcv {Instance Variable}', + 'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME + 'defmethod', 'defop Method', + 'deftypemethod', 'defop Method', # NEW:FIXME + # x shortcuts + 'defunx', 'deffnx Function', + 'defmacx', 'deffnx Macro', + 'defspecx', 'deffnx {Special Form}', + 'defvarx', 'defvrx Variable', + 'defoptx', 'defvrx {User Option}', + 'deftypefunx', 'deftypefnx Function', + 'deftypevarx', 'deftypevrx Variable', + 'defivarx', 'defcvx {Instance Variable}', + 'defmethodx', 'defopx Method', + ); + +# +# things to skip +# +%to_skip = ( + # comments + 'c', 1, + 'comment', 1, + 'ifnotinfo', 1, + 'ifnottex', 1, + 'ifhtml', 1, + 'end ifhtml', 1, + 'end ifnotinfo', 1, + 'end ifnottex', 1, + # useless + 'detailmenu', 1, + 'direntry', 1, + 'contents', 1, + 'shortcontents', 1, + 'summarycontents', 1, + 'footnotestyle', 1, + 'end ifclear', 1, + 'end ifset', 1, + 'titlepage', 1, + 'end titlepage', 1, + # unsupported commands (formatting) + 'afourpaper', 1, + 'cropmarks', 1, + 'finalout', 1, + 'headings', 1, + 'sp', 1, + 'need', 1, + 'page', 1, + 'setchapternewpage', 1, + 'everyheading', 1, + 'everyfooting', 1, + 'evenheading', 1, + 'evenfooting', 1, + 'oddheading', 1, + 'oddfooting', 1, + 'smallbook', 1, + 'vskip', 1, + 'filbreak', 1, + 'paragraphindent', 1, + # unsupported formats + 'cartouche', 1, + 'end cartouche', 1, + 'group', 1, + 'end group', 1, + ); + +#+++############################################################################ +# # +# Argument parsing, initialisation # +# # +#---############################################################################ + +# +# flush stdout and stderr after every write +# +select(STDERR); +$| = 1; +select(STDOUT); +$| = 1; + + +%value = (); # hold texinfo variables, see also -D +$use_bibliography = 1; +$use_acc = 1; + +# +# called on -init-file +sub LoadInitFile +{ + my $init_file = shift; + # second argument is value of options + $init_file = shift; + if (-f $init_file) + { + print "# reading initialization file from $init_file\n" + if ($T2H_VERBOSE); + require($init_file); + } + else + { + print "$ERROR Error: can't read init file $int_file\n"; + $init_file = ''; + } +} + +# +# called on -lang +sub SetDocumentLanguage +{ + my $lang = shift; + if (! exists($T2H_WORDS->{$lang})) + { + warn "$ERROR: Language specs for '$lang' do not exists. Reverting to '" . + ($T2H_LANG ? T2H_LANG : "en") . "'\n"; + } + else + { + print "# using '$lang' as document language\n" if ($T2H_VERBOSE); + $T2H_LANG = $lang; + } +} + +## +## obsolete cmd line options +## +$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} = +{ + type => '!', + linkage => sub {$main::T2H_SECTION_NAVIGATION = 0;}, + verbose => 'obsolete, use -nosec_nav', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {use_acc} = +{ + type => '!', + linkage => \$use_acc, + verbose => 'obsolete', + noHelp => 2 +}; +$T2H_OBSOLETE_OPTIONS -> {expandinfo} = +{ + type => '!', + linkage => sub {$main::T2H_EXPAND = 'info';}, + verbose => 'obsolete, use "-expand info" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {expandtex} = +{ + type => '!', + linkage => sub {$main::T2H_EXPAND = 'tex';}, + verbose => 'obsolete, use "-expand tex" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {monolithic} = +{ + type => '!', + linkage => sub {$main::T2H_SPLIT = '';}, + verbose => 'obsolete, use "-split no" instead', + noHelp => 2 +}; +$T2H_OBSOLETE_OPTIONS -> {split_node} = +{ + type => '!', + linkage => sub{$main::T2H_SPLIT = 'section';}, + verbose => 'obsolete, use "-split section" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {split_chapter} = +{ + type => '!', + linkage => sub{$main::T2H_SPLIT = 'chapter';}, + verbose => 'obsolete, use "-split chapter" instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {no_verbose} = +{ + type => '!', + linkage => sub {$main::T2H_VERBOSE = 0;}, + verbose => 'obsolete, use -noverbose instead', + noHelp => 2, +}; +$T2H_OBSOLETE_OPTIONS -> {output_file} = +{ + type => '=s', + linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, + verbose => 'obsolete, use -out_file instead', + noHelp => 2 +}; + +$T2H_OBSOLETE_OPTIONS -> {section_navigation} = +{ + type => '!', + linkage => \$T2H_SECTION_NAVIGATION, + verbose => 'obsolete, use -sec_nav instead', + noHelp => 2, +}; + +$T2H_OBSOLETE_OPTIONS -> {verbose} = +{ + type => '!', + linkage => \$T2H_VERBOSE, + verbose => 'obsolete, use -Verbose instead', + noHelp => 2 +}; + +# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc +my $home = $ENV{HOME}; +defined($home) or $home = ''; +foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") { + if (-f $i) { + print "# reading initialization file from $i\n" + if ($T2H_VERBOSE); + require($i); + } +} + + +#+++############################################################################ +# # +# parse command-line options +# # +#---############################################################################ +$T2H_USAGE_TEXT = <getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) +{ + print $Configure_failed if $Configure_failed; + die $T2H_FAILURE_TEXT; +} + +if (@ARGV > 1) +{ + eval {Getopt::Long::Configure("no_pass_through");}; + if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) + { + print $Configure_failed if $Configure_failed; + die $T2H_FAILURE_TEXT; + } +} + +if ($T2H_CHECK) { + die "Need file to check\n$T2H_FAILURE_TEXT" unless @ARGV > 0; + ✓ + exit; +} + +#+++############################################################################ +# # +# evaluation of cmd line options +# # +#---############################################################################ + +if ($T2H_EXPAND eq 'info') +{ + $to_skip{'ifinfo'} = 1; + $to_skip{'end ifinfo'} = 1; +} +elsif ($T2H_EXPAND eq 'tex') +{ + $to_skip{'iftex'} = 1; + $to_skip{'end iftex'} = 1; + +} + +$T2H_INVISIBLE_MARK = '' if $T2H_INVISIBLE_MARK eq 'xbm'; + +# +# file name buisness +# +die "Need exactly one file to translate\n$T2H_FAILURE_TEXT" unless @ARGV == 1; +$docu = shift(@ARGV); +if ($docu =~ /.*\//) { + chop($docu_dir = $&); + $docu_name = $'; +} else { + $docu_dir = '.'; + $docu_name = $docu; +} +unshift(@T2H_INCLUDE_DIRS, $docu_dir); +$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document +$docu_name = $T2H_PREFIX if ($T2H_PREFIX); + +# subdir +if ($T2H_SUBDIR && ! $T2H_OUT) +{ + $T2H_SUBDIR =~ s|/*$||; + unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR") + { + if ( mkdir($T2H_SUBDIR, oct(755))) + { + print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE); + } + else + { + warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n"; + $T2H_SUBDIR = ''; + } + } +} + +if ($T2H_SUBDIR && ! $T2H_OUT) +{ + $docu_rdir = "$T2H_SUBDIR/"; + print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); +} +else +{ + if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|) + { + $docu_rdir = "$1/"; + print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); + } + else + { + print "# putting result files into current directory \n" if ($T2H_VERBOSE); + $docu_rdir = ''; + } +} + +# extension +if ($T2H_SHORTEXTN) +{ + $docu_ext = "htm"; +} +else +{ + $docu_ext = "html"; +} +if ($T2H_TOP_FILE =~ /\..*$/) +{ + $T2H_TOP_FILE = $`.".$docu_ext"; +} + +# result files +if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i)) +{ + $T2H_SPLIT = 'section'; +} +elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i) +{ + $T2H_SPLIT = 'chapter' +} +else +{ + undef $T2H_SPLIT; +} + +$docu_doc = "$docu_name.$docu_ext"; # document's contents +$docu_doc_file = "$docu_rdir$docu_doc"; +if ($T2H_SPLIT) +{ + $docu_toc = $T2H_TOC_FILE || "${docu_name}_toc.$docu_ext"; # document's table of contents + $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc + $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes + $docu_about = "${docu_name}_abt.$docu_ext"; # about this document + $docu_top = $T2H_TOP_FILE || $docu_doc; +} +else +{ + if ($T2H_OUT) + { + $docu_doc = $T2H_OUT; + $docu_doc =~ s|.*/||; + } + $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc; +} + +$docu_toc_file = "$docu_rdir$docu_toc"; +$docu_stoc_file = "$docu_rdir$docu_stoc"; +$docu_foot_file = "$docu_rdir$docu_foot"; +$docu_about_file = "$docu_rdir$docu_about"; +$docu_top_file = "$docu_rdir$docu_top"; + +$docu_frame_file = "$docu_rdir${docu_name}_frame.$docu_ext"; +$docu_toc_frame_file = "$docu_rdir${docu_name}_toc_frame.$docu_ext"; + +# +# variables +# +$value{'html'} = 1; # predefine html (the output format) +$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) +# _foo: internal to track @foo +foreach ('_author', '_title', '_subtitle', + '_settitle', '_setfilename', '_shorttitle') { + $value{$_} = ''; # prevent -w warnings +} +%node2sec = (); # node to section name +%sec2node = (); # section to node name +%sec2number = (); # section to number +%number2sec = (); # number to section +%idx2node = (); # index keys to node +%node2href = (); # node to HREF +%node2next = (); # node to next +%node2prev = (); # node to prev +%node2up = (); # node to up +%bib2href = (); # bibliography reference to HREF +%gloss2href = (); # glossary term to HREF +@sections = (); # list of sections +%tag2pro = (); # protected sections + +# +# initial indexes +# +$bib_num = 0; +$foot_num = 0; +$gloss_num = 0; +$idx_num = 0; +$sec_num = 0; +$doc_num = 0; +$html_num = 0; + +# +# can I use ISO8879 characters? (HTML+) +# +if ($T2H_USE_ISO) { + $things_map{'bullet'} = "•"; + $things_map{'copyright'} = "©"; + $things_map{'dots'} = "…"; + $things_map{'equiv'} = "≡"; + $things_map{'expansion'} = "→"; + $things_map{'point'} = "∗"; + $things_map{'result'} = "⇒"; +} + +# +# read texi2html extensions (if any) +# +$extensions = 'texi2html.ext'; # extensions in working directory +if (-f $extensions) { + print "# reading extensions from $extensions\n" if $T2H_VERBOSE; + require($extensions); +} +($progdir = $0) =~ s/[^\/]+$//; +if ($progdir && ($progdir ne './')) { + $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory + if (-f $extensions) { + print "# reading extensions from $extensions\n" if $T2H_VERBOSE; + require($extensions); + } +} + + +print "# reading from $docu\n" if $T2H_VERBOSE; + +######################################################################### +# +# latex2html stuff +# +# latex2html conversions consist of three stages: +# 1) ToLatex: Put "latex" code into a latex file +# 2) ToHtml: Use latex2html to generate corresponding html code and images +# 3) FromHtml: Extract generated code and images from latex2html run +# + +########################## +# default settings +# + +# defaults for files and names + +sub l2h_Init +{ + local($root) = @_; + + return 0 unless ($root); + + $l2h_name = "${root}_l2h"; + + $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; + $l2h_cache_file = "${docu_rdir}l2h_cache.pm"; + $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H); + + # destination dir -- generated images are put there, should be the same + # as dir of enclosing html document -- + $l2h_html_file = "$docu_rdir${l2h_name}.html"; + $l2h_prefix = "${l2h_name}_"; + return 1; +} + + +########################## +# +# First stage: Generation of Latex file +# Initialize with: l2h_InitToLatex +# Add content with: l2h_ToLatex($text) --> HTML placeholder comment +# Finish with: l2h_FinishToLatex +# + +$l2h_latex_preample = <$l2h_latex_file")) + { + warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n"; + return 0; + } + print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE); + print L2H_LATEX $l2h_latex_preample; + } + # open database for caching + l2h_InitCache(); + $l2h_latex_count = 0; + $l2h_to_latex_count = 0; + $l2h_cached_count = 0; + return 1; +} + +# print text (1st arg) into latex file (if not already there), return +# HTML commentary which can be later on replaced by the latex2html +# generated text +sub l2h_ToLatex +{ + my($text) = @_; + my($count); + + $l2h_to_latex_count++; + $text =~ s/(\s*)$//; + + # try whether we can cache it + my $cached_text = l2h_FromCache($text); + if ($cached_text) + { + $l2h_cached_count++; + return $cached_text; + } + + # try whether we have text already on things to do + unless ($count = $l2h_to_latex{$text}) + { + $count = $l2h_latex_count; + $l2h_latex_count++; + $l2h_to_latex{$text} = $count; + $l2h_to_latex[$count] = $text; + unless ($T2H_L2H_SKIP) + { + print L2H_LATEX "\\begin{rawhtml}\n"; + print L2H_LATEX "\n"; + print L2H_LATEX "\\end{rawhtml}\n"; + + print L2H_LATEX "$text\n"; + + print L2H_LATEX "\\begin{rawhtml}\n"; + print L2H_LATEX "\n"; + print L2H_LATEX "\\end{rawhtml}\n"; + } + } + return ""; +} + +# print closing into latex file and close it +sub l2h_FinishToLatex +{ + local ($reused); + + $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count; + unless ($T2H_L2H_SKIP) + { + print L2H_LATEX $l2h_latex_closing; + close(L2H_LATEX); + } + print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE); + unless ($l2h_latex_count) + { + l2h_Finish(); + return 0; + } + return 1; +} + +################################### +# Second stage: Use latex2html to generate corresponding html code and images +# +# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]): +# Call latex2html on $l2h_latex_file +# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir +# Return 1, on success +# 0, otherwise +# +sub l2h_ToHtml +{ + local($call, $ext, $root, $dotbug); + + if ($T2H_L2H_SKIP) + { + print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE); + return 1; + } + + # Check for dot in directory where dvips will work + if ($T2H_L2H_TMP) + { + if ($T2H_L2H_TMP =~ /\./) + { + warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n"; + $dotbug = 1; + } + } + else + { + if (&getcwd =~ /\./) + { + warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n"; + $dotbug = 1; + } + } + # fix it, if necessary and hope that it works + $T2H_L2H_TMP = "/tmp" if ($dotbug); + + $call = $T2H_L2H_L2H; + # use init file, if specified + $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file); + # set output dir + $call .= ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir"); + # use l2h_tmp, if specified + $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP); + # options we want to be sure of + $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; + $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file"; + + print "# l2h: executing '$call'\n" if ($T2H_VERBOSE); + if (system($call)) + { + warn "l2h ***Error: '${call}' did not succeed\n"; + return 0; + } + else + { + print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE); + return 1; + } +} + +# this is directly pasted over from latex2html +sub getcwd { + local($_) = `pwd`; + + die "'pwd' failed (out of memory?)\n" + unless length; + chop; + $_; +} + + +########################## +# Third stage: Extract generated contents from latex2html run +# Initialize with: l2h_InitFromHtml +# open $l2h_html_file for reading +# reads in contents into array indexed by numbers +# return 1, on success -- 0, otherwise +# Extract Html code with: l2h_FromHtml($text) +# replaces in $text all previosuly inserted comments by generated html code +# returns (possibly changed) $text +# Finish with: l2h_FinishFromHtml +# closes $l2h_html_dir/$l2h_name.".$docu_ext" + +sub l2h_InitFromHtml +{ + local($h_line, $h_content, $count, %l2h_img); + + if (! open(L2H_HTML, "<${l2h_html_file}")) + { + print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n"; + return 0; + } + print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE); + + $l2h_html_count = 0; + + while ($h_line = ) + { + if ($h_line =~ /^/) + { + $count = $1; + $h_content = ""; + while ($h_line = ) + { + if ($h_line =~ /^/) + { + chomp $h_content; + chomp $h_content; + $l2h_html_count++; + $h_content = l2h_ToCache($count, $h_content); + $l2h_from_html[$count] = $h_content; + $h_content = ''; + last; + } + $h_content = $h_content.$h_line; + } + if ($hcontent) + { + print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n" + if ($T2H_VERBOSE); + close(L2H_HTML); + return 0; + } + } + } + print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n" + if ($T2H_VERBOSE); + + close(L2H_HTML); + return 1; +} + +sub l2h_FromHtml +{ + local($text) = @_; + local($done, $to_do, $count); + + $to_do = $text; + + while ($to_do =~ /([^\000]*)([^\000]*)/) + { + $to_do = $1; + $count = $2; + $done = $3.$done; + + $done = "".$done + if ($T2H_DEBUG & $DEBUG_L2H); + + $done = &l2h_ExtractFromHtml($count) . $done; + + $done = "".$done + if ($T2H_DEBUG & $DEBUG_L2H); + } + return $to_do.$done; +} + + +sub l2h_ExtractFromHtml +{ + local($count) = @_; + + return $l2h_from_html[$count] if ($l2h_from_html[$count]); + + if ($count >= 0 && $count < $l2h_latex_count) + { + # now we are in trouble + local($l_l2h, $_); + + $l2h_extract_error++; + print "$ERROR l2h: can't extract content $count from html\n" + if ($T2H_VERBOSE); + # try simple (ordinary) substition (without l2h) + $l_l2h = $T2H_L2H; + $T2H_L2H = 0; + $_ = $l2h_to_latex{$count}; + $_ = &substitute_style($_); + &unprotect_texi; + $_ = "" . $_ + if ($T2H_DEBUG & $DEBUG_L2H); + $T2H_L2H = $l_l2h; + return $_; + } + else + { + # now we have been incorrectly called + $l2h_range_error++; + print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n"; + return "" + if ($T2H_DEBUG & $DEBUG_L2H); + return ""; + } +} + +sub l2h_FinishFromHtml +{ + if ($T2H_VERBOSE) + { + if ($l2h_extract_error + $l2h_range_error) + { + print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n"; + } + else + { + print "# l2h: finished from html (no errors)\n"; + } + } +} + +sub l2h_Finish +{ + l2h_StoreCache(); + if ($T2H_L2H_CLEAN) + { + print "# l2h: removing temporary files generated by l2h extension\n" + if $T2H_VERBOSE; + while (<"$docu_rdir$l2h_name"*>) + { + unlink $_; + } + } + print "# l2h: Finished\n" if $T2H_VERBOSE; + return 1; +} + +############################## +# stuff for l2h caching +# + +# I tried doing this with a dbm data base, but it did not store all +# keys/values. Hence, I did as latex2html does it +sub l2h_InitCache +{ + if (-r "$l2h_cache_file") + { + my $rdo = do "$l2h_cache_file"; + warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n") + unless ($rdo); + } +} + +sub l2h_StoreCache +{ + return unless $l2h_latex_count; + + my ($key, $value); + open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n"; + + + while (($key, $value) = each %l2h_cache) + { + # escape stuff + $key =~ s|/|\\/|g; + $key =~ s|\\\\/|\\/|g; + # weird, a \ at the end of the key results in an error + # maybe this also broke the dbm database stuff + $key =~ s|\\$|\\\\|; + $value =~ s/\|/\\\|/g; + $value =~ s/\\\\\|/\\\|/g; + $value =~ s|\\\\|\\\\\\\\|g; + print FH "\n\$l2h_cache_key = q/$key/;\n"; + print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; + } + print FH "1;"; + close(FH); +} + +# return cached html, if it exists for text, and if all pictures +# are there, as well +sub l2h_FromCache +{ + my $text = shift; + my $cached = $l2h_cache{$text}; + if ($cached) + { + while ($cached =~ m/SRC="(.*?)"/g) + { + unless (-e "$docu_rdir$1") + { + return undef; + } + } + return $cached; + } + return undef; +} + +# insert generated html into cache, move away images, +# return transformed html +$maximage = 1; +sub l2h_ToCache +{ + my $count = shift; + my $content = shift; + my @images = ($content =~ /SRC="(.*?)"/g); + my ($src, $dest); + + for $src (@images) + { + $dest = $l2h_img{$src}; + unless ($dest) + { + my $ext; + if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext) + { + $ext = $1; + } + else + { + warn "$ERROR: L2h image $src has invalid extension\n"; + next; + } + while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;} + $dest = "${docu_name}_$maximage.$ext"; + system("cp -f $docu_rdir$src $docu_rdir$dest"); + $l2h_img{$src} = $dest; + unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H); + } + $content =~ s/$src/$dest/g; + } + $l2h_cache{$l2h_to_latex[$count]} = $content; + return $content; +} + + +#+++############################################################################ +# # +# Pass 1: read source, handle command, variable, simple substitution # +# # +#---############################################################################ + +@lines = (); # whole document +@toc_lines = (); # table of contents +@stoc_lines = (); # table of contents +$curlevel = 0; # current level in TOC +$node = ''; # current node name +$node_next = ''; # current node next name +$node_prev = ''; # current node prev name +$node_up = ''; # current node up name +$in_table = 0; # am I inside a table +$table_type = ''; # type of table ('', 'f', 'v', 'multi') +@tables = (); # nested table support +$in_bibliography = 0; # am I inside a bibliography +$in_glossary = 0; # am I inside a glossary +$in_top = 0; # am I inside the top node +$has_top = 0; # did I see a top node? +$has_top_command = 0; # did I see @top for automatic pointers? +$in_pre = 0; # am I inside a preformatted section +$in_list = 0; # am I inside a list +$in_html = 0; # am I inside an HTML section +$first_line = 1; # is it the first line +$dont_html = 0; # don't protect HTML on this line +$deferred_ref = ''; # deferred reference for indexes +@html_stack = (); # HTML elements stack +$html_element = ''; # current HTML element +&html_reset; +%macros = (); # macros + +# init l2h +$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H); +$T2H_L2H = &l2h_InitToLatex if ($T2H_L2H); + +# build code for simple substitutions +# the maps used (%simple_map and %things_map) MUST be aware of this +# watch out for regexps, / and escaped characters! +$subst_code = ''; +foreach (keys(%simple_map)) { + ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars + $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n"; +} +foreach (keys(%things_map)) { + $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n"; +} +if ($use_acc) { + # accentuated characters + foreach (keys(%accent_map)) { + if ($_ eq "`") { + $subst_code .= "s/$;3"; + } elsif ($_ eq "'") { + $subst_code .= "s/$;4"; + } else { + $subst_code .= "s/\\\@\\$_"; + } + $subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n"; + } +} +eval("sub simple_substitutions { $subst_code }"); + +&init_input; +INPUT_LINE: while ($_ = &next_line) { + # + # remove \input on the first lines only + # + if ($first_line) { + next if /^\\input/; + $first_line = 0; + } + # non-@ substitutions cf. texinfmt.el + # + # parse texinfo tags + # + $tag = ''; + $end_tag = ''; + if (/^\s*\@end\s+(\w+)\b/) { + $end_tag = $1; + } elsif (/^\s*\@(\w+)\b/) { + $tag = $1; + } + # + # handle @html / @end html + # + if ($in_html) { + if ($end_tag eq 'html') { + $in_html = 0; + } else { + $tag2pro{$in_html} .= $_; + } + next; + } elsif ($tag eq 'html') { + $in_html = $PROTECTTAG . ++$html_num; + push(@lines, $in_html); + next; + } + + # + # try to remove inlined comments + # syntax from tex-mode.el comment-start-skip + # + s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/; + +# Sometimes I use @c right at the end of a line ( to suppress the line feed ) +# s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/; +# s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; +# s/(.*)\@c{.*?}(.*)/$1$2/; +# s/(.*)\@comment{.*?}(.*)/$1$2/; +# s/^(.*)\@c /$1/; +# s/^(.*)\@comment /$1/; + + ############################################################# + # value substitution before macro expansion, so that + # it works in macro arguments + s/\@value{($VARRE)}/$value{$1}/eg; + + ############################################################# + # macro substitution + while (/\@(\w+)/g) + { + if (exists($macros->{$1})) + { + my $before = $`; + my $name = $1; + my $after = $'; + my @args; + my $args; + if ($after =~ /^\s*{(.*?[^\\])}(.*)/) + { + $args = $1; + $after = $2; + } + elsif (@{$macros->{$name}->{Args}} == 1) + { + $args = $after; + $args =~ s/^\s*//; + $args =~ s/\s*$//; + $after = ''; + } + $args =~ s|\\\\|\\|g; + $args =~ s|\\{|{|g; + $args =~ s|\\}|}|g; + if (@{$macros->{$name}->{Args}} > 1) + { + $args =~ s/(^|[^\\]),/$1$;/g ; + $args =~ s|\\,|,|g; + @args = split(/$;\s*/, $args) if (@{$macros->{$name}->{Args}} > 1); + } + else + { + $args =~ s|\\,|,|g; + @args = ($args); + } + my $macrobody = $macros->{$name}->{Body}; + for ($i=0; $i<=$#args; $i++) + { + $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g; + } + $macrobody =~ s|\\\\|\\|g; + $_ = $before . $macrobody . $after; + unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_); + next INPUT_LINE; + } + } # + + + # + # try to skip the line + # + if ($end_tag) { + $in_titlepage = 0 if $end_tag eq 'titlepage'; + next if $to_skip{"end $end_tag"}; + } elsif ($tag) { + $in_titlepage = 1 if $tag eq 'titlepage'; + next if $to_skip{$tag}; + last if $tag eq 'bye'; + } + if ($in_top) { + # parsing the top node + if ($tag eq 'node' || + ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/)) + { + # no more in top + $in_top = 0; + push(@lines, $TOPEND); + } + } + unless ($in_pre) { + s/``/\"/g; + s/''/\"/g; + s/([\w ])---([\w ])/$1--$2/g; + } + # + # analyze the tag + # + if ($tag) { + # skip lines + &skip_until($tag), next if $tag eq 'ignore'; + &skip_until($tag), next if $tag eq 'ifnothtml'; + if ($tag eq 'ifinfo') + { + &skip_until($tag), next unless $T2H_EXPAND eq 'info'; + } + if ($tag eq 'iftex') + { + &skip_until($tag), next unless $T2H_EXPAND eq 'tex'; + } + if ($tag eq 'tex') + { + # add to latex2html file + if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre) + { + # add space to the end -- tex(i2dvi) does this, as well + push(@lines, &l2h_ToLatex(&string_until($tag) . " ")); + } + else + { + &skip_until($tag); + } + next; + } + if ($tag eq 'titlepage') + { + next; + } + # handle special tables + if ($tag =~ /^(|f|v|multi)table$/) { + $table_type = $1; + $tag = 'table'; + } + # special cases + if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { + $in_top = 1; + $has_top = 1; + $has_top_command = 1 if $tag eq 'top'; + @lines = (); # ignore all lines before top (title page garbage) + next; + } elsif ($tag eq 'node') { + if ($in_top) + { + $in_top = 0; + push(@lines, $TOPEND); + } + warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; + # request of "Richard Y. Kim" + s/^\@node\s+//; + $_ = &protect_html($_); # if node contains '&' for instance + ($node, $node_next, $node_prev, $node_up) = split(/,/); + &normalise_node($node); + &normalise_node($node_next); + &normalise_node($node_prev); + &normalise_node($node_up); + $node =~ /\"/ ? + push @lines, &html_debug("\n", __LINE__) : + push @lines, &html_debug("\n", __LINE__); + next; + } elsif ($tag eq 'include') { + if (/^\@include\s+($FILERE)\s*$/o) { + $file = LocateIncludeFile($1); + if ($file && -e $file) { + &open($file); + print "# including $file\n" if $T2H_VERBOSE; + } else { + warn "$ERROR Can't find $1, skipping"; + } + } else { + warn "$ERROR Bad include line: $_"; + } + next; + } elsif ($tag eq 'ifclear') { + if (/^\@ifclear\s+($VARRE)\s*$/o) { + next unless defined($value{$1}); + &skip_until($tag); + } else { + warn "$ERROR Bad ifclear line: $_"; + } + next; + } elsif ($tag eq 'ifset') { + if (/^\@ifset\s+($VARRE)\s*$/o) { + next if defined($value{$1}); + &skip_until($tag); + } else { + warn "$ERROR Bad ifset line: $_"; + } + next; + } elsif ($tag eq 'menu') { + unless ($T2H_SHOW_MENU) { + &skip_until($tag); + next; + } + &html_push_if($tag); + push(@lines, &html_debug('', __LINE__)); + } elsif ($format_map{$tag}) { + $in_pre = 1 if $format_map{$tag} eq 'PRE'; + &html_push_if($format_map{$tag}); + push(@lines, &html_debug('', __LINE__)); + $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; +# push(@lines, &debug("

    \n", __LINE__)) +# if $tag =~ /example/i; + # sunshine@sunshineco.com:
    bla
    looks better than + #
    \nbla
    (at least on NeXTstep browser + push(@lines, &debug("<$format_map{$tag}>" . + ($in_pre ? '' : "\n"), __LINE__)); + next; + } + elsif (exists $complex_format_map->{$tag}) + { + my $start = eval $complex_format_map->{$tag}->[0]; + if ($@) + { + print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@"; + $start = '
    '
    +	  }
    +	  $in_pre = 1 if $start =~ /
    \n", __LINE__));
    +		    &html_push_if('TABLE');
    +		} else {
    +		    push(@lines, &debug("
    \n", __LINE__)); + &html_push_if('DL'); + } + push(@lines, &html_debug('', __LINE__)); + } else { + warn "$ERROR Bad table line: $_"; + } + next; + } + elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') + { + if (/^\@$tag\s+(\w+)\s+(\w+)\s*$/) + { + my $from = $1; + my $to = $2; + my $prefix_from = IndexName2Prefix($from); + my $prefix_to = IndexName2Prefix($to); + + warn("$ERROR unknown from index name $from ind syn*index line: $_"), next + unless $prefix_from; + warn("$ERROR unknown to index name $to ind syn*index line: $_"), next + unless $prefix_to; + + if ($tag eq 'syncodeindex') + { + $index_properties->{$prefix_to}->{'from_code'}->{$prefix_from} = 1; + } + else + { + $index_properties->{$prefix_to}->{'from'}->{$prefix_from} = 1; + } + } + else + { + warn "$ERROR Bad syn*index line: $_"; + } + next; + } + elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') + { + if (/^\@$tag\s+(\w+)\s*$/) + { + my $name = $1; + $index_properties->{$name}->{name} = $name; + $index_properties->{$name}->{code} = 1 if $tag eq 'defcodeindex'; + } + else + { + warn "$ERROR Bad defindex line: $_"; + } + next; + } + elsif (/^\@printindex/) + { + push (@lines, "$_"); + next; + } + elsif ($tag eq 'sp') { + push(@lines, &debug("

    \n", __LINE__)); + next; + } elsif ($tag eq 'center') { + push(@lines, &debug("

    \n", __LINE__)); + s/\@center//; + } elsif ($tag eq 'setref') { + &protect_html; # if setref contains '&' for instance + if (/^\@$tag\s*{($NODERE)}\s*$/) { + $setref = $1; + $setref =~ s/\s+/ /g; # normalize + $setref =~ s/ $//; + $node2sec{$setref} = $name; + $sec2node{$name} = $setref; + $node2href{$setref} = "$docu_doc#$docid"; + } else { + warn "$ERROR Bad setref line: $_"; + } + next; + } elsif ($tag eq 'lowersections') { + local ($sec, $level); + while (($sec, $level) = each %sec2level) { + $sec2level{$sec} = $level + 1; + } + next; + } elsif ($tag eq 'raisesections') { + local ($sec, $level); + while (($sec, $level) = each %sec2level) { + $sec2level{$sec} = $level - 1; + } + next; + } + elsif ($tag eq 'macro' || $tag eq 'rmacro') + { + if (/^\@$tag\s*(\w+)\s*(.*)/) + { + my $name = $1; + my @args; + @args = split(/\s*,\s*/ , $1) + if ($2 =~ /^\s*{(.*)}\s*/); + + $macros->{$name}->{Args} = \@args; + $macros->{$name}->{Body} = ''; + while (($_ = &next_line) && $_ !~ /\@end $tag/) + { + $macros->{$name}->{Body} .= $_; + } + die "ERROR: No closing '\@end $tag' found for macro definition of '$name'\n" + unless (/\@end $tag/); + chomp $macros->{$name}->{Body}; + } + else + { + warn "$ERROR: Bad macro defintion $_" + } + next; + } + elsif ($tag eq 'unmacro') + { + delete $macros->{$1} if (/^\@unmacro\s*(\w+)/); + next; + } + elsif ($tag eq 'documentlanguage') + { + SetDocumentLanguage($1) if (!$T2H_LANG && /documentlanguage\s*(\w+)/); + } + elsif (defined($def_map{$tag})) { + if ($def_map{$tag}) { + s/^\@$tag\s+//; + $tag = $def_map{$tag}; + $_ = "\@$tag $_"; + $tag =~ s/\s.*//; + } + } elsif (defined($user_sub{$tag})) { + s/^\@$tag\s+//; + $sub = $user_sub{$tag}; + print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER; + if (defined(&$sub)) { + chop($_); + &$sub($_); + } else { + warn "$ERROR Bad user sub for $tag: $sub\n"; + } + next; + } + if (defined($def_map{$tag})) { + s/^\@$tag\s+//; + if ($tag =~ /x$/) { + # extra definition line + $tag = $`; + $is_extra = 1; + } else { + $is_extra = 0; + } + while (/\{([^\{\}]*)\}/) { + # this is a {} construct + ($before, $contents, $after) = ($`, $1, $'); + # protect spaces + $contents =~ s/\s+/$;9/g; + # restore $_ protecting {} + $_ = "$before$;7$contents$;8$after"; + } + @args = split(/\s+/, &protect_html($_)); + foreach (@args) { + s/$;9/ /g; # unprotect spaces + s/$;7/\{/g; # ... { + s/$;8/\}/g; # ... } + } + $type = shift(@args); + $type =~ s/^\{(.*)\}$/$1/; + print "# def ($tag): {$type} ", join(', ', @args), "\n" + if $T2H_DEBUG & $DEBUG_DEF; + $type .= ':'; # it's nicer like this + my $name = shift(@args); + $name =~ s/^\{(.*)\}$/$1/; + if ($is_extra) { + $_ = &debug("
    ", __LINE__); + } else { + $_ = &debug("
    \n
    ", __LINE__); + } + if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { + $_ .= "$type $name"; + $_ .= " @args" if @args; + } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' + || $tag eq 'defcv' || $tag eq 'defop') { + $ftype = $name; + $name = shift(@args); + $name =~ s/^\{(.*)\}$/$1/; + $_ .= "$type $ftype $name"; + $_ .= " @args" if @args; + } else { + warn "$ERROR Unknown definition type: $tag\n"; + $_ .= "$type $name"; + $_ .= " @args" if @args; + } + $_ .= &debug("\n
    ", __LINE__); + $name = &unprotect_html($name); + if ($tag eq 'deffn' || $tag eq 'deftypefn') { + EnterIndexEntry('f', $name, $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@findex $name\n"); + } elsif ($tag eq 'defop') { + EnterIndexEntry('f', "$name on $ftype", $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@findex $name on $ftype\n"); + } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { + EnterIndexEntry('v', $name, $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@vindex $name\n"); + } else { + EnterIndexEntry('t', $name, $docu_doc, $section, \@lines); +# unshift(@input_spool, "\@tindex $name\n"); + } + $dont_html = 1; + } + } elsif ($end_tag) { + if ($format_map{$end_tag}) { + $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; + $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; + &html_pop_if('P'); + &html_pop_if('LI'); + &html_pop_if(); + push(@lines, &debug("\n", __LINE__)); + push(@lines, &html_debug('', __LINE__)); + } + elsif (exists $complex_format_map->{$end_tag}) + { + my $end = eval $complex_format_map->{$end_tag}->[1]; + if ($@) + { + print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@"; + $end = '
    ' + } + $in_pre = 0 if $end =~ m|
    |; + push(@lines, html_debug($end, __LINE__)); + } elsif ($end_tag =~ /^(|f|v|multi)table$/) { + unless (@tables) { + warn "$ERROR \@end $end_tag without \@*table\n"; + next; + } + &html_pop_if('P'); + ($table_type, $in_table) = split($;, shift(@tables)); + unless ($1 eq $table_type) { + warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; + next; + } + if ($table_type eq "multi") { + push(@lines, "
    \n"); + &html_pop_if('TR'); + } else { + push(@lines, "\n"); + &html_pop_if('DD'); + } + &html_pop_if(); + if (@tables) { + ($table_type, $in_table) = split($;, $tables[0]); + } else { + $in_table = 0; + } + } elsif (defined($def_map{$end_tag})) { + push(@lines, &debug("\n", __LINE__)); + } elsif ($end_tag eq 'menu') { + &html_pop_if(); + push(@lines, $_); # must keep it for pass 2 + } + next; + } + ############################################################# + # anchor insertion + while (/\@anchor\s*\{(.*?)\}/) + { + $_ = $`.$'; + my $anchor = $1; + $anchor = &normalise_node($anchor); + push @lines, &html_debug("\n"); + $node2href{$anchor} = "$docu_doc#$anchor"; + next INPUT_LINE if $_ =~ /^\s*$/; + } + + ############################################################# + # index entry generation, after value substitutions + if (/^\@(\w+?)index\s+/) + { + EnterIndexEntry($1, $', $docu_doc, $section, \@lines); + next; + } + # + # protect texi and HTML things + &protect_texi; + $_ = &protect_html($_) unless $dont_html; + $dont_html = 0; + # substitution (unsupported things) + s/^\@exdent\s+//g; + s/\@noindent\s+//g; + s/\@refill\s+//g; + # other substitutions + &simple_substitutions; + s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 + # + # analyze the tag again + # + if ($tag) { + if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { + if (/^\@$tag\s+(.+)$/) { + $name = $1; + $name = &normalise_node($name); + $level = $sec2level{$tag}; + # check for index + $first_index_chapter = $name + if ($level == 1 && !$first_index_chapter && + $name =~ /index/i); + if ($in_top && /heading/){ + $T2H_HAS_TOP_HEADING = 1; + $_ = &debug("$name\n", __LINE__); + &html_push_if('body'); + print "# top heading, section $name, level $level\n" + if $T2H_DEBUG & $DEBUG_TOC; + } + else + { + unless (/^\@\w*heading/) + { + unless (/^\@unnumbered/) + { + my $number = &update_sec_num($tag, $level); + $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS; + $sec2number{$name} = $number; + $number2sec{$number} = $name; + } + if (defined($toplevel)) + { + push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND); + } + else + { + # first time we see a "section" + unless ($level == 1) + { + warn "$WARN The first section found is not of level 1: $_"; + } + $toplevel = $level; + } + push(@sections, $name); + next_doc() if ($T2H_SPLIT eq 'section' || + $T2H_SPLIT && $level == $toplevel); + } + $sec_num++; + $docid = "SEC$sec_num"; + $tocid = (/^\@\w*heading/ ? undef : "TOC$sec_num"); + # check biblio and glossary + $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); + $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); + # check node + if ($node) + { + warn "$ERROR Duplicate node found: $node\n" + if ($node2sec{$node}); + } + else + { + $name .= ' ' while ($node2sec{$name}); + $node = $name; + } + $name .= ' ' while ($sec2node{$name}); + $section = $name; + $node2sec{$node} = $name; + $sec2node{$name} = $node; + $node2href{$node} = "$docu_doc#$docid"; + $node2next{$node} = $node_next; + $node2prev{$node} = $node_prev; + $node2up{$node} = $node_up; + print "# node $node, section $name, level $level\n" + if $T2H_DEBUG & $DEBUG_TOC; + + $node = ''; + $node_next = ''; + $node_prev = ''; + $node_next = ''; + if ($tocid) + { + # update TOC + while ($level > $curlevel) { + $curlevel++; + push(@toc_lines, "
      \n"); + } + while ($level < $curlevel) { + $curlevel--; + push(@toc_lines, "
    \n"); + } + $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1); + $_ = &substitute_style($_); + push(@stoc_lines, "$_
    \n") if ($level == 1); + if ($T2H_NUMBER_SECTIONS) + { + push(@toc_lines, $_ . "
    \n") + } + else + { + push(@toc_lines, "
  • " . $_ ."
  • "); + } + } + else + { + push(@lines, &html_debug("\n", + __LINE__)); + } + # update DOC + push(@lines, &html_debug('', __LINE__)); + &html_reset; + $_ = " $name \n\n"; + $_ = &debug($_, __LINE__); + push(@lines, &html_debug('', __LINE__)); + } + # update DOC + foreach $line (split(/\n+/, $_)) { + push(@lines, "$line\n"); + } + next; + } else { + warn "$ERROR Bad section line: $_"; + } + } else { + # track variables + $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o; + delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; + # store things + $value{'_shorttitle'} = Unprotect_texi($1), next if /^\@shorttitle\s+(.*)$/; + $value{'_setfilename'} = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/; + $value{'_settitle'} = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/; + $value{'_author'} .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/; + $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/; + $value{'_title'} .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/; + + # list item + if (/^\s*\@itemx?\s+/) { + $what = $'; + $what =~ s/\s+$//; + if ($in_bibliography && $use_bibliography) { + if ($what =~ /^$BIBRE$/o) { + $id = 'BIB' . ++$bib_num; + $bib2href{$what} = "$docu_doc#$id"; + print "# found bibliography for '$what' id $id\n" + if $T2H_DEBUG & $DEBUG_BIB; + $what = &t2h_anchor($id, '', $what); + } + } elsif ($in_glossary && $T2H_USE_GLOSSARY) { + $id = 'GLOSS' . ++$gloss_num; + $entry = $what; + $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; + $gloss2href{$entry} = "$docu_doc#$id"; + print "# found glossary for '$entry' id $id\n" + if $T2H_DEBUG & $DEBUG_GLOSS; + $what = &t2h_anchor($id, '', $what); + } + elsif ($in_table && ($table_type eq 'f' || $table_type eq 'v')) + { + EnterIndexEntry($table_type, $what, $docu_doc, $section, \@lines); + } + &html_pop_if('P'); + if ($html_element eq 'DL' || $html_element eq 'DD') { + if ($things_map{$in_table} && !$what) { + # special case to allow @table @bullet for instance + push(@lines, &debug("
    $things_map{$in_table}\n", __LINE__)); + } else { + push(@lines, &debug("
    \@$in_table\{$what\}\n", __LINE__)); + } + push(@lines, "
    "); + &html_push('DD') unless $html_element eq 'DD'; + if ($table_type) { # add also an index + unshift(@input_spool, "\@${table_type}index $what\n"); + } + } elsif ($html_element eq 'TABLE') { + push(@lines, &debug("$what\n", __LINE__)); + &html_push('TR'); + } elsif ($html_element eq 'TR') { + push(@lines, &debug("\n", __LINE__)); + push(@lines, &debug("$what\n", __LINE__)); + } else { + push(@lines, &debug("
  • $what\n", __LINE__)); + &html_push('LI') unless $html_element eq 'LI'; + } + push(@lines, &html_debug('', __LINE__)); + if ($deferred_ref) { + push(@lines, &debug("$deferred_ref\n", __LINE__)); + $deferred_ref = ''; + } + next; + } elsif (/^\@tab\s+(.*)$/) { + push(@lines, "$1\n"); + next; + } + } + } + # paragraph separator + if ($_ eq "\n" && ! $in_pre) { + next if $#lines >= 0 && $lines[$#lines] eq "\n"; + if ($html_element eq 'P') { + push (@lines, &debug("

    \n", __LINE__)); + } +# else +# { +# push(@lines, "

    \n"); +# $_ = &debug("

    \n", __LINE__); +# } + elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI') + { + &html_push('P'); + push(@lines, &debug("

    \n", __LINE__)); + } + } + # otherwise + push(@lines, $_) unless $in_titlepage; + push(@lines, &debug("\n", __LINE__)) if ($tag eq 'center'); +} + +# finish TOC +$level = 0; +while ($level < $curlevel) { + $curlevel--; + push(@toc_lines, "\n"); +} + +print "# end of pass 1\n" if $T2H_VERBOSE; + +SetDocumentLanguage('en') unless ($T2H_LANG); +#+++############################################################################ +# # +# Stuff related to Index generation # +# # +#---############################################################################ + +sub EnterIndexEntry +{ + my $prefix = shift; + my $key = shift; + my $docu_doc = shift; + my $section = shift; + my $lines = shift; + local $_; + + warn "$ERROR Undefined index command: $_", next + unless (exists ($index_properties->{$prefix})); + $key =~ s/\s+$//; + $_ = $key; + &protect_texi; + $key = $_; + $_ = &protect_html($_); + my $html_key = substitute_style($_); + my $id; + $key = remove_style($key); + $key = remove_things($key); + $_ = $key; + &unprotect_texi; + $key = $_; + while (exists $index->{$prefix}->{$key}) {$key .= ' '}; + if ($lines->[$#lines] =~ /^$/) + { + $id = $1; + } + else + { + $id = 'IDX' . ++$idx_num; + push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); + } + $index->{$prefix}->{$key}->{html_key} = $html_key; + $index->{$prefix}->{$key}->{section} = $section; + $index->{$prefix}->{$key}->{href} = "$docu_doc#$id"; + print "# found ${prefix}index for '$key' with id $id\n" + if $T2H_DEBUG & $DEBUG_INDEX; +} + +sub IndexName2Prefix +{ + my $name = shift; + my $prefix; + + for $prefix (keys %$index_properties) + { + return $prefix if ($index_properties->{$prefix}->{name} eq $name); + } + return undef; +} + +sub GetIndexEntries +{ + my $normal = shift; + my $code = shift; + my ($entries, $prefix, $key) = ({}); + + for $prefix (keys %$normal) + { + for $key (keys %{$index->{$prefix}}) + { + $entries->{$key} = {%{$index->{$prefix}->{$key}}}; + } + } + + if (defined($code)) + { + for $prefix (keys %$code) + { + unless (exists $normal->{$keys}) + { + for $key (keys %{$index->{$prefix}}) + { + $entries->{$key} = {%{$index->{$prefix}->{$key}}}; + $entries->{$key}->{html_key} = "$entries->{$key}->{html_key}"; + } + } + } + } + return $entries; +} + +sub byAlpha +{ + if ($a =~ /^[A-Za-z]/) + { + if ($b =~ /^[A-Za-z]/) + { + return lc($a) cmp lc($b); + } + else + { + return 1; + } + } + elsif ($b =~ /^[A-Za-z]/) + { + return -1; + } + else + { + return lc($a) cmp lc($b); + } +} + +sub GetIndexPages +{ + my $entries = shift; + my (@Letters, $key); + my ($EntriesByLetter, $Pages, $page) = ({}, [], {}); + my @keys = sort byAlpha keys %$entries; + + for $key (@keys) + { + push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key}; + } + @Letters = sort byAlpha keys %$EntriesByLetter; + + $T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT); + + unless ($T2H_SPLIT_INDEX) + { + $page->{First} = $Letters[0]; + $page->{Last} = $Letters[$#Letters]; + $page->{Letters} = \@Letters; + $page->{EntriesByLetter} = $EntriesByLetter; + push @$Pages, $page; + return $Pages; + } + + if ($T2H_SPLIT_INDEX =~ /^\d+$/) + { + my $i = 0; + my ($prev_letter, $letter); + $page->{First} = $Letters[0]; + for $letter (@Letters) + { + if ($i > $T2H_SPLIT_INDEX) + { + $page->{Last} = $prev_letter; + push @$Pages, {%$page}; + $page->{Letters} = []; + $page->{EntriesByLetter} = {}; + $page->{First} = $letter; + $i=0; + } + push @{$page->{Letters}}, $letter; + $page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}]; + $i += scalar(@{$EntriesByLetter->{$letter}}); + $prev_letter = $letter; + } + $page->{Last} = $Letters[$#Letters]; + push @$Pages, {%$page}; + } + return $Pages; +} + +sub GetIndexSummary +{ + my $first_page = shift; + my $Pages = shift; + my $name = shift; + my ($page, $letter, $summary, $i, $l1, $l2, $l); + + $i = 0; + $summary = '
    Jump to:   '; + + for $page ($first_page, @$Pages) + { + for $letter (@{$page->{Letters}}) + { + $l = t2h_anchor('', "$page->{href}#${name}_$letter", "$letter", + 0, 'style="text-decoration:none"') . "\n   \n"; + + if ($letter =~ /^[A-Za-z]/) + { + $l2 .= $l; + } + else + { + $l1 .= $l; + } + } + } + $summary .= $l1 . "
    \n" if ($l1); + $summary .= $l2 . '

    '; + return $summary; +} + +sub PrintIndexPage +{ + my $lines = shift; + my $summary = shift; + my $page = shift; + my $name = shift; + + push @$lines, $summary; + + push @$lines , <

    + + + +EOT + + for $letter (@{$page->{Letters}}) + { + push @$lines, "\n"; + for $entry (@{$page->{EntriesByLetter}->{$letter}}) + { + push @$lines, + "\n"; + } + push @$lines, "\n"; + } + push @$lines, "
    Index Entry Section

    $letter
    " . + t2h_anchor('', $entry->{href}, $entry->{html_key}) . + "" . + t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) . + "

    "; + push @$lines, $summary; +} + +sub PrintIndex +{ + my $lines = shift; + my $name = shift; + my $section = shift; + $section = 'Top' unless $section; + my $prefix = IndexName2Prefix($name); + + warn ("$ERROR printindex: bad index name: $name"), return + unless $prefix; + + if ($index_properties->{$prefix}->{code}) + { + $index_properties->{$prefix}->{from_code}->{$prefix} = 1; + } + else + { + $index_properties->{$prefix}->{from}->{$prefix}= 1; + } + + my $Entries = GetIndexEntries($index_properties->{$prefix}->{from}, + $index_properties->{$prefix}->{from_code}); + return unless %$Entries; + + if ($T2H_IDX_SUMMARY) + { + my $key; + open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx") + || die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n"; + print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE; + + for $key (sort keys %$Entries) + { + print FHIDX "$key\t$Entries->{$key}->{href}\n"; + } + } + + my $Pages = GetIndexPages($Entries); + my $page; + my $first_page = shift @$Pages; + my $sec_name = $section; + # remove section number + $sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./; + + ($first_page->{href} = sec_href($section)) =~ s/\#.*$//; + # Update tree structure of document + if (@$Pages) + { + my $sec; + my @after; + + while (@sections && $sections[$#sections] ne $section) + { + unshift @after, pop @sections; + } + + for $page (@$Pages) + { + my $node = ($page->{First} ne $page->{Last} ? + "$sec_name: $page->{First} -- $page->{Last}" : + "$sec_name: $page->{First}"); + push @sections, $node; + $node2sec{$node} = $node; + $sec2node{$node} = $node; + $node2up{$node} = $section; + $page->{href} = next_doc(); + $page->{name} = $node; + $node2href{$node} = $page->{href}; + if ($prev_node) + { + $node2next{$prev_node} = $node; + $node2prev{$node} = $prev_node; + } + $prev_node = $node; + } + push @sections, @after; + } + + my $summary = GetIndexSummary($first_page, $Pages, $name); + PrintIndexPage($lines, $summary, $first_page, $name); + for $page (@$Pages) + { + push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); + push @$lines, "

    $page->{name}

    \n"; + PrintIndexPage($lines, $summary, $page, $name); + } +} + + +#+++############################################################################ +# # +# Pass 2/3: handle style, menu, index, cross-reference # +# # +#---############################################################################ + +@lines2 = (); # whole document (2nd pass) +@lines3 = (); # whole document (3rd pass) +$in_menu = 0; # am I inside a menu + +while (@lines) { + $_ = shift(@lines); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@lines2, $_); + next; + } + # + # menu + # + if (/^\@menu\b/) + { + $in_menu = 1; + $in_menu_listing = 1; + push(@lines2, &debug("
    \n", __LINE__)); + next; + } + if (/^\@end\s+menu\b/) + { + if ($in_menu_listing) + { + push(@lines2, &debug("
    \n", __LINE__)); + } + else + { + push(@lines2, &debug("\n", __LINE__)); + } + $in_menu = 0; + $in_menu_listing = 0; + next; + } + if ($in_menu) + { + my ($node, $name, $descr); + if (/^\*\s+($NODERE)::/o) + { + $node = $1; + $descr = $'; + } + elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) + { + $name = $1; + $node = $2; + $descr = $'; + } + elsif (/^\*/) + { + warn "$ERROR Bad menu line: $_"; + } + else + { + if ($in_menu_listing) + { + $in_menu_listing = 0; + push(@lines2, &debug("\n", __LINE__)); + } + # should be like verbatim -- preseve spaces, etc + s/ /\ /g; + $_ .= "
    \n"; + push(@lines2, $_); + } + if ($node) + { + if (! $in_menu_listing) + { + $in_menu_listing = 1; + push(@lines2, &debug("\n", __LINE__)); + } + # look for continuation + while ($lines[0] =~ /^\s+\w+/) + { + $descr .= shift(@lines); + } + &menu_entry($node, $name, $descr); + } + next; + } + # + # printindex + # + PrintIndex(\@lines2, $2, $1), next + if (/^\@printindex\s+(\w+)/); + # + # simple style substitutions + # + $_ = &substitute_style($_); + # + # xref + # + while (/\@(x|px|info|)ref{([^{}]+)(}?)/) { + # note: Texinfo may accept other characters + ($type, $nodes, $full) = ($1, $2, $3); + ($before, $after) = ($`, $'); + if (! $full && $after) { + warn "$ERROR Bad xref (no ending } on line): $_"; + $_ = "$before$;0${type}ref\{$nodes$after"; + next; # while xref + } + if ($type eq 'x') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; + } elsif ($type eq 'px') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; + } elsif ($type eq 'info') { + $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info"; + } else { + $type = ''; + } + unless ($full) { + $next = shift(@lines); + $next = &substitute_style($next); + chop($nodes); # remove final newline + if ($next =~ /\}/) { # split on 2 lines + $nodes .= " $`"; + $after = $'; + } else { + $nodes .= " $next"; + $next = shift(@lines); + $next = &substitute_style($next); + chop($nodes); + if ($next =~ /\}/) { # split on 3 lines + $nodes .= " $`"; + $after = $'; + } else { + warn "$ERROR Bad xref (no ending }): $_"; + $_ = "$before$;0xref\{$nodes$after"; + unshift(@lines, $next); + next; # while xref + } + } + } + $nodes =~ s/\s+/ /g; # remove useless spaces + @args = split(/\s*,\s*/, $nodes); + $node = $args[0]; # the node is always the first arg + $node = &normalise_node($node); + $sec = $args[2] || $args[1] || $node2sec{$node}; + $href = $node2href{$node}; + if (@args == 5) { # reference to another manual + $sec = $args[2] || $node; + $man = $args[4] || $args[3]; + $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after"; + } elsif ($type =~ /Info/) { # inforef + warn "$ERROR Wrong number of arguments: $_" unless @args == 3; + ($nn, $_, $in) = @args; + $_ = "${before}${type} file `$in', node `$nn'$after"; + } elsif ($sec && $href && ! $T2H_SHORT_REF) { + $_ = "${before}${type}"; + $_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type}; + $_ .= &t2h_anchor('', $href, $sec) . $after; + } + elsif ($href) + { + $_ = "${before}${type} " . + &t2h_anchor('', $href, $args[2] || $args[1] || $node) . + $after; + } + else { + warn "$ERROR Undefined node ($node): $_"; + $_ = "$before$;0xref{$nodes}$after"; + } + } + + # replace images + s[\@image\s*{(.+?)}] + { + my @args = split (/\s*,\s*/, $1); + my $base = $args[0]; + my $image = + LocateIncludeFile("$base.png") || + LocateIncludeFile("$base.jpg") || + LocateIncludeFile("$base.gif"); + warn "$ERROR no image file for $base: $_" unless ($image && -e $image); + "\"$base\""; + ($T2H_CENTER_IMAGE ? + "
    \"$base\"
    " : + "\"$base\""); + }eg; + + # + # try to guess bibliography references or glossary terms + # + unless (/^/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + if ($T2H_USE_GLOSSARY) { + $done = ''; + while (/\b\w+\b/) { + ($pre, $what, $post) = ($`, $&, $'); + $entry = $what; + $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; + $href = $gloss2href{$entry}; + if (defined($href) && $post !~ /^[^<]*<\/A>/) { + $done .= $pre . &t2h_anchor('', $href, $what); + } else { + $done .= "$pre$what"; + } + $_ = $post; + } + $_ = $done . $_; + } + } + # otherwise + push(@lines2, $_); +} +print "# end of pass 2\n" if $T2H_VERBOSE; + +# +# split style substitutions +# +while (@lines2) { + $_ = shift(@lines2); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@lines3, $_); + next; + } + # + # split style substitutions + # + $old = ''; + while ($old ne $_) { + $old = $_; + if (/\@(\w+)\{/) { + ($before, $style, $after) = ($`, $1, $'); + if (defined($style_map{$style})) { + $_ = $after; + $text = ''; + $after = ''; + $failed = 1; + while (@lines2) { + if (/\}/) { + $text .= $`; + $after = $'; + $failed = 0; + last; + } else { + $text .= $_; + $_ = shift(@lines2); + } + } + if ($failed) { + die "* Bad syntax (\@$style) after: $before\n"; + } else { + $text = &apply_style($style, $text); + $_ = "$before$text$after"; + } + } + } + } + # otherwise + push(@lines3, $_); +} +print "# end of pass 3\n" if $T2H_VERBOSE; + +#+++############################################################################ +# # +# Pass 4: foot notes, final cleanup # +# # +#---############################################################################ + +@foot_lines = (); # footnotes +@doc_lines = (); # final document +$end_of_para = 0; # true if last line is

    + +while (@lines3) { + $_ = shift(@lines3); + # + # special case (protected sections) + # + if (/^$PROTECTTAG/o) { + push(@doc_lines, $_); + $end_of_para = 0; + next; + } + # + # footnotes + # + while (/\@footnote([^\{\s]+)\{/) { + ($before, $d, $after) = ($`, $1, $'); + $_ = $after; + $text = ''; + $after = ''; + $failed = 1; + while (@lines3) { + if (/\}/) { + $text .= $`; + $after = $'; + $failed = 0; + last; + } else { + $text .= $_; + $_ = shift(@lines3); + } + } + if ($failed) { + die "* Bad syntax (\@footnote) after: $before\n"; + } else { + $foot_num++; + $docid = "DOCF$foot_num"; + $footid = "FOOT$foot_num"; + $foot = "($foot_num)"; + push(@foot_lines, "

    " . &t2h_anchor($footid, "$d#$docid", $foot) . "

    \n"); + $text = "

    $text" unless $text =~ /^\s*

    /; + push(@foot_lines, "$text\n"); + $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after; + } + } + # + # remove unnecessary

    + # + if (/^\s*

    \s*$/) { + next if $end_of_para++; + } else { + $end_of_para = 0; + } + # otherwise + push(@doc_lines, $_); +} + +print "# end of pass 4\n" if $T2H_VERBOSE; + +#+++############################################################################ +# # +# Pass 5: print things # +# # +#---############################################################################ + +$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H); +$T2H_L2H = &l2h_ToHtml if ($T2H_L2H); +$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H); + +# fix node2up, node2prev, node2next, if desired +if ($has_top_command) +{ + for $section (keys %sec2number) + { + $node = $sec2node{$section}; + $node2up{$node} = Sec2UpNode($section) unless $node2up{$node}; + $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node}; + $node2next{$node} = Sec2NextNode($section) unless $node2next{$node}; + } +} + +# prepare %T2H_THISDOC +$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document"; +$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle}; +$T2H_THISDOC{author} = $value{'_author'}; +$T2H_THISDOC{subtitle} = $value{'_subtitle'}; +$T2H_THISDOC{shorttitle} = $value{'_shorttitle'}; +for $key (keys %T2H_THISDOC) +{ + $_ = &substitute_style($T2H_THISDOC{$key}); + &unprotect_texi; + s/\s*$//; + $T2H_THISDOC{$key} = $_; +} + +# if no sections, then simply print document as is +unless (@sections) +{ + print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE; + open(FILE, "> $docu_top_file") + || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; + + &$T2H_print_page_head(\*FILE); + $T2H_THIS_SECTION = \@doc_lines; + t2h_print_lines(\*FILE); + &$T2H_print_foot_navigation(\*FILE); + &$T2H_print_page_foot(\*FILE); + close(FILE); + goto Finish; +} + +# initialize $T2H_HREF, $T2H_NAME +%T2H_HREF = + ( + 'First' , sec_href($sections[0]), + 'Last', sec_href($sections[$#sections]), + 'About', $docu_about. '#SEC_About', + ); + +# prepare TOC, OVERVIEW, TOP +$T2H_TOC = \@toc_lines; +$T2H_OVERVIEW = \@stoc_lines; +if ($has_top) +{ + while (1) + { + $_ = shift @doc_lines; + last if /$TOPEND/; + push @$T2H_TOP, $_; + } + $T2H_HREF{'Top'} = $docu_top . '#SEC_Top'; +} +else +{ + $T2H_HREF{'Top'} = $T2H_HREF{First}; +} + +$node2href{Top} = $T2H_HREF{Top}; +$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines; +$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines; + +# settle on index +if ($T2H_INDEX_CHAPTER) +{ + $T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)}; + warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n" + unless $T2H_HREF{Index}; +} +if (! $T2H_HREF{Index} && $first_index_chapter) +{ + $T2H_INDEX_CHAPTER = $first_index_chapter; + $T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER}; +} + +print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n" + if ($T2H_VERBOSE && $T2H_HREF{Index}); + +%T2H_NAME = + ( + 'First', clean_name($sec2node{$sections[0]}), + 'Last', clean_name($sec2node{$sections[$#sections]}), + 'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'}, + 'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'}, + 'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'}, + 'Index' , clean_name($T2H_INDEX_CHAPTER), + 'Top', clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}), + ); + +############################################################################# +# print frame and frame toc file +# +if ( $T2H_FRAMES ) +{ + open(FILE, "> $docu_frame_file") + || die "$ERROR: Can't open $docu_frame_file for writing: $!\n"; + print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE; + &$T2H_print_frame(\*FILE); + close(FILE); + + open(FILE, "> $docu_toc_frame_file") + || die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n"; + print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE; + &$T2H_print_toc_frame(\*FILE); + close(FILE); +} + + +############################################################################# +# print Top +# +open(FILE, "> $docu_top_file") + || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; +&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT); + +if ($has_top) +{ + print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE; + $T2H_THIS_SECTION = $T2H_TOP; + $T2H_HREF{This} = $T2H_HREF{Top}; + $T2H_NAME{This} = $T2H_NAME{Top}; + &$T2H_print_Top(\*FILE); +} + +close(FILE) if $T2H_SPLIT; + +############################################################################# +# Print sections +# +$T2H_NODE{Forward} = $sec2node{$sections[0]}; +$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]}); +$T2H_HREF{Forward} = sec_href($sections[0]); +$T2H_NODE{This} = 'Top'; +$T2H_NAME{This} = $T2H_NAME{Top}; +$T2H_HREF{This} = $T2H_HREF{Top}; +if ($T2H_SPLIT) +{ + print "# writing " . scalar(@sections) . + " sections in $docu_rdir$docu_name"."_[1..$doc_num]" + if $T2H_VERBOSE; + $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); + undef $FH; + $doc_num = 0; +} +else +{ + print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." + if $T2H_VERBOSE; + $FH = \*FILE; + $previous = ''; +} + +$counter = 0; +# loop through sections +while ($section = shift(@sections)) +{ + if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND)) + { + if ($FH) + { + #close previous page + &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; + &$T2H_print_page_foot($FH); + close($FH); + undef $FH; + } + } + $T2H_NAME{Back} = $T2H_NAME{This}; + $T2H_HREF{Back} = $T2H_HREF{This}; + $T2H_NODE{Back} = $T2H_NODE{This}; + $T2H_NAME{This} = $T2H_NAME{Forward}; + $T2H_HREF{This} = $T2H_HREF{Forward}; + $T2H_NODE{This} = $T2H_NODE{Forward}; + if ($sections[0]) + { + $T2H_NODE{Forward} = $sec2node{$sections[0]}; + $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward}); + $T2H_HREF{Forward} = sec_href($sections[0]); + } + else + { + undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward}; + } + + $node = $node2up{$T2H_NODE{This}}; + $T2H_HREF{Up} = $node2href{$node}; + if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up}) + { + $T2H_NAME{Up} = $T2H_NAME{Top}; + $T2H_HREF{Up} = $T2H_HREF{Top}; + $T2H_NODE{Up} = 'Up'; + } + else + { + $T2H_NAME{Up} = &clean_name($node); + $T2H_NODE{Up} = $node; + } + + $node = $T2H_NODE{This}; + $node = $node2prev{$node}; + $T2H_NAME{Prev} = &clean_name($node); + $T2H_HREF{Prev} = $node2href{$node}; + $T2H_NODE{Prev} = $node; + + $node = $T2H_NODE{This}; + if ($node2up{$node} && $node2up{$node} ne 'Top'&& + ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node})) + { + $node = $node2up{$node}; + while ($node && $node ne $node2up{$node} && ! $node2prev{$node}) + { + $node = $node2up{$node}; + } + $node = $node2prev{$node} + unless $node2up{$node} eq 'Top' || ! $node2up{$node}; + } + else + { + $node = $node2prev{$node}; + } + $T2H_NAME{FastBack} = &clean_name($node); + $T2H_HREF{FastBack} = $node2href{$node}; + $T2H_NODE{FastBack} = $node; + + $node = $T2H_NODE{This}; + $node = $node2next{$node}; + $T2H_NAME{Next} = &clean_name($node); + $T2H_HREF{Next} = $node2href{$node}; + $T2H_NODE{Next} = $node; + + $node = $T2H_NODE{This}; + if ($node2up{$node} && $node2up{$node} ne 'Top'&& + ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node})) + { + $node = $node2up{$node}; + while ($node && $node ne $node2up{$node} && ! $node2next{$node}) + { + $node = $node2up{$node}; + } + } + $node = $node2next{$node}; + $T2H_NAME{FastForward} = &clean_name($node); + $T2H_HREF{FastForward} = $node2href{$node}; + $T2H_NODE{FastForward} = $node; + + if (! defined($FH)) + { + my $file = $T2H_HREF{This}; + $file =~ s/\#.*$//; + open(FILE, "> $docu_rdir$file") || + die "$ERROR: Can't open $docu_rdir$file for writing: $!\n"; + $FH = \*FILE; + &$T2H_print_page_head($FH); + t2h_print_label($FH); + &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter'; + } + else + { + t2h_print_label($FH); + } + + $T2H_THIS_SECTION = []; + while (@doc_lines) { + $_ = shift(@doc_lines); + last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND); + push(@$T2H_THIS_SECTION, $_); + } + $previous = $_; + &$T2H_print_section($FH); + + if ($T2H_VERBOSE) + { + $counter++; + print "." if $counter =~ /00$/; + } +} +if ($T2H_SPLIT) +{ + &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; + &$T2H_print_page_foot($FH); + close($FH); +} +print "\n" if $T2H_VERBOSE; + +############################################################################# +# Print ToC, Overview, Footnotes +# +undef $T2H_HREF{Prev}; +undef $T2H_HREF{Next}; +undef $T2H_HREF{Back}; +undef $T2H_HREF{Forward}; +undef $T2H_HREF{Up}; + +if (@foot_lines) +{ + print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n" + if $T2H_SPLIT; + $T2H_HREF{This} = $docu_foot; + $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'}; + $T2H_THIS_SECTION = \@foot_lines; + &$T2H_print_Footnotes(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if (@toc_lines) +{ + print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n" + if $T2H_SPLIT; + $T2H_HREF{This} = $T2H_HREF{Contents}; + $T2H_NAME{This} = $T2H_NAME{Contents}; + $T2H_THIS_SECTION = \@toc_lines; + &$T2H_print_Toc(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if (@stoc_lines) +{ + print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n" + if $T2H_SPLIT; + + $T2H_HREF{This} = $T2H_HREF{Overview}; + $T2H_NAME{This} = $T2H_NAME{Overview}; + $T2H_THIS_SECTION = \@stoc_lines; + unshift @$T2H_THIS_SECTION, "

    \n"; + push @$T2H_THIS_SECTION, "\n
    \n"; + &$T2H_print_Overview(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +if ($about_body = &$T2H_about_body()) +{ + print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE; + open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n" + if $T2H_SPLIT; + + $T2H_HREF{This} = $T2H_HREF{About}; + $T2H_NAME{This} = $T2H_NAME{About}; + $T2H_THIS_SECTION = [$about_body]; + &$T2H_print_About(\*FILE); + close(FILE) if $T2H_SPLIT; +} + +unless ($T2H_SPLIT) +{ + &$T2H_print_page_foot(\*FILE); + close (FILE); +} + +Finish: +&l2h_FinishFromHtml if ($T2H_L2H); +&l2h_Finish if($T2H_L2H); +print "# that's all folks\n" if $T2H_VERBOSE; + +exit(0); + +#+++############################################################################ +# # +# Low level functions # +# # +#---############################################################################ + +sub LocateIncludeFile +{ + my $file = shift; + my $dir; + + return $file if (-e $file && -r $file); + foreach $dir (@T2H_INCLUDE_DIRS) + { + return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); + } + return undef; +} + +sub clean_name +{ + local ($_); + $_ = &remove_style($_[0]); + &unprotect_texi; + return $_; +} + +sub update_sec_num { + local($name, $level) = @_; + my $ret; + + $level--; # here we start at 0 + if ($name =~ /^appendix/ || defined(@appendix_sec_num)) { + # appendix style + if (defined(@appendix_sec_num)) { + &incr_sec_num($level, @appendix_sec_num); + } else { + @appendix_sec_num = ('A', 0, 0, 0); + } + $ret = join('.', @appendix_sec_num[0..$level]); + } else { + # normal style + if (defined(@normal_sec_num)) + { + &incr_sec_num($level, @normal_sec_num); + } + else + { + @normal_sec_num = (1, 0, 0, 0); + } + $ret = join('.', @normal_sec_num[0..$level]); + } + + $ret .= "." if $level == 0; + return $ret; +} + +sub incr_sec_num { + local($level, $l); + $level = shift(@_); + $_[$level]++; + foreach $l ($level+1 .. 3) { + $_[$l] = 0; + } +} + +sub Sec2UpNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + + return '' unless $num; + return 'Top' unless $num =~ /\.\d+/; + $num =~ s/\.[^\.]*$//; + $num = $num . '.' unless $num =~ /\./; + return $sec2node{$number2sec{$num}}; +} + +sub Sec2PrevNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + my ($i, $post); + + if ($num =~ /(\w+)(\.$|$)/) + { + $num = $`; + $i = $1; + $post = $2; + if ($i eq 'A') + { + $i = $normal_sec_num[0]; + } + elsif ($i ne '1') + { + # unfortunately, -- operator is not magical + $i = chr(ord($i) + 1); + } + else + { + return ''; + } + return $sec2node{$number2sec{$num . $i . $post}} + } + return ''; +} + +sub Sec2NextNode +{ + my $sec = shift; + my $num = $sec2number{$sec}; + my $i; + + if ($num =~ /(\w+)(\.$|$)/) + { + $num = $`; + $i = $1; + $post = $2; + if ($post eq '.' && $i eq $normal_sec_num[0]) + { + $i = 'A'; + } + else + { + $i++; + } + return $sec2node{$number2sec{$num . $i . $post}} + } + return ''; +} + +sub check { + local($_, %seen, %context, $before, $match, $after); + + while (<>) { + if (/\@(\*|\.|\:|\@|\{|\})/) { + $seen{$&}++; + $context{$&} .= "> $_" if $T2H_VERBOSE; + $_ = "$`XX$'"; + redo; + } + if (/\@(\w+)/) { + ($before, $match, $after) = ($`, $&, $'); + if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address + $seen{'e-mail address'}++; + $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; + } else { + $seen{$match}++; + $context{$match} .= "> $_" if $T2H_VERBOSE; + } + $match =~ s/^\@/X/; + $_ = "$before$match$after"; + redo; + } + } + + foreach (sort(keys(%seen))) { + if ($T2H_VERBOSE) { + print "$_\n"; + print $context{$_}; + } else { + print "$_ ($seen{$_})\n"; + } + } +} + +sub open { + local($name) = @_; + + ++$fh_name; + if (open($fh_name, $name)) { + unshift(@fhs, $fh_name); + } else { + warn "$ERROR Can't read file $name: $!\n"; + } +} + +sub init_input { + @fhs = (); # hold the file handles to read + @input_spool = (); # spooled lines to read + $fh_name = 'FH000'; + &open($docu); +} + +sub next_line { + local($fh, $line); + + if (@input_spool) { + $line = shift(@input_spool); + return($line); + } + while (@fhs) { + $fh = $fhs[0]; + $line = <$fh>; + return($line) if $line; + close($fh); + shift(@fhs); + } + return(undef); +} + +# used in pass 1, use &next_line +sub skip_until { + local($tag) = @_; + local($_); + + while ($_ = &next_line) { + return if /^\@end\s+$tag\s*$/; + } + die "* Failed to find '$tag' after: " . $lines[$#lines]; +} + +# used in pass 1 for l2h use &next_line +sub string_until { + local($tag) = @_; + local($_, $string); + + while ($_ = &next_line) { + return $string if /^\@end\s+$tag\s*$/; +# $_ =~ s/hbox/mbox/g; + $string = $string.$_; + } + die "* Failed to find '$tag' after: " . $lines[$#lines]; +} + +# +# HTML stacking to have a better HTML output +# + +sub html_reset { + @html_stack = ('html'); + $html_element = 'body'; +} + +sub html_push { + local($what) = @_; + push(@html_stack, $html_element); + $html_element = $what; +} + +sub html_push_if { + local($what) = @_; + push(@html_stack, $html_element) + if ($html_element && $html_element ne 'P'); + $html_element = $what; +} + +sub html_pop { + $html_element = pop(@html_stack); +} + +sub html_pop_if { + local($elt); + + if (@_) { + foreach $elt (@_) { + if ($elt eq $html_element) { + $html_element = pop(@html_stack) if @html_stack; + last; + } + } + } else { + $html_element = pop(@html_stack) if @html_stack; + } +} + +sub html_debug { + local($what, $line) = @_; + if ($T2H_DEBUG & $DEBUG_HTML) + { + $what = "\n" unless $what; + return("$what") + } + return($what); +} + +# to debug the output... +sub debug { + local($what, $line) = @_; + return("$what") + if $T2H_DEBUG & $DEBUG_HTML; + return($what); +} + +sub SimpleTexi2Html +{ + local $_ = $_[0]; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +sub normalise_node { + local $_ = $_[0]; + s/\s+/ /g; + s/ $//; + s/^ //; + &protect_texi; + &protect_html; + $_ = substitute_style($_); + $_[0] = $_; +} + +sub menu_entry +{ + my ($node, $name, $descr) = @_; + my ($href, $entry); + + &normalise_node($node); + $href = $node2href{$node}; + if ($href) + { + $descr =~ s/^\s+//; + $descr =~ s/\s*$//; + $descr = SimpleTexi2Html($descr); + if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node}) + { + $entry = $node2sec{$node}; + $name = ''; + } + else + { + &normalise_node($name); + $entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY) + ? "$name : $node" : $node); + } + + if ($T2H_AVOID_MENU_REDUNDANCY && $descr) + { + my $clean_entry = $entry; + $clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /); + $clean_entry =~ s/[^\w]//g; + my $clean_descr = $descr; + $clean_descr =~ s/[^\w]//g; + $descr = '' if ($clean_entry eq $clean_descr) + } + push(@lines2,&debug('
    \n", __LINE__)); + } + elsif ($node =~ /^\(.*\)\w+/) + { + push(@lines2,&debug('\n", __LINE__)) + } + else + { + warn "$ERROR Undefined node of menu_entry ($node): $_"; + } +} + +sub do_ctrl { "^$_[0]" } + +sub do_email { + local($addr, $text) = split(/,\s*/, $_[0]); + + $text = $addr unless $text; + &t2h_anchor('', "mailto:$addr", $text); +} + +sub do_sc +{ + # l2h does this much better + return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H); + return "\U$_[0]\E"; +} + +sub do_math +{ + return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); + return "".$text.""; +} + +sub do_uref { + local($url, $text, $only_text) = split(/,\s*/, $_[0]); + + $text = $only_text if $only_text; + $text = $url unless $text; + &t2h_anchor('', $url, $text); +} + +sub do_url { &t2h_anchor('', $_[0], $_[0]) } + +sub do_acronym +{ + return '' . $_[0] . ''; +} + +sub do_accent +{ + return "&$_[0]acute;" if $_[1] eq 'H'; + return "$_[0]." if $_[1] eq 'dotaccent'; + return "$_[0]*" if $_[1] eq 'ringaccent'; + return "$_[0]".'[' if $_[1] eq 'tieaccent'; + return "$_[0]".'(' if $_[1] eq 'u'; + return "$_[0]_" if $_[1] eq 'ubaraccent'; + return ".$_[0]" if $_[1] eq 'udotaccent'; + return "$_[0]<" if $_[1] eq 'v'; + return "&$_[0]cedil;" if $_[1] eq ','; + return "$_[0]" if $_[1] eq 'dotless'; + return undef; +} + +sub apply_style { + local($texi_style, $text) = @_; + local($style); + + $style = $style_map{$texi_style}; + if (defined($style)) { # known style + if ($style =~ /^\"/) { # add quotes + $style = $'; + $text = "\`$text\'"; + } + if ($style =~ /^\&/) { # custom + $style = $'; + $text = &$style($text, $texi_style); + } elsif ($style) { # good style + $text = "<$style>$text"; + } else { # no style + } + } else { # unknown style + $text = undef; + } + return($text); +} + +# remove Texinfo styles +sub remove_style { + local($_) = @_; + 1 while(s/\@\w+{([^\{\}]+)}/$1/g); + return($_); +} + +sub remove_things +{ + local ($_) = @_; + s|\@(\w+)\{\}|$1|g; + return $_; +} + +sub substitute_style { + local($_) = @_; + local($changed, $done, $style, $text); + + &simple_substitutions; + $changed = 1; + while ($changed) { + $changed = 0; + $done = ''; + while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) { + $text = &apply_style($1, $2); + if ($text) { + $_ = "$`$text$'"; + $changed = 1; + } else { + $done .= "$`\@$1"; + $_ = "{$2}$'"; + } + } + $_ = $done . $_; + } + return($_); +} + +sub t2h_anchor { + local($name, $href, $text, $newline, $extra_attribs) = @_; + local($result); + + $result = " + $what =~ s/\&/\&\#38;/g; + $what =~ s/\/\&\#62;/g; + # restore anything in quotes + # this fixes my problem where I had: + # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < in my ALT text ?? + # maybe byte stuffing or some other technique should be used. + $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g; + $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g; + $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g; + # but recognize some HTML things + $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # + $what =~ s/\&\#60;A ([^\&]+)\&\#62;//g; # + $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;//g; # + return($what); +} + +sub unprotect_texi { + s/$;0/\@/go; + s/$;1/\{/go; + s/$;2/\}/go; + s/$;3/\`/go; + s/$;4/\'/go; +} + +sub Unprotect_texi +{ + local $_ = shift; + &unprotect_texi; + return($_); +} + +sub unprotect_html { + local($what) = @_; + $what =~ s/\&\#38;/\&/g; + $what =~ s/\&\#60;/\/g; + return($what); +} + +sub t2h_print_label +{ + my $fh = shift; + my $href = shift || $T2H_HREF{This}; + $href =~ s/.*#(.*)$/$1/; + print $fh qq{\n}; +} + +############################################################################## + + # These next few lines are legal in both Perl and nroff. + +.00 ; # finish .ig + +'di \" finish diversion--previous line must be blank +.nr nl 0-1 \" fake up transition to first page again +.nr % 0 \" start at page 1 +'; __END__ ############# From here on it's a standard manual page ############ +.so /usr/local/man/man1/texi2html.1 diff --git a/readline-4.3/doc/texinfo.tex b/readline-4.3/doc/texinfo.tex new file mode 100644 index 0000000..c49af9f --- /dev/null +++ b/readline-4.3/doc/texinfo.tex @@ -0,0 +1,5992 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{1999-09-25.10} +% +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 +% Free Software Foundation, Inc. +% +% This texinfo.tex file 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 texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.gnu.org/gnu/texinfo.tex +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) +% ftp://texinfo.org/tex/texinfo.tex +% ftp://us.ctan.org/macros/texinfo/texinfo.tex +% (and all CTAN mirrors, finger ctan@us.ctan.org for a list). +% /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% The texinfo.tex in any given Texinfo distribution could well be out +% of date, so if that's what you're using, please check. +% Texinfo has a small home page at http://texinfo.org/. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever, to process the dvi file; this makes foo.ps. +% The extra runs of TeX get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages. You can get +% the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/. + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% Save some parts of plain tex whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexi=\i +\let\ptexlbrace=\{ +\let\ptexrbrace=\} +\let\ptexstar=\* +\let\ptext=\t + +% We never want plain's outer \+ definition in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +\message{Basics,} +\chardef\other=12 + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi + +% Ignore a token. +% +\def\gobble#1{} + +\hyphenation{ap-pen-dix} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{eshell} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen \bindingoffset +\newdimen \normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\ifx\eTeXversion\undefined +\def\loggingall{\tracingcommands2 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\else +\def\loggingall{\tracingcommands3 \tracingstats2 + \tracingpages1 \tracingoutput1 \tracinglostchars1 + \tracingmacros2 \tracingparagraphs1 \tracingrestores1 + \tracingscantokens1 \tracingassigns1 \tracingifs1 + \tracinggroups1 \tracingnesting2 + \showboxbreadth\maxdimen\showboxdepth\maxdimen +}% +\fi + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \turnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +% Single-spacing is done by various environments (specifically, in +% \nonfillstart and \quotations). +\newskip\singlespaceskip \singlespaceskip = 12.5pt +\def\singlespace{% + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip +} + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce actual \{ & \} command in an index. + \catcode`\{ = 12 \catcode`\} = 12 + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\@ = 0 \catcode`\\ = 12 + @gdef@lbracecmd[\{]% + @gdef@rbracecmd[\}]% +@endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + \endgroup % End the \group. + }% + % + \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + + +% @page forces the start of a new page +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + +%\hbox{{\rm#1}}\hfil\break}} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line outputs that line, centered + +\def\center{\parsearg\centerzzz} +\def\centerzzz #1{{\advance\hsize by -\leftskip +\advance\hsize by -\rightskip +\centerline{#1}}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% We cannot implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\def\paragraphindent{\parsearg\doparagraphindent} +\def\doparagraphindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\def\exampleindent{\parsearg\doexampleindent} +\def\doexampleindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math means output in math mode. +% We don't use $'s directly in the definition of \math because control +% sequences like \math are expanded when the toc file is written. Then, +% we read the toc file back, the $'s will be normal characters (as they +% should be, according to the definition of Texinfo). So we must use a +% control sequence to switch into and out of math mode. +% +% This isn't quite enough for @math to work properly in indices, but it +% seems unlikely it will ever be needed there. +% +\let\implicitmath = $ +\def\math#1{\implicitmath #1\implicitmath} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \iflinks + \readauxfile + \fi % \openindices needs to do some work in any case. + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +\ifx\pdfoutput\undefined + \pdffalse + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\linkcolor = \relax + \let\pdfmakeoutlines = \relax +\else + \pdftrue + \pdfoutput = 1 + \input pdfcolor + \def\dopdfimage#1#2#3{% + \def\imagewidth{#2}% + \def\imageheight{#3}% + \ifnum\pdftexversion < 14 + \pdfimage + \else + \pdfximage + \fi + \ifx\empty\imagewidth\else width \imagewidth \fi + \ifx\empty\imageheight\else height \imageheight \fi + {#1.pdf}% + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + \def\pdfmkdest#1{\pdfdest name{#1@} xyz} + \def\pdfmkpgn#1{#1@} + \let\linkcolor = \Cyan + \def\endlink{\Black\pdfendlink} + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + \def\pdfmakeoutlines{{% + \openin 1 \jobname.toc + \ifeof 1\else\bgroup + \closein 1 + \indexnofonts + \def\tt{} + % thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % + \def\chapentry ##1##2##3{} + \def\unnumbchapentry ##1##2{} + \def\secentry ##1##2##3##4{\advancenumber{chap##2}} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} + \def\unnumbsubsubsecentry ##1##2{} + \input \jobname.toc + \def\chapentry ##1##2##3{% + \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} + \def\unnumbchapentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\secentry ##1##2##3##4{% + \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} + \def\unnumbsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsecentry ##1##2##3##4##5{% + \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} + \def\unnumbsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \def\subsubsecentry ##1##2##3##4##5##6{% + \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} + \def\unnumbsubsubsecentry ##1##2{% + \pdfoutline goto name{\pdfmkpgn{##2}}{##1}} + \input \jobname.toc + \egroup\fi + }} + \def\makelinks #1,{% + \def\params{#1}\def\E{END}% + \ifx\params\E + \let\nextmakelinks=\relax + \else + \let\nextmakelinks=\makelinks + \ifnum\lnkcount>0,\fi + \picknum{#1}% + \startlink attr{/Border [0 0 0]} + goto name{\pdfmkpgn{\the\pgn}}% + \linkcolor #1% + \advance\lnkcount by 1% + \endlink + \fi + \nextmakelinks + } + \def\picknum#1{\expandafter\pn#1} + \def\pn#1{% + \def\p{#1}% + \ifx\p\lbrace + \let\nextpn=\ppn + \else + \let\nextpn=\ppnn + \def\first{#1} + \fi + \nextpn + } + \def\ppn#1{\pgn=#1\gobble} + \def\ppnn{\pgn=\first} + \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \fi + \nextsp} + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + \def\pdfurl#1{% + \begingroup + \normalturnoffactive\def\@{@}% + \leavevmode\Red + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + % #1 + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS| + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\mkpgn{#1}} + \linkcolor #1\endlink} + \def\mkpgn#1{#1@} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\fi % \ifx\pdfoutput + + +\message{fonts,} +% Font-change commands. + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Use Computer Modern fonts at \magstephalf (11pt). +\newcount\mainmagstep +\mainmagstep=\magstephalf + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\ifx\bigger\relax +\let\mainmagstep=\magstep1 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} +\else +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you many want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10. +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\setfont\smallrm\rmshape{9}{1000} +\setfont\smalltt\ttshape{9}{1000} +\setfont\smallbf\bfshape{10}{900} +\setfont\smallit\itshape{9}{1000} +\setfont\smallsl\slshape{9}{1000} +\setfont\smallsf\sfshape{9}{1000} +\setfont\smallsc\scshape{10}{900} +\setfont\smallttsl\ttslshape{10}{900} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} + +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} + +%\let\ssecbf=\ssecrm + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts, we +% don't bother to reset \scriptfont and \scriptscriptfont (which would +% also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy + \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf + \textfont\ttfam = \tentt \textfont\sffam = \tensf +} + + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \resetmathfonts \setleading{11pt}} + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} +\def\smartslanted#1{{\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\it #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic +\let\cite=\smartslanted + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp#1{`\tclose{#1}'\null} +\setfont\keyrm\rmshape{8}{1000} +\font\keysy=cmsy9 +\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active + \catcode`\_=\active + % + \global\def\code{\begingroup + \catcode`\-=\active \let-\codedash + \catcode`\_=\active \let_\codeunder + \codex + } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} +\def\codex #1{\tclose{#1}\endgroup} + +%\let\exp=\tclose %Was temporary + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is kbdinputdistinct. (Too much of a hassle to call the macro, +% the catcodes are wrong for parsearg to work.) +\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi + % + \ifpdf \pdfmakepagedesttrue \fi + % + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% Produces Day Month Year style of output. +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue. + \nobreak + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +% @table, @ftable, @vtable. +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey #1#2{% +\aboveenvbreak % +\itemmax=\itemindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \itemindent % +\exdentamount=\itemindent +\parindent = 0pt % +\parskip = \smallskipamount % +\ifdim \parskip=0pt \parskip=2pt \fi% +\def#2{\endgraf\afterenvbreak\endgroup}% +\def\itemcontents{#1}% +\let\item=\itemizeitem} + +% Set sfcode to normal for the chars that usually have another value. +% These are `.?!:;,' +\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 + \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip }% Add a normal word space as a separator; + % typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% This used to have \hskip1sp. But then the space in a template line is +% not enough. That is bad. So let's go back to just & until we +% encounter the problem it was intended to solve again. +% --karl, nathan@acm.org, 20apr99. +\def\tab{&} + +% @multitable ... @end multitable definitions: +% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup + \vskip\parskip + \let\item\crcr + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +\else +%% FIXME: what is \box0 supposed to be? +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{conditionals,} +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% + \let\chapter=\relax + \let\unnumbered=\relax + \let\top=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax + \let\section=\relax + \let\subsec=\relax + \let\subsubsec=\relax + \let\subsection=\relax + \let\subsubsection=\relax + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + \let\contents=\relax + \let\smallbook=\relax + \let\titlepage=\relax +} + +% Used in nested conditionals, where we have to parse the Texinfo source +% and so want to turn off most commands, in case they are used +% incorrectly. +% +\def\ignoremorecommands{% + \let\defcodeindex = \relax + \let\defcv = \relax + \let\deffn = \relax + \let\deffnx = \relax + \let\defindex = \relax + \let\defivar = \relax + \let\defmac = \relax + \let\defmethod = \relax + \let\defop = \relax + \let\defopt = \relax + \let\defspec = \relax + \let\deftp = \relax + \let\deftypefn = \relax + \let\deftypefun = \relax + \let\deftypeivar = \relax + \let\deftypeop = \relax + \let\deftypevar = \relax + \let\deftypevr = \relax + \let\defun = \relax + \let\defvar = \relax + \let\defvr = \relax + \let\ref = \relax + \let\xref = \relax + \let\printindex = \relax + \let\pxref = \relax + \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax + \let\include = \relax + \let\lowersections = \relax + \let\down = \relax + \let\raisesections = \relax + \let\up = \relax + \let\set = \relax + \let\clear = \relax + \let\item = \relax +} + +% Ignore @ignore ... @end ignore. +% +\def\ignore{\doignore{ignore}} + +% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. +% +\def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifnottex{\doignore{ifnottex}} +\def\html{\doignore{html}} +\def\menu{\doignore{menu}} +\def\direntry{\doignore{direntry}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1'. +% +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define a command to swallow text until we reach `@end #1'. + % This @ is a catcode 12 token (that is the normal catcode of @ in + % this texinfo.tex file). We change the catcode of @ below to match. + \long\def\doignoretext##1@end #1{\enddoignore}% + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode32 = 10 + % + % Ignore braces, too, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % We must not have @c interpreted as a control sequence. + \catcode`\@ = 12 + % + % Make the letter c a comment character so that the rest of the line + % will be ignored. This way, the document can have (for example) + % @c @end ifinfo + % and the @end ifinfo will be properly ignored. + % (We've just changed @ to catcode 12.) + \catcode`\c = 14 + % + % And now expand that command. + \doignoretext +} + +% What we do to finish off ignored text. +% +\def\enddoignore{\endgroup\ignorespaces}% + +\newif\ifwarnedobs\warnedobsfalse +\def\obstexwarn{% + \ifwarnedobs\relax\else + % We need to warn folks that they may have trouble with TeX 3.0. + % This uses \immediate\write16 rather than \message to get newlines. + \immediate\write16{} + \immediate\write16{WARNING: for users of Unix TeX 3.0!} + \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} + \immediate\write16{If you are running another version of TeX, relax.} + \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} + \immediate\write16{ Then upgrade your TeX installation if you can.} + \immediate\write16{ (See ftp://ftp.gnu.org/pub/gnu/TeX.README.)} + \immediate\write16{If you are stuck with version 3.0, run the} + \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} + \immediate\write16{ to use a workaround.} + \immediate\write16{} + \global\warnedobstrue + \fi +} + +% **In TeX 3.0, setting text in \nullfont hangs tex. For a +% workaround (which requires the file ``dummy.tfm'' to be installed), +% uncomment the following line: +%%%%%\font\nullfont=dummy\let\obstexwarn=\relax + +% Ignore text, except that we keep track of conditional commands for +% purposes of nesting, up to an `@end #1' command. +% +\def\nestedignore#1{% + \obstexwarn + % We must actually expand the ignored text to look for the @end + % command, so that nested ignore constructs work. Thus, we put the + % text into a \vbox and then do nothing with the result. To minimize + % the change of memory overflow, we follow the approach outlined on + % page 401 of the TeXbook: make the current font be a dummy font. + % + \setbox0 = \vbox\bgroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Define `@end #1' to end the box, which will in turn undefine the + % @end command again. + \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% + % + % We are going to be parsing Texinfo commands. Most cause no + % trouble when they are used incorrectly, but some commands do + % complicated argument parsing or otherwise get confused, so we + % undefine them. + % + % We can't do anything about stray @-signs, unfortunately; + % they'll produce `undefined control sequence' errors. + \ignoremorecommands + % + % Set the current font to be \nullfont, a TeX primitive, and define + % all the font commands to also use \nullfont. We don't use + % dummy.tfm, as suggested in the TeXbook, because not all sites + % might have that installed. Therefore, math mode will still + % produce output, but that should be an extremely small amount of + % stuff compared to the main input. + % + \nullfont + \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont + \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont + \let\tensf=\nullfont + % Similarly for index fonts (mostly for their use in smallexample). + \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont + \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont + \let\smallsf=\nullfont + % + % Don't complain when characters are missing from the fonts. + \tracinglostchars = 0 + % + % Don't bother to do space factor calculations. + \frenchspacing + % + % Don't report underfull hboxes. + \hbadness = 10000 + % + % Do minimal line-breaking. + \pretolerance = 10000 + % + % Do not execute instructions in @tex + \def\tex{\doignore{tex}}% + % Do not execute macro definitions. + % `c' is a comment character, so the word `macro' will get cut off. + \def\macro{\doignore{ma}}% +} + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +{ + \catcode`\_ = \active + % + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup + \catcode`\-=12 \catcode`\_=12 + \indexbreaks \let_\normalunderscore + \valuexxx} +} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable, since the result +% winds up in the index file. This means that if the variable's value +% contains other Texinfo commands, it's almost certain it will fail +% (although perhaps we could fix that with sufficient work to do a +% one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\ifsetxxx} +\def\ifsetxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifsetfail + \else + \expandafter\ifsetsucceed + \fi +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\nestedignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\ifclearxxx} +\def\ifclearxxx #1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \expandafter\ifclearsucceed + \else + \expandafter\ifclearfail + \fi +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\nestedignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text +% following, through the first @end iftex (etc.). Make `@end iftex' +% (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} + +% We can't just want to start a group at @iftex (for example) and end it +% at @end iftex, since then @set commands inside the conditional have no +% effect (they'd get reverted at the end of the group). So we must +% define \Eiftex to redefine itself to be its previous value. (We can't +% just define it to fail again with an ``unmatched end'' error, since +% the @ifset might be nested.) +% +\def\conditionalsucceed#1{% + \edef\temp{% + % Remember the current value of \E#1. + \let\nece{prevE#1} = \nece{E#1}% + % + % At the `@end #1', redefine \E#1 to be its previous value. + \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% + }% + \temp +} + +% We need to expand lots of \csname's, but we don't want to expand the +% control sequences after we've constructed them. +% +\def\nece#1{\expandafter\noexpand\csname#1\endcsname} + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} + +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. + +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}} +} + +\def\defcodeindex{\parsearg\newcodeindex} + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% The \closeout helps reduce unnecessary open files; the limit on the +% Acorn RISC OS is a mere 16 files. +\def\synindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\doindex{#2}}% +} + +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +\def\syncodeindex#1 #2 {% + \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname + \expandafter\closeout\csname#1indfile\endcsname + \expandafter\let\csname#1indfile\endcsname=\synindexfoo + \expandafter\xdef\csname#1index\endcsname{% define \xxxindex + \noexpand\docodeindex{#2}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +\def\indexdummies{% +\def\ { }% +% Take care of the plain tex accent commands. +\def\"{\realbackslash "}% +\def\`{\realbackslash `}% +\def\'{\realbackslash '}% +\def\^{\realbackslash ^}% +\def\~{\realbackslash ~}% +\def\={\realbackslash =}% +\def\b{\realbackslash b}% +\def\c{\realbackslash c}% +\def\d{\realbackslash d}% +\def\u{\realbackslash u}% +\def\v{\realbackslash v}% +\def\H{\realbackslash H}% +% Take care of the plain tex special European modified letters. +\def\oe{\realbackslash oe}% +\def\ae{\realbackslash ae}% +\def\aa{\realbackslash aa}% +\def\OE{\realbackslash OE}% +\def\AE{\realbackslash AE}% +\def\AA{\realbackslash AA}% +\def\o{\realbackslash o}% +\def\O{\realbackslash O}% +\def\l{\realbackslash l}% +\def\L{\realbackslash L}% +\def\ss{\realbackslash ss}% +% Take care of texinfo commands likely to appear in an index entry. +% (Must be a way to avoid doing expansion at all, and thus not have to +% laboriously list every single command here.) +\def\@{@}% will be @@ when we switch to @ as escape char. +% Need these in case \tex is in effect and \{ is a \delimiter again. +% But can't use \lbracecmd and \rbracecmd because texindex assumes +% braces and backslashes are used only as delimiters. +\let\{ = \mylbrace +\let\} = \myrbrace +\def\_{{\realbackslash _}}% +\def\w{\realbackslash w }% +\def\bf{\realbackslash bf }% +%\def\rm{\realbackslash rm }% +\def\sl{\realbackslash sl }% +\def\sf{\realbackslash sf}% +\def\tt{\realbackslash tt}% +\def\gtr{\realbackslash gtr}% +\def\less{\realbackslash less}% +\def\hat{\realbackslash hat}% +\def\TeX{\realbackslash TeX}% +\def\dots{\realbackslash dots }% +\def\result{\realbackslash result}% +\def\equiv{\realbackslash equiv}% +\def\expansion{\realbackslash expansion}% +\def\print{\realbackslash print}% +\def\error{\realbackslash error}% +\def\point{\realbackslash point}% +\def\copyright{\realbackslash copyright}% +\def\tclose##1{\realbackslash tclose {##1}}% +\def\code##1{\realbackslash code {##1}}% +\def\uref##1{\realbackslash uref {##1}}% +\def\url##1{\realbackslash url {##1}}% +\def\env##1{\realbackslash env {##1}}% +\def\command##1{\realbackslash command {##1}}% +\def\option##1{\realbackslash option {##1}}% +\def\dotless##1{\realbackslash dotless {##1}}% +\def\samp##1{\realbackslash samp {##1}}% +\def\,##1{\realbackslash ,{##1}}% +\def\t##1{\realbackslash t {##1}}% +\def\r##1{\realbackslash r {##1}}% +\def\i##1{\realbackslash i {##1}}% +\def\b##1{\realbackslash b {##1}}% +\def\sc##1{\realbackslash sc {##1}}% +\def\cite##1{\realbackslash cite {##1}}% +\def\key##1{\realbackslash key {##1}}% +\def\file##1{\realbackslash file {##1}}% +\def\var##1{\realbackslash var {##1}}% +\def\kbd##1{\realbackslash kbd {##1}}% +\def\dfn##1{\realbackslash dfn {##1}}% +\def\emph##1{\realbackslash emph {##1}}% +\def\acronym##1{\realbackslash acronym {##1}}% +% +% Handle some cases of @value -- where the variable name does not +% contain - or _, and the value does not contain any +% (non-fully-expandable) commands. +\let\value = \expandablevalue +% +\unsepspaces +% Turn off macro expansion +\turnoffmacros +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + +% \indexnofonts no-ops all font-change commands. +% This is used when outputting the strings to sort the index by. +\def\indexdummyfont#1{#1} +\def\indexdummytex{TeX} +\def\indexdummydots{...} + +\def\indexnofonts{% +% Just ignore accents. +\let\,=\indexdummyfont +\let\"=\indexdummyfont +\let\`=\indexdummyfont +\let\'=\indexdummyfont +\let\^=\indexdummyfont +\let\~=\indexdummyfont +\let\==\indexdummyfont +\let\b=\indexdummyfont +\let\c=\indexdummyfont +\let\d=\indexdummyfont +\let\u=\indexdummyfont +\let\v=\indexdummyfont +\let\H=\indexdummyfont +\let\dotless=\indexdummyfont +% Take care of the plain tex special European modified letters. +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% +\let\w=\indexdummyfont +\let\t=\indexdummyfont +\let\r=\indexdummyfont +\let\i=\indexdummyfont +\let\b=\indexdummyfont +\let\emph=\indexdummyfont +\let\strong=\indexdummyfont +\let\cite=\indexdummyfont +\let\sc=\indexdummyfont +%Don't no-op \tt, since it isn't a user-level command +% and is used in the definitions of the active chars like <, >, |... +%\let\tt=\indexdummyfont +\let\tclose=\indexdummyfont +\let\code=\indexdummyfont +\let\url=\indexdummyfont +\let\uref=\indexdummyfont +\let\env=\indexdummyfont +\let\acronym=\indexdummyfont +\let\command=\indexdummyfont +\let\option=\indexdummyfont +\let\file=\indexdummyfont +\let\samp=\indexdummyfont +\let\kbd=\indexdummyfont +\let\key=\indexdummyfont +\let\var=\indexdummyfont +\let\TeX=\indexdummytex +\let\dots=\indexdummydots +\def\@{@}% +} + +% To define \realbackslash, we must make \ not be an escape. +% We must first make another character (@) an escape +% so we do not become unable to do a definition. + +{\catcode`\@=0 \catcode`\\=\other + @gdef@realbackslash{\}} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% For \ifx comparisons. +\def\emptymacro{\empty} + +% Most index entries go through here, but \dosubind is the general case. +% +\def\doind#1#2{\dosubind{#1}{#2}\empty} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. +% +\def\dosubind#1#2#3{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% + \fi + {% + \count255=\lastpenalty + {% + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + {% + \let\folio = 0% We will expand all macros now EXCEPT \folio. + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + \def\thirdarg{#3}% + % + % If third arg is present, precede it with space in sort key. + \ifx\thirdarg\emptymacro + \let\subentry = \empty + \else + \def\subentry{ #3}% + \fi + % + % First process the index entry with all font commands turned + % off to get the string to sort by. + {\indexnofonts \xdef\indexsorttmp{#2\subentry}}% + % + % Now the real index entry with the fonts. + \toks0 = {#2}% + % + % If third (subentry) arg is present, add it to the index + % string. And include a space. + \ifx\thirdarg\emptymacro \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + % Set up the complete index entry, with both the sort key + % and the original text, including any font commands. We write + % three arguments to \entry to the .?? file, texindex reduces to + % two when writing the .??s sorted result. + \edef\temp{% + \write\csname#1indfile\endcsname{% + \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% + }% + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write will make \lastskip zero. The result is that sequences + % like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + \iflinks + \ifvmode + \skip0 = \lastskip + \ifdim\lastskip = 0pt \else \nobreak\vskip-\lastskip \fi + \fi + % + \temp % do the write + % + % + \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi + \fi + }% + }% + \penalty\count255 + }% +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \indexbreaks + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \penalty -300 + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % + % Do our best not to break after the initial. + \nobreak +}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ #2% The page number ends the paragraph. + \fi + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm + +\def\secondary #1#2{ +{\parfillskip=0in \parskip=0in +\hangindent =1in \hangafter=1 +\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +\def\pagesofar{% + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split, in box0 and box2. + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +\def\enddoublecolumns{% + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +\def\balancecolumns{% + % Called at the end of the double column material. + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% \def\appendixletter{\char\the\appendixno} +% We do the following for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise. +\def\thischapter{} +\def\thissection{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raise/lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2} +\or + \seczzz{#2} +\or + \numberedsubseczzz{#2} +\or + \numberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \chapterzzz{#2} + \else + \numberedsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2} +\or + \appendixsectionzzz{#2} +\or + \appendixsubseczzz{#2} +\or + \appendixsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \appendixzzz{#2} + \else + \appendixsubsubseczzz{#2} + \fi +\fi +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \unnumberedzzz{#2} +\or + \unnumberedseczzz{#2} +\or + \unnumberedsubseczzz{#2} +\or + \unnumberedsubsubseczzz{#2} +\else + \ifnum \absseclevel<0 + \unnumberedzzz{#2} + \else + \unnumberedsubsubseczzz{#2} + \fi +\fi +} + +% @chapter, @appendix, @unnumbered. +\def\thischaptername{No Chapter Title} +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% +\chapmacro {#1}{\the\chapno}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +% We don't substitute the actual chapter name into \thischapter +% because we don't want its macros evaluated now. +\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\the\chapno}}}% +\temp +\donoderef +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec +} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +\global\advance \appendixno by 1 +\message{\putwordAppendix\space \appendixletter}% +\chapmacro {#1}{\putwordAppendix{} \appendixletter}% +\gdef\thissection{#1}% +\gdef\thischaptername{#1}% +\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash chapentry{\the\toks0}% + {\putwordAppendix{} \appendixletter}}}% +\temp +\appendixnoderef +\global\let\section = \appendixsec +\global\let\subsection = \appendixsubsec +\global\let\subsubsection = \appendixsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz #1{% +\secno=0 \subsecno=0 \subsubsecno=0 +% +% This used to be simply \message{#1}, but TeX fully expands the +% argument to \message. Therefore, if #1 contained @-commands, TeX +% expanded them. For example, in `@unnumbered The @cite{Book}', TeX +% expanded @cite (which turns out to cause errors because \cite is meant +% to be executed, not expanded). +% +% Anyway, we don't want the fully-expanded definition of @cite to appear +% as a result of the \message, we just want `@cite' itself. We use +% \the to achieve this: TeX expands \the only once, +% simply yielding the contents of . (We also do this for +% the toc entries.) +\toks0 = {#1}\message{(\the\toks0)}% +% +\unnumbchapmacro {#1}% +\gdef\thischapter{#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbchapentry{\the\toks0}}}% +\temp +\unnumbnoderef +\global\let\section = \unnumberedsec +\global\let\subsection = \unnumberedsubsec +\global\let\subsubsection = \unnumberedsubsubsec +} + +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy #1{\numhead1{#1}} % normally calls seczzz +\def\seczzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\the\chapno}{\the\secno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz #1{% +\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % +\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash secentry{\the\toks0}% + {\appendixletter}{\the\secno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz #1{% +\plainsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsecentry{\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsections. +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz #1{% +\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % +\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz #1{% +\plainsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% Subsubsections. +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\donoderef +\nobreak +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz #1{% +\gdef\thissection{#1}\global\advance \subsubsecno by 1 % +\subsubsecheading {#1} + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash subsubsecentry{\the\toks0}% + {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}}% +\temp +\appendixnoderef +\nobreak +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz #1{% +\plainsubsubsecheading {#1}\gdef\thissection{#1}% +\toks0 = {#1}% +\edef\temp{\noexpand\writetocentry{\realbackslash unnumbsubsubsecentry% + {\the\toks0}}}% +\temp +\unnumbnoderef +\nobreak +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they should now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\global\let\section = \numberedsec +\global\let\subsection = \numberedsubsec +\global\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{\parsearg\majorheadingzzz} +\def\majorheadingzzz #1{% +{\advance\chapheadingskip by 10pt \chapbreak }% +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +\def\chapheading{\parsearg\chapheadingzzz} +\def\chapheadingzzz #1{\chapbreak % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\penalty 200} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\plainsecheading} +\def\subheading{\parsearg\plainsubsecheading} +\def\subsubheading{\parsearg\plainsubsubsecheading} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{ +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{ +\global\let\chapmacro=\chfplain +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} + +% Plain chapter opening. +% #1 is the text, #2 the chapter number or empty if unnumbered. +\def\chfplain#1#2{% + \pchapsepmacro + {% + \chapfonts \rm + \def\chapnum{#2}% + \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% Plain opening for unnumbered. +\def\unnchfplain#1{\chfplain{#1}{}} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{}% +}} + +\CHAPFplain % The default + +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} + +\def\CHAPFopen{ +\global\let\chapmacro=\chfopen +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip {-1000}} +\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} +\def\plainsecheading#1{\sectionheading{sec}{}{#1}} + +% Subsection titles. +\newskip \subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} +\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} +\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} + +% Subsubsection titles. +\let\subsubsecheadingskip = \subsecheadingskip +\let\subsubsecheadingbreak = \subsecheadingbreak +\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} +\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} + + +% Print any size section title. +% +% #1 is the section type (sec/subsec/subsubsec), #2 is the section +% number (maybe empty), #3 the text. +\def\sectionheading#1#2#3{% + {% + \expandafter\advance\csname #1headingskip\endcsname by \parskip + \csname #1headingbreak\endcsname + }% + {% + % Switch to the right set of fonts. + \csname #1fonts\endcsname \rm + % + % Only insert the separating space if we have a section number. + \def\secnum{#2}% + \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% + % + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent = \wd0 % zero if no section number + \unhbox0 #3}% + }% + \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. We supply {\folio} at the end of the +% argument, which will end up as the last argument to the \...entry macro. +% +% We open the .toc file here instead of at @setfilename or any other +% given time so that @contents can be put in the document anywhere. +% +\newif\iftocfileopened +\def\writetocentry#1{% + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + \iflinks \write\tocfile{#1{\folio}}\fi +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Finish up the main text and prepare to read what we've written +% to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \unnumbchapmacro{#1}\def\thischapter{}% + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \pageno = \lastnegativepageno \fi +} + + +% Normal (long) toc. +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \pdfmakeoutlines + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\chapentry = \shortchapentry + \let\unnumbchapentry = \shortunnumberedentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\secentry ##1##2##3##4{} + \def\unnumbsecentry ##1##2{} + \def\subsecentry ##1##2##3##4##5{} + \def\unnumbsubsecentry ##1##2{} + \def\subsubsecentry ##1##2##3##4##5##6{} + \def\unnumbsubsubsecentry ##1##2{} + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \pageno = \savepageno +} +\let\shortcontents = \summarycontents + +\ifpdf + \pdfcatalog{/PageMode /UseOutlines}% +\fi + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapter-level things, for both the long and short contents. +\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} + +% See comments in \dochapentry re vbox and related settings +\def\shortchapentry#1#2#3{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% +} + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. +% We could simplify the code here by writing out an \appendixentry +% command in the toc file for appendices, instead of using \chapentry +% for both, but it doesn't seem worth it. +% +\newdimen\shortappendixwidth +% +\def\shortchaplabel#1{% + % Compute width of word "Appendix", may change with language. + \setbox0 = \hbox{\shortcontrm \putwordAppendix}% + \shortappendixwidth = \wd0 + % + % We typeset #1 in a box of constant width, regardless of the text of + % #1, so the chapter titles will come out aligned. + \setbox0 = \hbox{#1}% + \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi + % + % This space should be plenty, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + \advance\dimen0 by 1.1em + \hbox to \dimen0{#1\hfil}% +} + +\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} +\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno\bgroup#2\egroup}} + +% Sections. +\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} +\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} + +% Subsections. +\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} +\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} + +% And subsubsections. +\def\subsubsecentry#1#2#3#4#5#6{% + \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} +\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 3pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, so characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\let\subsecentryfonts = \textfonts +\let\subsubsecentryfonts = \textfonts + + +\message{environments,} +% @foo ... @end foo. + +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% Furthermore, these definitions must come after we define our fonts. +\newbox\dblarrowbox \newbox\longdblarrowbox +\newbox\pushcharbox \newbox\bullbox +\newbox\equivbox \newbox\errorbox + +%{\tentt +%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} +%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} +%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} +%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} +% Adapted from the manmac format (p.420 of TeXbook) +%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex +% depth .1ex\hfil} +%} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% Adapted from the TeXbook's \boxit. +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} + +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + +% The @error{} command. +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie + \catcode `\%=14 + \catcode 43=12 % plus + \catcode`\"=12 + \catcode`\==12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +\let\Etex=\endgroup} + +% Define @lisp ... @endlisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @endlisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip +% +\def\aboveenvbreak{{\advance\envskipamount by \parskip +\endgraf \ifdim\lastskip<\envskipamount +\removelastskip \penalty-50 \vskip\envskipamount \fi}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\long\def\cartouche{% +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \singlespace + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. +% +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} + +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} + +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + +% @small... is usually equivalent to the non-small (@smallbook +% redefines). We must call \example (or whatever) last in the +% definition, since it reads the return following the @example (or +% whatever) command. +% +% This actually allows (for example) @end display inside an +% @smalldisplay. Too bad, but makeinfo will catch the error anyway. +% +\def\smalldisplay{\begingroup\def\Esmalldisplay{\nonfillfinish\endgroup}\display} +\def\smallexample{\begingroup\def\Esmallexample{\nonfillfinish\endgroup}\lisp} +\def\smallformat{\begingroup\def\Esmallformat{\nonfillfinish\endgroup}\format} +\def\smalllisp{\begingroup\def\Esmalllisp{\nonfillfinish\endgroup}\lisp} + +% Real @smallexample and @smalllisp (when @smallbook): use smaller fonts. +% Originally contributed by Pavel@xerox. +\def\smalllispx{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \smallfonts + \lisp +} + +% @display: same as @lisp except keep current font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} + +% @smalldisplay (when @smallbook): @display plus smaller fonts. +% +\def\smalldisplayx{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \smallfonts \rm + \display +} + +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} + +% @smallformat (when @smallbook): @format plus smaller fonts. +% +\def\smallformatx{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \smallfonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} + +% @flushright. +% +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble +} + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + + +\message{defuns,} +% @defun etc. + +% Allow user to change definition object font (\df) internally +\def\setdeffont #1 {\csname DEF#1\endcsname} + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deftypemargin \deftypemargin=12pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount +% define \functionparens, which makes ( and ) and & do special things. +% \functionparens affects the group it is contained in. +\def\activeparens{% +\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active +\catcode`\[=\active \catcode`\]=\active} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\let\ampnr = \& +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% Active &'s sneak into the index arguments, so make sure it's defined. +{ + \catcode`& = 13 + \global\let& = \ampnr +} + +% First, defname, which formats the header line itself. +% #1 should be the function name. +% #2 should be the type of definition, such as "Function". + +\def\defname #1#2{% +% Get the values of \leftskip and \rightskip as they were +% outside the @def... +\dimen2=\leftskip +\advance\dimen2 by -\defbodyindent +\noindent +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +{% Adjust \hsize to exclude the ambient margins, +% so that \rightline will obey them. +\advance \hsize by -\dimen2 +\rlap{\rightline{{\rm #2}\hskip -1.25pc }}}% +% Make all lines underfull and no complaints: +\tolerance=10000 \hbadness=10000 +\advance\leftskip by -\defbodyindent +\exdentamount=\defbodyindent +{\df #1}\enskip % Generate function name +} + +% Actually process the body of a definition +% #1 should be the terminating control sequence, such as \Edefun. +% #2 should be the "another name" control sequence, such as \defunx. +% #3 should be the control sequence that actually processes the header, +% such as \defunheader. + +\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\activeparens\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % 61 is `=' +\obeylines\activeparens\spacesplit#3} + +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by the space, is the class name. +% +\def\defmethparsebody#1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +% Used for @deftypemethod and @deftypeivar. +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence for consecutive fns (which we define). +% #3 is the control sequence to call to resume processing. +% #4, delimited by a space, is the class name. +% #5 is the method's return type. +% +\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}} + +% Used for @deftypeop. The change from \deftypemethparsebody is an +% extra argument at the beginning which is the `category', instead of it +% being the hardwired string `Method' or `Instance Variable'. We have +% to account for this both in the \...x definition and in parsing the +% input at hand. Thus also need a control sequence (passed as #5) for +% the \E... definition to assign the category name to. +% +\def\deftypeopparsebody#1#2#3#4#5 #6 {\begingroup\inENV + \medbreak + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 ##2 ##3 {% + \def#4{##1}% + \begingroup\obeylines\activeparens\spacesplit{#3{##2}{##3}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines\activeparens\spacesplit{#3{#5}{#6}}} + +\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\activeparens\spacesplit{#3{#5}}} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. + +\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2{\begingroup\obeylines\spacesplit#3}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup % +\catcode 61=\active % +\obeylines\spacesplit#3} + +% This is used for \def{tp,vr}parsebody. It could probably be used for +% some of the others, too, with some judicious conditionals. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV % + \medbreak % + % Define the end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + \begingroup\obeylines +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 ##2 {\def#4{##1}% +\begingroup\obeylines\spacesplit{#3{##2}}}% +\parindent=0in +\advance\leftskip by \defbodyindent +\exdentamount=\defbodyindent +\begingroup\obeylines\spacesplit{#3{#5}}} + +% Split up #2 at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. + +{\obeylines +\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% +\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% +\ifx\relax #3% +#1{#2}{}\else #1{#2}{#3#4}\fi}} + +% So much for the things common to all kinds of definitions. + +% Define @defun. + +% First, define the processing that is wanted for arguments of \defun +% Use this to expand the args and terminate the paragraph they make up + +\def\defunargs#1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Set the font temporarily and use \font in case \setfont made \tensl a macro. +{\tensl\hyphenchar\font=0}% +#1% +{\tensl\hyphenchar\font=45}% +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars +\interlinepenalty=10000 +\advance\rightskip by 0pt plus 1fil +\endgraf\nobreak\vskip -\parskip\nobreak +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDeffunc}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypefun}% +\deftypefunargs {#3}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$$$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefmac}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefspec}% +\defunargs {#2}\endgroup % +\catcode 61=\other % Turn off change made in \defparsebody +} + +% @defop CATEGORY CLASS OPERATION ARG... +% +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} +% +\def\defopheader#1#2#3{% +\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index +\begingroup\defname {#2}{\defoptype\ \putwordon\ #1}% +\defunargs {#3}\endgroup % +} + +% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... +% +\def\deftypeop #1 {\def\deftypeopcategory{#1}% + \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader + \deftypeopcategory} +% +% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. +\def\deftypeopheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3} + {\deftypeopcategory\ \putwordon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypemethod CLASS TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypeivar CLASS TYPE VARNAME +% +\def\deftypeivar{% + \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} +% +% #1 is the class name, #2 the data type, #3 the variable name. +\def\deftypeivarheader#1#2#3{% + \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index + \begingroup + \defname{#3}{\putwordInstanceVariableof\ \code{#1}}% + \defvarargs{#3}% + \endgroup +} + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% +\dosubind {vr}{\code{#2}}{\putwordof\ #1}% Make entry in var index +\begingroup\defname {#2}{\defcvtype\ \putwordof\ #1}% +\defvarargs {#3}\endgroup % +} + +% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME +% +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} +% +\def\defivarheader#1#2#3{% + \dosubind {vr}{\code{#2}}{\putwordof\ #1}% entry in var index + \begingroup + \defname{#2}{\putwordInstanceVariableof\ #1}% + \defvarargs{#3}% + \endgroup +} + +% @defvar +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefvar}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefopt}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{\putwordDeftypevar}% +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} +\interlinepenalty=10000 +\endgraf\nobreak\vskip -\parskip\nobreak +\endgroup} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% These definitions are used if you use @defunx (etc.) +% anywhere other than immediately after a @defun or @defunx. +% +\def\defcvx#1 {\errmessage{@defcvx in invalid context}} +\def\deffnx#1 {\errmessage{@deffnx in invalid context}} +\def\defivarx#1 {\errmessage{@defivarx in invalid context}} +\def\defmacx#1 {\errmessage{@defmacx in invalid context}} +\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\defopx#1 {\errmessage{@defopx in invalid context}} +\def\defspecx#1 {\errmessage{@defspecx in invalid context}} +\def\deftpx#1 {\errmessage{@deftpx in invalid context}} +\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} +\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} +\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} +\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} +\def\defunx#1 {\errmessage{@defunx in invalid context}} +\def\defvarx#1 {\errmessage{@defvarx in invalid context}} +\def\defvrx#1 {\errmessage{@defvrx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + % Undo catcode changes of \startcontents and \doprintindex + \catcode`\@=0 \catcode`\\=12 \escapechar=`\@ + % Append \endinput to make sure that TeX does not see the ending newline. + \toks0={#1\endinput}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup +} +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +% Undo catcode changes of \startcontents and \doprintindex +\catcode`\@=0 \catcode`\\=12 \escapechar=`\@ +\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} +\fi + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? +\def\macrolist{} % List of all defined macros in the form + % \do\macro1\do\macro2... + +% Utility routines. +% Thisdoes \let #1 = #2, except with \csnames. +\def\cslet#1#2{% +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=12\catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\macrobodyctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\{=12 + \catcode`\}=12 + \catcode`\@=12 + \catcode`\^^M=12 + \usembodybackslash} + +\def\macroargctxt{% + \catcode`\~=12 + \catcode`\^=12 + \catcode`\_=12 + \catcode`\|=12 + \catcode`\<=12 + \catcode`\>=12 + \catcode`\+=12 + \catcode`\@=12 + \catcode`\\=12} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{The name \the\macname\space is reserved}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + % Add the macroname to \macrolist + \toks0 = \expandafter{\macrolist\do}% + \xdef\macrolist{\the\toks0 + \expandafter\noexpand\csname\the\macname\endcsname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\def\unmacro{\parsearg\unmacroxxx} +\def\unmacroxxx#1{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist + \begingroup + \edef\tempa{\expandafter\noexpand\csname#1\endcsname}% + \def\do##1{% + \def\tempb{##1}% + \ifx\tempa\tempb + % remove this + \else + \toks0 = \expandafter{\newmacrolist\do}% + \edef\newmacrolist{\the\toks0\expandafter\noexpand\tempa}% + \fi}% + \def\newmacrolist{}% + % Execute macro list to define \newmacrolist + \macrolist + \global\let\macrolist\newmacrolist + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \next} + +% We mant to disable all macros during \shipout so that they are not +% expanded by \write. +\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% + \edef\next{\macrolist}\expandafter\endgroup\next} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Just make them active and then expand them all to nothing. +\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{\ignoreactivespaces +\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% + \expandafter\noexpand\csname#2\endcsname}% +\expandafter\endgroup\next} + + +\message{cross references,} +% @xref etc. + +\newwrite\auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's job is to define \lastnode. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx [#1,]} +\def\nodexxx[#1,#2]{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\relax + +% The sectioning commands (@chapter, etc.) call these. +\def\donoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Ysectionnumberandtype}% + \global\let\lastnode=\relax + \fi +} +\def\unnumbnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% + \global\let\lastnode=\relax + \fi +} +\def\appendixnoderef{% + \ifx\lastnode\relax\else + \expandafter\expandafter\expandafter\setref{\lastnode}% + {Yappendixletterandtype}% + \global\let\lastnode=\relax + \fi +} + + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME, namely +% NAME-title, NAME-pg, and NAME-SNT. Called from \foonoderef. We have +% to set \indexdummies so commands such as @code in a section title +% aren't expanded. It would be nicer not to expand the titles in the +% first place, but there's so many layers that that is hard to do. +% +\def\setref#1#2{{% + \indexdummies + \pdfmkdest{#1}% + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2}% +}} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifpdf + \leavevmode + \getfilename{#4}% + \ifnum\filenamelength>0 + \startlink attr{/Border [0 0 0]}% + goto file{\the\filename.pdf} name{#1@}% + \else + \startlink attr{/Border [0 0 0]}% + goto name{#1@}% + \fi + \linkcolor + \fi + % + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\normalturnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % [mynode], + [\printednodename],\space + % page 3 + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi + \endlink +\endgroup} + +% \dosetq is the interface for calls from other macros + +% Use \normalturnoffactive so that punctuation chars such as underscore +% and backslash work in node names. (\turnoffactive doesn't do \.) +\def\dosetq#1#2{% + {\let\folio=0% + \normalturnoffactive + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \iflinks + \next + \fi + }% +} + +% \internalsetq {foo}{page} expands into +% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} +% When the aux file is read, ' is the escape character + +\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq + +\def\Ypagenumber{\folio} + +\def\Ytitle{\thissection} + +\def\Ynothing{} + +\def\Ysectionnumberandtype{% +\ifnum\secno=0 \putwordChapter\xreftie\the\chapno % +\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\def\Yappendixletterandtype{% +\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% +\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % +\else \ifnum \subsubsecno=0 % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % +\else % +\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % +\fi \fi \fi } + +\gdef\xreftie{'tie} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Non-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. + +\def\refx#1#2{% + \expandafter\ifx\csname X#1\endcsname\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \csname X#1\endcsname + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +% +\def\xrdef#1{\begingroup + % Reenable \ as an escape while reading the second argument. + \catcode`\\ = 0 + \afterassignment\endgroup + \expandafter\gdef\csname X#1\endcsname +} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + \catcode`\@=\other + \catcode`\^=\other + % It was suggested to define this as 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % The aux file uses ' as the escape (for now). + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\%=\other + \catcode`\'=0 + \catcode`\\=\other + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \global\warnedobstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \footnotezzz +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\long\gdef\footnotezzz{\insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Hang the footnote text off the number. + \hang + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t + \else\let\next\f@t\fi \next} +\def\f@@t{\bgroup\aftergroup\@foot\let\next} +\def\f@t#1{#1\@foot} +\def\@foot{\strut\par\egroup} + +}%end \catcode `\@=11 + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + \closein 1 + % Do not bother showing banner with post-v2.7 epsf.tex (available in + % doc/epsf.tex until it shows up on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is just the usual extra ignored arg for parsing this stuff. +\def\imagexxx#1,#2,#3,#4\finish{% + \ifpdf + \centerline{\dopdfimage{#1}{#2}{#3}}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \begingroup + \catcode`\^^M = 5 % in case we're inside an example + % If the image is by itself, center it. + \ifvmode + \nobreak\bigskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \centerline{\epsfbox{#1.eps}}% + \bigbreak + \else + % In the middle of a paragraph, no extra space. + \epsfbox{#1.eps}% + \fi + \endgroup + \fi +} + + +\message{localization,} +% and i18n. + +% @documentlanguage is usually given very early, just after +% @setfilename. If done too late, it may not override everything +% properly. Single argument is the language abbreviation. +% It would be nice if we could set up a hyphenation file here. +% +\def\documentlanguage{\parsearg\dodocumentlanguage} +\def\dodocumentlanguage#1{% + \tex % read txi-??.tex file in plain TeX. + % Read the file if it exists. + \openin 1 txi-#1.tex + \ifeof1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \let\temp = \relax + \else + \def\temp{\input txi-#1.tex }% + \fi + \temp + \endgroup +} +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? In the current directory +should work if nowhere else does.} + + +% @documentencoding should change something in TeX eventually, most +% likely, but for now just recognize it. +\let\documentencoding = \comment + + +% Page size parameters. +% +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; +% 4) hoffset; 5) binding offset; 6) topskip. Then whoever calls us can +% set \parskip and call \setleading for \baselineskip. +% +\def\internalpagesizes#1#2#3#4#5#6{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + % If page is nothing but text, make it come out even. + \internalpagesizes{46\baselineskip}{6in}{\voffset}{.25in}{\bindingoffset}{36pt}% +}} + +% Use @smallbook to reset parameters for 7x9.5 (or so) format. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \setleading{12pt}% + % + \internalpagesizes{7.5in}{5.in}{\voffset}{.25in}{\bindingoffset}{16pt}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \deftypemargin = 0pt + \defbodyindent = .5cm + % + \let\smalldisplay = \smalldisplayx + \let\smallexample = \smalllispx + \let\smallformat = \smallformatx + \let\smalllisp = \smalllispx +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \setleading{12pt}% + \parskip = 3pt plus 2pt minus 1pt + % + \internalpagesizes{53\baselineskip}{160mm}{\voffset}{4mm}{\bindingoffset}{44pt}% + % + \tolerance = 700 + \hfuzz = 1pt +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex{{\globaldefs = 1 + \setleading{13.6pt}% + % + \afourpaper + \internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}% + % + \globaldefs = 0 +}} + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{% + \afourpaper + \internalpagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}% + % + \globaldefs = 0 +} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{13.2pt}% + % + \internalpagesizes{#1}{\hsize}{\voffset}{\normaloffset}{\bindingoffset}{44pt}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$} + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar} +%\catcode 27=\active +%\def^^[{$\diamondsuit$} + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx output one backslash character in current font +\global\chardef\rawbackslashxx=`\\ +%{\catcode`\\=\other +%@gdef@rawbackslashxx{\}} + +% \rawbackslash redefines \ as input to do \rawbackslashxx. +{\catcode`\\=\active +@gdef@rawbackslash{@let\=@rawbackslashxx }} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +% \catcode 17=0 % Define control-q +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus +@let$=@normaldollar} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These look ok in all fonts, so just make them not special. +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other + +@c Set initial fonts. +@textfonts +@rm + + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: diff --git a/readline-4.3/emacs_keymap.c b/readline-4.3/emacs_keymap.c new file mode 100644 index 0000000..ca9d134 --- /dev/null +++ b/readline-4.3/emacs_keymap.c @@ -0,0 +1,873 @@ +/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +/* An array of function pointers, one for each possible key. + If the type byte is ISKMAP, then the pointer is the address of + a keymap. */ + +KEYMAP_ENTRY_ARRAY emacs_standard_keymap = { + + /* Control keys. */ + { ISFUNC, rl_set_mark }, /* Control-@ */ + { ISFUNC, rl_beg_of_line }, /* Control-a */ + { ISFUNC, rl_backward_char }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_delete }, /* Control-d */ + { ISFUNC, rl_end_of_line }, /* Control-e */ + { ISFUNC, rl_forward_char }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, rl_char_search }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_undo_command }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { 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) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { 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 */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_meta_keymap = { + + /* Meta keys. Just like above, but the high bit is set. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */ + { ISFUNC, rl_abort }, /* Meta-Control-g */ + { ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */ + { ISFUNC, rl_tab_insert }, /* Meta-Control-i */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-l */ + { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */ + { ISFUNC, rl_revert_line }, /* Meta-Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */ + { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */ + + { ISFUNC, rl_complete }, /* Meta-Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */ + { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_set_mark }, /* Meta-SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */ + { ISFUNC, rl_insert_comment }, /* Meta-# */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */ + { ISFUNC, rl_tilde_expand }, /* Meta-& */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */ + { ISFUNC, rl_insert_completions }, /* Meta-* */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */ + { ISFUNC, rl_digit_argument }, /* Meta-- */ + { ISFUNC, rl_yank_last_arg}, /* Meta-. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */ + + /* Regular digits. */ + { ISFUNC, rl_digit_argument }, /* Meta-0 */ + { ISFUNC, rl_digit_argument }, /* Meta-1 */ + { ISFUNC, rl_digit_argument }, /* Meta-2 */ + { ISFUNC, rl_digit_argument }, /* Meta-3 */ + { ISFUNC, rl_digit_argument }, /* Meta-4 */ + { ISFUNC, rl_digit_argument }, /* Meta-5 */ + { ISFUNC, rl_digit_argument }, /* Meta-6 */ + { ISFUNC, rl_digit_argument }, /* Meta-7 */ + { ISFUNC, rl_digit_argument }, /* Meta-8 */ + { ISFUNC, rl_digit_argument }, /* Meta-9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */ + { ISFUNC, rl_beginning_of_history }, /* Meta-< */ + { ISFUNC, rl_possible_completions }, /* Meta-= */ + { ISFUNC, rl_end_of_history }, /* Meta-> */ + { ISFUNC, rl_possible_completions }, /* Meta-? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-A */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-B */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-C */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-D */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-E */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-F */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-G */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-H */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-I */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-J */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-K */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-L */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-M */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-N */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-O */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-P */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Q */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-R */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-S */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-T */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-U */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-V */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-W */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-X */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Y */ + { ISFUNC, rl_do_lowercase_version }, /* Meta-Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */ + { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */ + { ISFUNC, rl_yank_last_arg }, /* Meta-_ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */ + { ISFUNC, rl_backward_word }, /* Meta-b */ + { ISFUNC, rl_capitalize_word }, /* Meta-c */ + { ISFUNC, rl_kill_word }, /* Meta-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */ + { ISFUNC, rl_forward_word }, /* Meta-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */ + { ISFUNC, rl_downcase_word }, /* Meta-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */ + { ISFUNC, rl_noninc_forward_search }, /* Meta-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */ + { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */ + { ISFUNC, rl_revert_line }, /* Meta-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */ + { ISFUNC, rl_transpose_words }, /* Meta-t */ + { ISFUNC, rl_upcase_word }, /* Meta-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */ + { ISFUNC, rl_yank_pop }, /* Meta-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */ + { ISFUNC, rl_tilde_expand }, /* Meta-~ */ + { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + +KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = { + + /* Control keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, rl_re_read_init_file }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, rl_undo_command }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, rl_exchange_point_and_mark }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, rl_start_kbd_macro }, /* ( */ + { ISFUNC, rl_end_kbd_macro }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, rl_call_last_kbd_macro }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_line }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; diff --git a/readline-4.3/examples/Inputrc b/readline-4.3/examples/Inputrc new file mode 100644 index 0000000..d7fdb42 --- /dev/null +++ b/readline-4.3/examples/Inputrc @@ -0,0 +1,81 @@ +# My ~/.inputrc file is in -*- text -*- for easy editing with Emacs. +# +# Notice the various bindings which are conditionalized depending +# on which program is running, or what terminal is active. +# + +# Copyright (C) 1989-2002 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 USA. + +# In all programs, all terminals, make sure this is bound. +"\C-x\C-r": re-read-init-file + +# Hp terminals (and some others) have ugly default behaviour for C-h. +"\C-h": backward-delete-char +"\e\C-h": backward-kill-word +"\C-xd": dump-functions + +# In xterm windows, make the arrow keys do the right thing. +$if TERM=xterm +"\e[A": previous-history +"\e[B": next-history +"\e[C": forward-char +"\e[D": backward-char + +# alternate arrow key prefix +"\eOA": previous-history +"\eOB": next-history +"\eOC": forward-char +"\eOD": backward-char + +# Under Xterm in Bash, we bind local Function keys to do something useful. +$if Bash +"\e[11~": "Function Key 1" +"\e[12~": "Function Key 2" +"\e[13~": "Function Key 3" +"\e[14~": "Function Key 4" +"\e[15~": "Function Key 5" + +# I know the following escape sequence numbers are 1 greater than +# the function key. Don't ask me why, I didn't design the xterm terminal. +"\e[17~": "Function Key 6" +"\e[18~": "Function Key 7" +"\e[19~": "Function Key 8" +"\e[20~": "Function Key 9" +"\e[21~": "Function Key 10" +$endif +$endif + +# For Bash, all terminals, add some Bash specific hacks. +$if Bash +"\C-xv": show-bash-version +"\C-x\C-e": shell-expand-line + +# Here is one for editing my path. +"\C-xp": "$PATH\C-x\C-e\C-e\"\C-aPATH=\":\C-b" + +# Make C-x r read my mail in emacs. +# "\C-xr": "emacs -f rmail\C-j" +$endif + +# For FTP, different hacks: +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif + +" ": self-insert diff --git a/readline-4.3/examples/Makefile.in b/readline-4.3/examples/Makefile.in new file mode 100644 index 0000000..72c9904 --- /dev/null +++ b/readline-4.3/examples/Makefile.in @@ -0,0 +1,104 @@ +# +# This is the Makefile for the readline examples subdirectory. +# +# Copyright (C) 1994 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 USA. +RL_LIBRARY_VERSION = @LIBVERSION@ + +SHELL = @MAKE_SHELL@ +RM = rm -f + +srcdir = @srcdir@ +VPATH = .:@srcdir@ +top_srcdir = @top_srcdir@ +BUILD_DIR = . + +# Support an alternate destination root directory for package building +DESTDIR = + +DEFS = @DEFS@ +CC = @CC@ +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DREADLINE_LIBRARY -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I$(srcdir) -I$(top_srcdir) -I.. + +CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS) +LDFLAGS = -g -L.. @LDFLAGS@ + +READLINE_LIB = ../libreadline.a +HISTORY_LIB = ../libhistory.a + +TERMCAP_LIB = @TERMCAP_LIB@ + +.c.o: + ${RM} $@ + $(CC) $(CCFLAGS) -c $< + +EXECUTABLES = fileman rltest rl rlcat rlversion histexamp +OBJECTS = fileman.o rltest.o rl.o rlversion.o histexamp.o + +all: $(EXECUTABLES) +everything: all rlfe + +rl: rl.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rl.o -lreadline $(TERMCAP_LIB) + +rlcat: rlcat.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline $(TERMCAP_LIB) + +fileman: fileman.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ fileman.o -lreadline $(TERMCAP_LIB) + +rltest: rltest.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rltest.o -lreadline $(TERMCAP_LIB) + +rlversion: rlversion.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rlversion.o -lreadline $(TERMCAP_LIB) + +histexamp: histexamp.o $(HISTORY_LIB) + $(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 + +fileman.o: fileman.c +rltest.o: rltest.c +rl.o: rl.c +rlversion.o: rlversion.c +histexamp.o: histexamp.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 diff --git a/readline-4.3/examples/excallback.c b/readline-4.3/examples/excallback.c new file mode 100644 index 0000000..3d4bb18 --- /dev/null +++ b/readline-4.3/examples/excallback.c @@ -0,0 +1,188 @@ +/* +From: Jeff Solomon +Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT) +To: chet@po.cwru.edu +Subject: new readline example +Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU> + +Chet, + +I've been using readline 4.0. Specifically, I've been using the perl +version Term::ReadLine::Gnu. It works great. + +Anyway, I've been playing around the alternate interface and I wanted +to contribute a little C program, callback.c, to you that you could +use as an example of the alternate interface in the /examples +directory of the readline distribution. + +My example shows how, using the alternate interface, you can +interactively change the prompt (which is very nice imo). Also, I +point out that you must roll your own terminal setting when using the +alternate interface because readline depreps (using your parlance) the +terminal while in the user callback. I try to demostrate what I mean +with an example. I've included the program below. + +To compile, I just put the program in the examples directory and made +the appropriate changes to the EXECUTABLES and OBJECTS line and added +an additional target 'callback'. + +I compiled on my Sun Solaris2.6 box using Sun's cc. + +Let me know what you think. + +Jeff +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include /* xxx - should make this more general */ + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +/* This little examples demonstrates the alternate interface to using readline. + * In the alternate interface, the user maintains control over program flow and + * only calls readline when STDIN is readable. Using the alternate interface, + * you can do anything else while still using readline (like talking to a + * network or another program) without blocking. + * + * Specifically, this program highlights two importants features of the + * alternate interface. The first is the ability to interactively change the + * prompt, which can't be done using the regular interface since rl_prompt is + * read-only. + * + * The second feature really highlights a subtle point when using the alternate + * interface. That is, readline will not alter the terminal when inside your + * callback handler. So let's so, your callback executes a user command that + * takes a non-trivial amount of time to complete (seconds). While your + * executing the command, the user continues to type keystrokes and expects them + * to be re-echoed on the new prompt when it returns. Unfortunately, the default + * terminal configuration doesn't do this. After the prompt returns, the user + * must hit one additional keystroke and then will see all of his previous + * keystrokes. To illustrate this, compile and run this program. Type "sleep" at + * the prompt and then type "bar" before the prompt returns (you have 3 + * seconds). Notice how "bar" is re-echoed on the prompt after the prompt + * returns? This is what you expect to happen. Now comment out the 4 lines below + * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do + * the same thing. When the prompt returns, you should not see "bar". Now type + * "f", see how "barf" magically appears? This behavior is un-expected and not + * desired. + */ + +void process_line(char *line); +int change_prompt(void); +char *get_prompt(void); + +int prompt = 1; +char prompt_buf[40], line_buf[256]; +tcflag_t old_lflag; +cc_t old_vtime; +struct termios term; + +int +main() +{ + fd_set fds; + + /* Adjust the terminal slightly before the handler is installed. Disable + * canonical mode processing and set the input character time flag to be + * non-blocking. + */ + if( tcgetattr(STDIN_FILENO, &term) < 0 ) { + perror("tcgetattr"); + exit(1); + } + old_lflag = term.c_lflag; + old_vtime = term.c_cc[VTIME]; + term.c_lflag &= ~ICANON; + term.c_cc[VTIME] = 1; + /* COMMENT LINE BELOW - see above */ + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + + rl_add_defun("change-prompt", change_prompt, CTRL('t')); + rl_callback_handler_install(get_prompt(), process_line); + + while(1) { + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + + if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(1); + } + + if( FD_ISSET(fileno(stdin), &fds) ) { + rl_callback_read_char(); + } + } +} + +void +process_line(char *line) +{ + if( line == NULL ) { + fprintf(stderr, "\n", line); + + /* reset the old terminal setting before exiting */ + term.c_lflag = old_lflag; + term.c_cc[VTIME] = old_vtime; + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + exit(0); + } + + if( strcmp(line, "sleep") == 0 ) { + sleep(3); + } else { + fprintf(stderr, "|%s|\n", line); + } + + free (line); +} + +int +change_prompt(void) +{ + /* toggle the prompt variable */ + prompt = !prompt; + + /* save away the current contents of the line */ + strcpy(line_buf, rl_line_buffer); + + /* install a new handler which will change the prompt and erase the current line */ + rl_callback_handler_install(get_prompt(), process_line); + + /* insert the old text on the new line */ + rl_insert_text(line_buf); + + /* redraw the current line - this is an undocumented function. It invokes the + * redraw-current-line command. + */ + rl_refresh_line(0, 0); +} + +char * +get_prompt(void) +{ + /* The prompts can even be different lengths! */ + sprintf(prompt_buf, "%s", + prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); + return prompt_buf; +} diff --git a/readline-4.3/examples/fileman.c b/readline-4.3/examples/fileman.c new file mode 100644 index 0000000..340eee7 --- /dev/null +++ b/readline-4.3/examples/fileman.c @@ -0,0 +1,485 @@ +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_SYS_FILE_H +# include +#endif +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern char *xmalloc (); + +/* The names of functions that actually do the manipulation. */ +int com_list PARAMS((char *)); +int com_view PARAMS((char *)); +int com_rename PARAMS((char *)); +int com_stat PARAMS((char *)); +int com_pwd PARAMS((char *)); +int com_delete PARAMS((char *)); +int com_help PARAMS((char *)); +int com_cd PARAMS((char *)); +int com_quit PARAMS((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 global means the user is done using this program. */ +int done; + +char * +dupstr (s) + char *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 PARAMS((const char *, int)); +char **fileman_completion PARAMS((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. Return the 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; + +#if defined (__MSDOS__) + /* more.com doesn't grok slashes in pathnames */ + sprintf (syscom, "less %s", arg); +#else + sprintf (syscom, "more %s", arg); +#endif + 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. Write it yourself.\n", + caller); +} + +/* 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); +} diff --git a/readline-4.3/examples/histexamp.c b/readline-4.3/examples/histexamp.c new file mode 100644 index 0000000..45651df --- /dev/null +++ b/readline-4.3/examples/histexamp.c @@ -0,0 +1,112 @@ +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include + +#ifdef READLINE_LIBRARY +# include "history.h" +#else +# include +#endif + +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; + + using_history (); + + 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"); + } + } + } +} diff --git a/readline-4.3/examples/manexamp.c b/readline-4.3/examples/manexamp.c new file mode 100644 index 0000000..9c6cf2c --- /dev/null +++ b/readline-4.3/examples/manexamp.c @@ -0,0 +1,112 @@ +/* manexamp.c -- The examples which appear in the documentation are here. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include +#include + +/* **************************************************************** */ +/* */ +/* How to Emulate gets () */ +/* */ +/* **************************************************************** */ + +/* 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); +} + +/* **************************************************************** */ +/* */ +/* Writing a Function to be Called by Readline. */ +/* */ +/* **************************************************************** */ + +/* Invert the case of the COUNT following characters. */ +invert_case_line (count, key) + int count, key; +{ + register int start, end; + + start = rl_point; + + 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 = -1; + + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + if (start == end) + return; + + /* Tell readline that we are modifying the line, so save the undo + information. */ + rl_modifying (start, end); + + for (; start != end; start += direction) + { + if (_rl_uppercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); + else if (_rl_lowercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); + } + + /* Move point to on top of the last character changed. */ + rl_point = end - direction; +} diff --git a/readline-4.3/examples/readlinebuf.h b/readline-4.3/examples/readlinebuf.h new file mode 100644 index 0000000..91ef4d6 --- /dev/null +++ b/readline-4.3/examples/readlinebuf.h @@ -0,0 +1,139 @@ +/******************************************************************************* + * $Revision$ + * $Date$ + * $Author$ + * + * Contents: A streambuf which uses the GNU readline library for line I/O + * (c) 2001 by Dimitris Vyzovitis [vyzo@media.mit.edu] + * + * 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 + * + ******************************************************************************/ + +#ifndef _READLINEBUF_H_ +#define _READLINEBUF_H_ + +#include +#include +#include +#include +#include + +#include +#include + +#if (defined __GNUC__) && (__GNUC__ < 3) +#include +#else +#include +using std::streamsize; +using std::streambuf; +#endif + +class readlinebuf : public streambuf { +public: +#if (defined __GNUC__) && (__GNUC__ < 3) + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; +#endif + static const int_type eof = EOF; // this is -1 + static const int_type not_eof = 0; + +private: + const char* prompt_; + bool history_; + char* line_; + int low_; + int high_; + +protected: + + virtual int_type showmanyc() const { return high_ - low_; } + + virtual streamsize xsgetn( char_type* buf, streamsize n ) { + int rd = n > (high_ - low_)? (high_ - low_) : n; + memcpy( buf, line_, rd ); + low_ += rd; + + if ( rd < n ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + rd += xsgetn( buf + rd, n - rd ); + } + } + + return rd; + } + + virtual int_type underflow() { + if ( high_ == low_ ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + } + } + + if ( low_ < high_ ) return line_[low_]; + else return eof; + } + + virtual int_type uflow() { + int_type c = underflow(); + if ( c != eof ) ++low_; + return c; + } + + virtual int_type pbackfail( int_type c = eof ) { + if ( low_ > 0 ) --low_; + else if ( c != eof ) { + if ( high_ > 0 ) { + char* nl = (char*)realloc( line_, high_ + 1 ); + if ( nl ) { + line_ = (char*)memcpy( nl + 1, line_, high_ ); + high_ += 1; + line_[0] = char( c ); + } else return eof; + } else { + assert( !line_ ); + line_ = (char*)malloc( sizeof( char ) ); + *line_ = char( c ); + high_ = 1; + } + } else return eof; + + return not_eof; + } + +public: + readlinebuf( const char* prompt = NULL, bool history = true ) + : prompt_( prompt ), history_( history ), + line_( NULL ), low_( 0 ), high_( 0 ) { + setbuf( 0, 0 ); + } + + +}; + +#endif diff --git a/readline-4.3/examples/rl.c b/readline-4.3/examples/rl.c new file mode 100644 index 0000000..d260489 --- /dev/null +++ b/readline-4.3/examples/rl.c @@ -0,0 +1,151 @@ +/* + * rl - command-line interface to read a line from the standard input + * (or another fd) using readline. + * + * usage: rl [-p prompt] [-u unit] [-d default] [-n nchars] + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixstat.h" + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +#if !defined (strchr) && !defined (__STDC__) +extern char *strrchr(); +#endif + +static char *progname; +static char *deftext; + +static int +set_deftext () +{ + if (deftext) + { + rl_insert_text (deftext); + deftext = (char *)NULL; + rl_startup_hook = (rl_hook_func_t *)NULL; + } + return 0; +} + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n", + progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp, *prompt; + struct stat sb; + int opt, fd, nch; + FILE *ifp; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + /* defaults */ + prompt = "readline$ "; + fd = nch = 0; + deftext = (char *)0; + + while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF) + { + switch (opt) + { + case 'p': + prompt = optarg; + break; + case 'u': + fd = atoi(optarg); + if (fd < 0) + { + fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg); + exit (2); + } + break; + case 'd': + deftext = optarg; + break; + case 'n': + nch = atoi(optarg); + if (nch < 0) + { + fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg); + exit (2); + } + break; + default: + usage (); + exit (2); + } + } + + if (fd != 0) + { + if (fstat (fd, &sb) < 0) + { + fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd); + exit (1); + } + ifp = fdopen (fd, "r"); + rl_instream = ifp; + } + + if (deftext && *deftext) + rl_startup_hook = set_deftext; + + if (nch > 0) + rl_num_chars_to_read = nch; + + temp = readline (prompt); + + /* Test for EOF. */ + if (temp == 0) + exit (1); + + printf ("%s\n", temp); + exit (0); +} diff --git a/readline-4.3/examples/rlcat.c b/readline-4.3/examples/rlcat.c new file mode 100644 index 0000000..176b9f4 --- /dev/null +++ b/readline-4.3/examples/rlcat.c @@ -0,0 +1,174 @@ +/* + * rlcat - cat(1) using readline + * + * usage: rlcat + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include "posixstat.h" + +#include +#include +#include +#include + +#ifndef errno +extern int errno; +#endif + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +static int stdcat(); + +static char *progname; +static int vflag; + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp; + int opt, Vflag, Nflag; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + vflag = Vflag = Nflag = 0; + while ((opt = getopt(argc, argv, "vEVN")) != EOF) + { + switch (opt) + { + case 'v': + vflag = 1; + break; + case 'V': + Vflag = 1; + break; + case 'E': + Vflag = 0; + break; + case 'N': + Nflag = 1; + break; + default: + usage (); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (isatty(0) == 0 || argc || Nflag) + return stdcat(argc, argv); + + rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs"); + while (temp = readline ("")) + { + if (*temp) + add_history (temp); + printf ("%s\n", temp); + } + + return (ferror (stdout)); +} + +static int +fcopy(fp) + FILE *fp; +{ + int c; + char *x; + + while ((c = getc(fp)) != EOF) + { + if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0) + { + x = rl_untranslate_keyseq (c); + if (fputs (x, stdout) != 0) + return 1; + } + else if (putchar (c) == EOF) + return 1; + } + return (ferror (stdout)); +} + +int +stdcat (argc, argv) + int argc; + char **argv; +{ + int i, fd, r; + char *s; + FILE *fp; + + if (argc == 0) + return (fcopy(stdin)); + + for (i = 0, r = 1; i < argc; i++) + { + if (*argv[i] == '-' && argv[i][1] == 0) + fp = stdin; + else + { + fp = fopen (argv[i], "r"); + if (fp == 0) + { + fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno)); + continue; + } + } + r = fcopy (fp); + if (fp != stdin) + fclose(fp); + } + return r; +} diff --git a/readline-4.3/examples/rlfe.c b/readline-4.3/examples/rlfe.c new file mode 100644 index 0000000..d634d7c --- /dev/null +++ b/readline-4.3/examples/rlfe.c @@ -0,0 +1,1042 @@ +/* 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#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-4.3/examples/rltest.c b/readline-4.3/examples/rltest.c new file mode 100644 index 0000000..99f083b --- /dev/null +++ b/readline-4.3/examples/rltest.c @@ -0,0 +1,87 @@ +/* **************************************************************** */ +/* */ +/* Testing Readline */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern HIST_ENTRY **history_list (); + +main () +{ + char *temp, *prompt; + int done; + + temp = (char *)NULL; + prompt = "readline$ "; + done = 0; + + while (!done) + { + temp = readline (prompt); + + /* Test for EOF. */ + if (!temp) + exit (1); + + /* If there is anything on the line, print it and remember it. */ + if (*temp) + { + fprintf (stderr, "%s\r\n", temp); + add_history (temp); + } + + /* Check for `command' that we handle. */ + if (strcmp (temp, "quit") == 0) + done = 1; + + if (strcmp (temp, "list") == 0) + { + HIST_ENTRY **list; + register int i; + + list = history_list (); + if (list) + { + for (i = 0; list[i]; i++) + fprintf (stderr, "%d: %s\r\n", i, list[i]->line); + } + } + free (temp); + } + exit (0); +} diff --git a/readline-4.3/examples/rlversion.c b/readline-4.3/examples/rlversion.c new file mode 100644 index 0000000..53949d1 --- /dev/null +++ b/readline-4.3/examples/rlversion.c @@ -0,0 +1,43 @@ +/* + * rlversion -- print out readline's version number + */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixstat.h" + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +main() +{ + printf ("%s\n", rl_library_version ? rl_library_version : "unknown"); + exit (0); +} diff --git a/readline-4.3/funmap.c b/readline-4.3/funmap.c new file mode 100644 index 0000000..fe9a1da --- /dev/null +++ b/readline-4.3/funmap.c @@ -0,0 +1,253 @@ +/* funmap.c -- attach names to functions. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if !defined (BUFSIZ) +#include +#endif /* BUFSIZ */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "rlconf.h" +#include "readline.h" + +#include "xmalloc.h" + +#ifdef __STDC__ +typedef int QSFUNC (const void *, const void *); +#else +typedef int QSFUNC (); +#endif + +extern int _rl_qsort_string_compare PARAMS((char **, char **)); + +FUNMAP **funmap; +static int funmap_size; +static int funmap_entry; + +/* After initializing the function map, this is the index of the first + program specific function. */ +int funmap_program_specific_entry_start; + +static FUNMAP default_funmap[] = { + { "abort", rl_abort }, + { "accept-line", rl_newline }, + { "arrow-key-prefix", rl_arrow_keys }, + { "backward-byte", rl_backward_byte }, + { "backward-char", rl_backward_char }, + { "backward-delete-char", rl_rubout }, + { "backward-kill-line", rl_backward_kill_line }, + { "backward-kill-word", rl_backward_kill_word }, + { "backward-word", rl_backward_word }, + { "beginning-of-history", rl_beginning_of_history }, + { "beginning-of-line", rl_beg_of_line }, + { "call-last-kbd-macro", rl_call_last_kbd_macro }, + { "capitalize-word", rl_capitalize_word }, + { "character-search", rl_char_search }, + { "character-search-backward", rl_backward_char_search }, + { "clear-screen", rl_clear_screen }, + { "complete", rl_complete }, + { "copy-backward-word", rl_copy_backward_word }, + { "copy-forward-word", rl_copy_forward_word }, + { "copy-region-as-kill", rl_copy_region_to_kill }, + { "delete-char", rl_delete }, + { "delete-char-or-list", rl_delete_or_show_completions }, + { "delete-horizontal-space", rl_delete_horizontal_space }, + { "digit-argument", rl_digit_argument }, + { "do-lowercase-version", rl_do_lowercase_version }, + { "downcase-word", rl_downcase_word }, + { "dump-functions", rl_dump_functions }, + { "dump-macros", rl_dump_macros }, + { "dump-variables", rl_dump_variables }, + { "emacs-editing-mode", rl_emacs_editing_mode }, + { "end-kbd-macro", rl_end_kbd_macro }, + { "end-of-history", rl_end_of_history }, + { "end-of-line", rl_end_of_line }, + { "exchange-point-and-mark", rl_exchange_point_and_mark }, + { "forward-backward-delete-char", rl_rubout_or_delete }, + { "forward-byte", rl_forward_byte }, + { "forward-char", rl_forward_char }, + { "forward-search-history", rl_forward_search_history }, + { "forward-word", rl_forward_word }, + { "history-search-backward", rl_history_search_backward }, + { "history-search-forward", rl_history_search_forward }, + { "insert-comment", rl_insert_comment }, + { "insert-completions", rl_insert_completions }, + { "kill-whole-line", rl_kill_full_line }, + { "kill-line", rl_kill_line }, + { "kill-region", rl_kill_region }, + { "kill-word", rl_kill_word }, + { "menu-complete", rl_menu_complete }, + { "next-history", rl_get_next_history }, + { "non-incremental-forward-search-history", rl_noninc_forward_search }, + { "non-incremental-reverse-search-history", rl_noninc_reverse_search }, + { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, + { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, + { "overwrite-mode", rl_overwrite_mode }, +#ifdef __CYGWIN__ + { "paste-from-clipboard", rl_paste_from_clipboard }, +#endif + { "possible-completions", rl_possible_completions }, + { "previous-history", rl_get_previous_history }, + { "quoted-insert", rl_quoted_insert }, + { "re-read-init-file", rl_re_read_init_file }, + { "redraw-current-line", rl_refresh_line}, + { "reverse-search-history", rl_reverse_search_history }, + { "revert-line", rl_revert_line }, + { "self-insert", rl_insert }, + { "set-mark", rl_set_mark }, + { "start-kbd-macro", rl_start_kbd_macro }, + { "tab-insert", rl_tab_insert }, + { "tilde-expand", rl_tilde_expand }, + { "transpose-chars", rl_transpose_chars }, + { "transpose-words", rl_transpose_words }, + { "tty-status", rl_tty_status }, + { "undo", rl_undo_command }, + { "universal-argument", rl_universal_argument }, + { "unix-line-discard", rl_unix_line_discard }, + { "unix-word-rubout", rl_unix_word_rubout }, + { "upcase-word", rl_upcase_word }, + { "yank", rl_yank }, + { "yank-last-arg", rl_yank_last_arg }, + { "yank-nth-arg", rl_yank_nth_arg }, + { "yank-pop", rl_yank_pop }, + +#if defined (VI_MODE) + { "vi-append-eol", rl_vi_append_eol }, + { "vi-append-mode", rl_vi_append_mode }, + { "vi-arg-digit", rl_vi_arg_digit }, + { "vi-back-to-indent", rl_vi_back_to_indent }, + { "vi-bWord", rl_vi_bWord }, + { "vi-bword", rl_vi_bword }, + { "vi-change-case", rl_vi_change_case }, + { "vi-change-char", rl_vi_change_char }, + { "vi-change-to", rl_vi_change_to }, + { "vi-char-search", rl_vi_char_search }, + { "vi-column", rl_vi_column }, + { "vi-complete", rl_vi_complete }, + { "vi-delete", rl_vi_delete }, + { "vi-delete-to", rl_vi_delete_to }, + { "vi-eWord", rl_vi_eWord }, + { "vi-editing-mode", rl_vi_editing_mode }, + { "vi-end-word", rl_vi_end_word }, + { "vi-eof-maybe", rl_vi_eof_maybe }, + { "vi-eword", rl_vi_eword }, + { "vi-fWord", rl_vi_fWord }, + { "vi-fetch-history", rl_vi_fetch_history }, + { "vi-first-print", rl_vi_first_print }, + { "vi-fword", rl_vi_fword }, + { "vi-goto-mark", rl_vi_goto_mark }, + { "vi-insert-beg", rl_vi_insert_beg }, + { "vi-insertion-mode", rl_vi_insertion_mode }, + { "vi-match", rl_vi_match }, + { "vi-movement-mode", rl_vi_movement_mode }, + { "vi-next-word", rl_vi_next_word }, + { "vi-overstrike", rl_vi_overstrike }, + { "vi-overstrike-delete", rl_vi_overstrike_delete }, + { "vi-prev-word", rl_vi_prev_word }, + { "vi-put", rl_vi_put }, + { "vi-redo", rl_vi_redo }, + { "vi-replace", rl_vi_replace }, + { "vi-search", rl_vi_search }, + { "vi-search-again", rl_vi_search_again }, + { "vi-set-mark", rl_vi_set_mark }, + { "vi-subst", rl_vi_subst }, + { "vi-tilde-expand", rl_vi_tilde_expand }, + { "vi-yank-arg", rl_vi_yank_arg }, + { "vi-yank-to", rl_vi_yank_to }, +#endif /* VI_MODE */ + + {(char *)NULL, (rl_command_func_t *)NULL } +}; + +int +rl_add_funmap_entry (name, function) + const char *name; + rl_command_func_t *function; +{ + if (funmap_entry + 2 >= funmap_size) + { + funmap_size += 64; + funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *)); + } + + funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP)); + funmap[funmap_entry]->name = name; + funmap[funmap_entry]->function = function; + + funmap[++funmap_entry] = (FUNMAP *)NULL; + return funmap_entry; +} + +static int funmap_initialized; + +/* Make the funmap contain all of the default entries. */ +void +rl_initialize_funmap () +{ + register int i; + + if (funmap_initialized) + return; + + for (i = 0; default_funmap[i].name; i++) + rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function); + + funmap_initialized = 1; + funmap_program_specific_entry_start = i; +} + +/* Produce a NULL terminated array of known function names. The array + is sorted. The array itself is allocated, but not the strings inside. + You should free () the array when you done, but not the pointrs. */ +const char ** +rl_funmap_names () +{ + const char **result; + int result_size, result_index; + + /* Make sure that the function map has been initialized. */ + rl_initialize_funmap (); + + for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++) + { + if (result_index + 2 > result_size) + { + result_size += 20; + result = (const char **)xrealloc (result, result_size * sizeof (char *)); + } + + result[result_index] = funmap[result_index]->name; + result[result_index + 1] = (char *)NULL; + } + + qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + return (result); +} diff --git a/readline-4.3/histexpand.c b/readline-4.3/histexpand.c new file mode 100644 index 0000000..6c81196 --- /dev/null +++ b/readline-4.3/histexpand.c @@ -0,0 +1,1491 @@ +/* histexpand.c -- history expansion. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifndef _MINIX +# include +# endif +# include +#endif + +#include "rlmbutil.h" + +#include "history.h" +#include "histlib.h" + +#include "rlshell.h" +#include "xmalloc.h" + +#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" +#define HISTORY_QUOTE_CHARACTERS "\"'`" + +typedef int _hist_search_func_t PARAMS((const char *, int)); + +extern int rl_byte_oriented; /* declared in mbutil.c */ + +static char error_pointer; + +static char *subst_lhs; +static char *subst_rhs; +static int subst_lhs_len; +static int subst_rhs_len; + +static char *get_history_word_specifier PARAMS((char *, char *, int *)); +static char *history_find_word PARAMS((char *, int)); + +static char *quote_breaks PARAMS((char *)); + +/* Variables exported by this file. */ +/* The character that represents the start of a history expansion + request. This is usually `!'. */ +char history_expansion_char = '!'; + +/* The character that invokes word substitution if found at the start of + a line. This is usually `^'. */ +char history_subst_char = '^'; + +/* During tokenization, if this character is seen as the first character + of a word, then it, and all subsequent characters upto a newline are + ignored. For a Bourne shell, this should be '#'. Bash special cases + the interactive comment character to not be a comment delimiter. */ +char history_comment_char = '\0'; + +/* The list of characters which inhibit the expansion of text if found + immediately following history_expansion_char. */ +char *history_no_expand_chars = " \t\n\r="; + +/* If set to a non-zero value, single quotes inhibit history expansion. + The default is 0. */ +int history_quotes_inhibit_expansion = 0; + +/* Used to split words by history_tokenize_internal. */ +char *history_word_delimiters = HISTORY_WORD_DELIMITERS; + +/* If set, this points to a function that is called to verify that a + particular history expansion should be performed. */ +rl_linebuf_func_t *history_inhibit_expansion_function; + +/* **************************************************************** */ +/* */ +/* History Expansion */ +/* */ +/* **************************************************************** */ + +/* Hairy history expansion on text, not tokens. This is of general + use, and thus belongs in this library. */ + +/* The last string searched for by a !?string? search. */ +static char *search_string; + +/* The last string matched by a !?string? search. */ +static char *search_match; + +/* Return the event specified at TEXT + OFFSET modifying OFFSET to + point to after the event specifier. Just a pointer to the history + line is returned; NULL is returned in the event of a bad specifier. + You pass STRING with *INDEX equal to the history_expansion_char that + begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. + So you might call this function like: + line = get_history_event ("!echo:p", &index, 0); */ +char * +get_history_event (string, caller_index, delimiting_quote) + const char *string; + int *caller_index; + int delimiting_quote; +{ + register int i; + register char c; + HIST_ENTRY *entry; + int which, sign, local_index, substring_okay; + _hist_search_func_t *search_func; + char *temp; + + /* The event can be specified in a number of ways. + + !! the previous command + !n command line N + !-n current command-line minus N + !str the most recent command starting with STR + !?str[?] + the most recent command containing STR + + All values N are determined via HISTORY_BASE. */ + + i = *caller_index; + + if (string[i] != history_expansion_char) + return ((char *)NULL); + + /* Move on to the specification. */ + i++; + + sign = 1; + substring_okay = 0; + +#define RETURN_ENTRY(e, w) \ + return ((e = history_get (w)) ? e->line : (char *)NULL) + + /* Handle !! case. */ + if (string[i] == history_expansion_char) + { + i++; + which = history_base + (history_length - 1); + *caller_index = i; + RETURN_ENTRY (entry, which); + } + + /* Hack case of numeric line specification. */ + if (string[i] == '-') + { + sign = -1; + i++; + } + + if (_rl_digit_p (string[i])) + { + /* Get the extent of the digits and compute the value. */ + for (which = 0; _rl_digit_p (string[i]); i++) + which = (which * 10) + _rl_digit_value (string[i]); + + *caller_index = i; + + if (sign < 0) + which = (history_length + history_base) - which; + + RETURN_ENTRY (entry, which); + } + + /* This must be something to search for. If the spec begins with + a '?', then the string may be anywhere on the line. Otherwise, + the string must be found at the start of a line. */ + if (string[i] == '?') + { + substring_okay++; + i++; + } + + /* 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; + + 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)) || + string[i] == delimiting_quote)) || + string[i] == '\n' || + (substring_okay && string[i] == '?')) + break; + + which = i - local_index; + temp = (char *)xmalloc (1 + which); + if (which) + strncpy (temp, string + local_index, which); + temp[which] = '\0'; + + if (substring_okay && string[i] == '?') + i++; + + *caller_index = i; + +#define FAIL_SEARCH() \ + do { \ + history_offset = history_length; free (temp) ; return (char *)NULL; \ + } while (0) + + /* If there is no search string, try to use the previous search string, + if one exists. If not, fail immediately. */ + if (*temp == '\0' && substring_okay) + { + if (search_string) + { + free (temp); + temp = savestring (search_string); + } + else + FAIL_SEARCH (); + } + + search_func = substring_okay ? history_search : history_search_prefix; + while (1) + { + local_index = (*search_func) (temp, -1); + + if (local_index < 0) + FAIL_SEARCH (); + + if (local_index == 0 || substring_okay) + { + entry = current_history (); + history_offset = history_length; + + /* If this was a substring search, then remember the + string that we matched for word substitution. */ + if (substring_okay) + { + FREE (search_string); + search_string = temp; + + FREE (search_match); + search_match = history_find_word (entry->line, local_index); + } + else + free (temp); + + return (entry->line); + } + + if (history_offset) + history_offset--; + else + FAIL_SEARCH (); + } +#undef FAIL_SEARCH +#undef RETURN_ENTRY +} + +/* Function for extracting single-quoted strings. Used for inhibiting + history expansion within single quotes. */ + +/* Extract the contents of STRING as if it is enclosed in single quotes. + SINDEX, when passed in, is the offset of the character immediately + following the opening single quote; on exit, SINDEX is left pointing + to the closing single quote. */ +static void +hist_string_extract_single_quoted (string, sindex) + char *string; + int *sindex; +{ + register int i; + + for (i = *sindex; string[i] && string[i] != '\''; i++) + ; + + *sindex = i; +} + +static char * +quote_breaks (s) + char *s; +{ + register char *p, *r; + char *ret; + int len = 3; + + for (p = s; p && *p; p++, len++) + { + if (*p == '\'') + len += 3; + else if (whitespace (*p) || *p == '\n') + len += 2; + } + + r = ret = (char *)xmalloc (len); + *r++ = '\''; + for (p = s; p && *p; ) + { + if (*p == '\'') + { + *r++ = '\''; + *r++ = '\\'; + *r++ = '\''; + *r++ = '\''; + p++; + } + else if (whitespace (*p) || *p == '\n') + { + *r++ = '\''; + *r++ = *p++; + *r++ = '\''; + } + else + *r++ = *p++; + } + *r++ = '\''; + *r = '\0'; + return ret; +} + +static char * +hist_error(s, start, current, errtype) + char *s; + int start, current, errtype; +{ + char *temp; + const char *emsg; + int ll, elen; + + ll = current - start; + + switch (errtype) + { + case EVENT_NOT_FOUND: + emsg = "event not found"; + elen = 15; + break; + case BAD_WORD_SPEC: + emsg = "bad word specifier"; + elen = 18; + break; + case SUBST_FAILED: + emsg = "substitution failed"; + elen = 19; + break; + case BAD_MODIFIER: + emsg = "unrecognized history modifier"; + elen = 29; + break; + case NO_PREV_SUBST: + emsg = "no previous substitution"; + elen = 24; + break; + default: + emsg = "unknown expansion error"; + elen = 23; + break; + } + + temp = (char *)xmalloc (ll + elen + 3); + strncpy (temp, s + start, ll); + temp[ll] = ':'; + temp[ll + 1] = ' '; + strcpy (temp + ll + 2, emsg); + return (temp); +} + +/* Get a history substitution string from STR starting at *IPTR + and return it. The length is returned in LENPTR. + + A backslash can quote the delimiter. If the string is the + empty string, the previous pattern is used. If there is + no previous pattern for the lhs, the last history search + string is used. + + If IS_RHS is 1, we ignore empty strings and set the pattern + to "" anyway. subst_lhs is not changed if the lhs is empty; + subst_rhs is allowed to be set to the empty string. */ + +static char * +get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) + char *str; + int *iptr, delimiter, is_rhs, *lenptr; +{ + register int si, i, j, k; + char *s; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; +#endif + + s = (char *)NULL; + i = *iptr; + +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); + _rl_adjust_point (str, i, &ps); +#endif + + for (si = i; str[si] && str[si] != delimiter; si++) +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + if ((v = _rl_get_char_len (str + si, &ps)) > 1) + si += v - 1; + else if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + } + else +#endif /* HANDLE_MULTIBYTE */ + if (str[si] == '\\' && str[si + 1] == delimiter) + si++; + + if (si > i || is_rhs) + { + s = (char *)xmalloc (si - i + 1); + for (j = 0, k = i; k < si; j++, k++) + { + /* Remove a backslash quoting the search string delimiter. */ + if (str[k] == '\\' && str[k + 1] == delimiter) + k++; + s[j] = str[k]; + } + s[j] = '\0'; + if (lenptr) + *lenptr = j; + } + + i = si; + if (str[i]) + i++; + *iptr = i; + + return s; +} + +static void +postproc_subst_rhs () +{ + char *new; + int i, j, new_size; + + new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len); + for (i = j = 0; i < subst_rhs_len; i++) + { + if (subst_rhs[i] == '&') + { + if (j + subst_lhs_len >= new_size) + new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); + strcpy (new + j, subst_lhs); + j += subst_lhs_len; + } + else + { + /* a single backslash protects the `&' from lhs interpolation */ + if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') + i++; + if (j >= new_size) + new = (char *)xrealloc (new, new_size *= 2); + new[j++] = subst_rhs[i]; + } + } + new[j] = '\0'; + free (subst_rhs); + subst_rhs = new; + subst_rhs_len = j; +} + +/* Expand the bulk of a history specifier starting at STRING[START]. + Returns 0 if everything is OK, -1 if an error occurred, and 1 + if the `p' modifier was supplied and the caller should just print + the returned string. Returns the new index into string in + *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ +static int +history_expand_internal (string, start, end_index_ptr, ret_string, current_line) + char *string; + int start, *end_index_ptr; + char **ret_string; + char *current_line; /* for !# */ +{ + int i, n, starting_index; + int substitute_globally, want_quotes, print_only; + char *event, *temp, *result, *tstr, *t, c, *word_spec; + int result_len; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + result = (char *)xmalloc (result_len = 128); + + i = start; + + /* If it is followed by something that starts a word specifier, + then !! is implied as the event specifier. */ + + if (member (string[i + 1], ":$*%^")) + { + char fake_s[3]; + int fake_i = 0; + i++; + fake_s[0] = fake_s[1] = history_expansion_char; + fake_s[2] = '\0'; + event = get_history_event (fake_s, &fake_i, 0); + } + else if (string[i + 1] == '#') + { + i += 2; + event = current_line; + } + else + { + int quoted_search_delimiter = 0; + + /* If the character before this `!' is a double or single + quote, then this expansion takes place inside of the + quoted string. If we have to search for some text ("!foo"), + allow the delimiter to end the search string. */ +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int c, l; + l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY); + c = string[l]; + /* XXX - original patch had i - 1 ??? If i == 0 it would fail. */ + if (i && (c == '\'' || c == '"')) + quoted_search_delimiter = c; + } + else +#endif /* HANDLE_MULTIBYTE */ + if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) + quoted_search_delimiter = string[i - 1]; + + event = get_history_event (string, &i, quoted_search_delimiter); + } + + if (event == 0) + { + *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); + free (result); + return (-1); + } + + /* If a word specifier is found, then do what that requires. */ + starting_index = i; + word_spec = get_history_word_specifier (string, event, &i); + + /* There is no such thing as a `malformed word specifier'. However, + it is possible for a specifier that has no match. In that case, + we complain. */ + if (word_spec == (char *)&error_pointer) + { + *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC); + free (result); + return (-1); + } + + /* If no word specifier, than the thing of interest was the event. */ + temp = word_spec ? savestring (word_spec) : savestring (event); + FREE (word_spec); + + /* Perhaps there are other modifiers involved. Do what they say. */ + want_quotes = substitute_globally = print_only = 0; + starting_index = i; + + while (string[i] == ':') + { + c = string[i + 1]; + + if (c == 'g') + { + substitute_globally = 1; + i++; + c = string[i + 1]; + } + + switch (c) + { + default: + *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER); + free (result); + free (temp); + return -1; + + case 'q': + want_quotes = 'q'; + break; + + case 'x': + want_quotes = 'x'; + break; + + /* :p means make this the last executed line. So we + return an error state after adding this line to the + history. */ + case 'p': + print_only++; + break; + + /* :t discards all but the last part of the pathname. */ + case 't': + tstr = strrchr (temp, '/'); + if (tstr) + { + tstr++; + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :h discards the last part of a pathname. */ + case 'h': + tstr = strrchr (temp, '/'); + if (tstr) + *tstr = '\0'; + break; + + /* :r discards the suffix. */ + case 'r': + tstr = strrchr (temp, '.'); + if (tstr) + *tstr = '\0'; + break; + + /* :e discards everything but the suffix. */ + case 'e': + tstr = strrchr (temp, '.'); + if (tstr) + { + t = savestring (tstr); + free (temp); + temp = t; + } + break; + + /* :s/this/that substitutes `that' for the first + occurrence of `this'. :gs/this/that substitutes `that' + for each occurrence of `this'. :& repeats the last + substitution. :g& repeats the last substitution + globally. */ + + case '&': + case 's': + { + char *new_event; + int delimiter, failed, si, l_temp; + + if (c == 's') + { + if (i + 2 < (int)strlen (string)) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + _rl_adjust_point (string, i + 2, &ps); + if (_rl_get_char_len (string + i + 2, &ps) > 1) + delimiter = 0; + else + delimiter = string[i + 2]; + } + else +#endif /* HANDLE_MULTIBYTE */ + delimiter = string[i + 2]; + } + else + break; /* no search delimiter */ + + i += 3; + + t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len); + /* An empty substitution lhs with no previous substitution + uses the last search string as the lhs. */ + if (t) + { + FREE (subst_lhs); + subst_lhs = t; + } + else if (!subst_lhs) + { + if (search_string && *search_string) + { + subst_lhs = savestring (search_string); + subst_lhs_len = strlen (subst_lhs); + } + else + { + subst_lhs = (char *) NULL; + subst_lhs_len = 0; + } + } + + FREE (subst_rhs); + subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len); + + /* If `&' appears in the rhs, it's supposed to be replaced + with the lhs. */ + if (member ('&', subst_rhs)) + postproc_subst_rhs (); + } + else + i += 2; + + /* If there is no lhs, the substitution can't succeed. */ + if (subst_lhs_len == 0) + { + *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST); + free (result); + free (temp); + return -1; + } + + l_temp = strlen (temp); + /* Ignore impossible cases. */ + if (subst_lhs_len > l_temp) + { + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + + /* Find the first occurrence of THIS in TEMP. */ + si = 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; + } + + if (substitute_globally > 1) + { + substitute_globally = 0; + continue; /* don't want to increment i */ + } + + if (failed == 0) + continue; /* don't want to increment i */ + + *ret_string = hist_error (string, starting_index, i, SUBST_FAILED); + free (result); + free (temp); + return (-1); + } + } + i += 2; + } + /* Done with modfiers. */ + /* Believe it or not, we have to back the pointer up by one. */ + --i; + + if (want_quotes) + { + char *x; + + if (want_quotes == 'q') + x = sh_single_quote (temp); + else if (want_quotes == 'x') + x = quote_breaks (temp); + else + x = savestring (temp); + + free (temp); + temp = x; + } + + n = strlen (temp); + if (n >= result_len) + result = (char *)xrealloc (result, n + 2); + strcpy (result, temp); + free (temp); + + *end_index_ptr = i; + *ret_string = result; + return (print_only); +} + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + -1) If there was an error in expansion. + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + 2) If the `p' modifier was given and the caller should print the result + + If an error ocurred in expansion, then OUTPUT contains a descriptive + error message. */ + +#define ADD_STRING(s) \ + do \ + { \ + int sl = strlen (s); \ + j += sl; \ + if (j >= result_len) \ + { \ + while (j >= result_len) \ + result_len += 128; \ + result = (char *)xrealloc (result, result_len); \ + } \ + strcpy (result + j - sl, s); \ + } \ + while (0) + +#define ADD_CHAR(c) \ + do \ + { \ + if (j >= result_len - 1) \ + result = (char *)xrealloc (result, result_len += 64); \ + result[j++] = c; \ + result[j] = '\0'; \ + } \ + while (0) + +int +history_expand (hstring, output) + char *hstring; + char **output; +{ + register int j; + int i, r, l, passc, cc, modified, eindex, only_printing; + char *string; + + /* The output string, and its length. */ + int result_len; + char *result; + +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; + mbstate_t ps; +#endif + + /* Used when adding the string. */ + char *temp; + + if (output == 0) + return 0; + + /* Setting the history expansion character to 0 inhibits all + history expansion. */ + if (history_expansion_char == 0) + { + *output = savestring (hstring); + return (0); + } + + /* Prepare the buffer for printing error messages. */ + result = (char *)xmalloc (result_len = 256); + result[0] = '\0'; + + only_printing = modified = 0; + l = strlen (hstring); + + /* Grovel the string. Only backslash and single quotes can quote the + history escape character. We also handle arg specifiers. */ + + /* Before we grovel forever, see if the history_expansion_char appears + anywhere within the text. */ + + /* The quick substitution character is a history expansion all right. That + is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact, + that is the substitution that we do. */ + if (hstring[0] == history_subst_char) + { + string = (char *)xmalloc (l + 5); + + string[0] = string[1] = history_expansion_char; + string[2] = ':'; + string[3] = 's'; + strcpy (string + 4, hstring); + l += 4; + } + else + { +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + string = hstring; + /* If not quick substitution, still maybe have to do expansion. */ + + /* `!' followed by one of the characters in history_no_expand_chars + is NOT an expansion. */ + for (i = 0; string[i]; i++) + { +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int v; + v = _rl_get_char_len (string + i, &ps); + if (v > 1) + { + i += v - 1; + continue; + } + } +#endif /* HANDLE_MULTIBYTE */ + + cc = string[i + 1]; + /* The history_comment_char, if set, appearing at the beginning + of a word signifies that the rest of the line should not have + history expansion performed on it. + Skip the rest of the line and break out of the loop. */ + if (history_comment_char && string[i] == history_comment_char && + (i == 0 || member (string[i - 1], history_word_delimiters))) + { + while (string[i]) + i++; + break; + } + else if (string[i] == history_expansion_char) + { + if (!cc || member (cc, history_no_expand_chars)) + continue; + /* If the calling application has set + history_inhibit_expansion_function to a function that checks + for special cases that should not be history expanded, + call the function and skip the expansion if it returns a + non-zero value. */ + else if (history_inhibit_expansion_function && + (*history_inhibit_expansion_function) (string, i)) + continue; + 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] == '\'') + { + /* If this is bash, single quotes inhibit history expansion. */ + i++; + hist_string_extract_single_quoted (string, &i); + } + else if (history_quotes_inhibit_expansion && string[i] == '\\') + { + /* If this is bash, allow backslashes to quote single + quotes and the history expansion character. */ + if (cc == '\'' || cc == history_expansion_char) + i++; + } + } + + if (string[i] != history_expansion_char) + { + free (result); + *output = savestring (string); + return (0); + } + } + + /* Extract and perform the substitution. */ + for (passc = i = j = 0; i < l; i++) + { + int tchar = string[i]; + + if (passc) + { + passc = 0; + ADD_CHAR (tchar); + continue; + } + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + int k, c; + + c = tchar; + memset (mb, 0, sizeof (mb)); + for (k = 0; k < MB_LEN_MAX; k++) + { + mb[k] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_get_char_len (mb, &ps) == -2) + c = string[++i]; + else + break; + } + if (strlen (mb) > 1) + { + ADD_STRING (mb); + break; + } + } +#endif /* HANDLE_MULTIBYTE */ + + if (tchar == history_expansion_char) + tchar = -3; + else if (tchar == history_comment_char) + tchar = -2; + + switch (tchar) + { + default: + ADD_CHAR (string[i]); + break; + + case '\\': + passc++; + ADD_CHAR (tchar); + break; + + case '\'': + { + /* If history_quotes_inhibit_expansion is set, single quotes + inhibit history expansion. */ + if (history_quotes_inhibit_expansion) + { + int quote, slen; + + quote = i++; + hist_string_extract_single_quoted (string, &i); + + slen = i - quote + 2; + temp = (char *)xmalloc (slen); + strncpy (temp, string + quote, slen); + temp[slen - 1] = '\0'; + ADD_STRING (temp); + free (temp); + } + else + ADD_CHAR (string[i]); + break; + } + + case -2: /* history_comment_char */ + if (i == 0 || member (string[i - 1], history_word_delimiters)) + { + temp = (char *)xmalloc (l - i + 1); + strcpy (temp, string + i); + ADD_STRING (temp); + free (temp); + i = l; + } + else + ADD_CHAR (string[i]); + break; + + case -3: /* history_expansion_char */ + cc = string[i + 1]; + + /* If the history_expansion_char is followed by one of the + characters in history_no_expand_chars, then it is not a + candidate for expansion of any kind. */ + if (member (cc, history_no_expand_chars)) + { + ADD_CHAR (string[i]); + break; + } + +#if defined (NO_BANG_HASH_MODIFIERS) + /* There is something that is listed as a `word specifier' in csh + documentation which means `the expanded text to this point'. + That is not a word specifier, it is an event specifier. If we + don't want to allow modifiers with `!#', just stick the current + output line in again. */ + if (cc == '#') + { + if (result) + { + temp = (char *)xmalloc (1 + strlen (result)); + strcpy (temp, result); + ADD_STRING (temp); + free (temp); + } + i++; + break; + } +#endif + + r = history_expand_internal (string, i, &eindex, &temp, result); + if (r < 0) + { + *output = temp; + free (result); + if (string != hstring) + free (string); + return -1; + } + else + { + if (temp) + { + modified++; + if (*temp) + ADD_STRING (temp); + free (temp); + } + only_printing = r == 1; + i = eindex; + } + break; + } + } + + *output = result; + if (string != hstring) + free (string); + + if (only_printing) + { + add_history (result); + return (2); + } + + return (modified != 0); +} + +/* Return a consed string which is the word specified in SPEC, and found + in FROM. NULL is returned if there is no spec. The address of + ERROR_POINTER is returned if the word specified cannot be found. + CALLER_INDEX is the offset in SPEC to start looking; it is updated + to point to just after the last character parsed. */ +static char * +get_history_word_specifier (spec, from, caller_index) + char *spec, *from; + int *caller_index; +{ + register int i = *caller_index; + int first, last; + int expecting_word_spec = 0; + char *result; + + /* The range of words to return doesn't exist yet. */ + first = last = 0; + result = (char *)NULL; + + /* If we found a colon, then this *must* be a word specification. If + it isn't, then it is an error. */ + if (spec[i] == ':') + { + i++; + expecting_word_spec++; + } + + /* Handle special cases first. */ + + /* `%' is the word last searched for. */ + if (spec[i] == '%') + { + *caller_index = i + 1; + return (search_match ? savestring (search_match) : savestring ("")); + } + + /* `*' matches all of the arguments, but not the command. */ + if (spec[i] == '*') + { + *caller_index = i + 1; + result = history_arg_extract (1, '$', from); + return (result ? result : savestring ("")); + } + + /* `$' is last arg. */ + if (spec[i] == '$') + { + *caller_index = i + 1; + return (history_arg_extract ('$', '$', from)); + } + + /* Try to get FIRST and LAST figured out. */ + + if (spec[i] == '-') + first = 0; + else if (spec[i] == '^') + first = 1; + else if (_rl_digit_p (spec[i]) && expecting_word_spec) + { + for (first = 0; _rl_digit_p (spec[i]); i++) + first = (first * 10) + _rl_digit_value (spec[i]); + } + else + return ((char *)NULL); /* no valid `first' for word specifier */ + + if (spec[i] == '^' || spec[i] == '*') + { + last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */ + i++; + } + else if (spec[i] != '-') + last = first; + else + { + i++; + + if (_rl_digit_p (spec[i])) + { + for (last = 0; _rl_digit_p (spec[i]); i++) + last = (last * 10) + _rl_digit_value (spec[i]); + } + else if (spec[i] == '$') + { + i++; + last = '$'; + } +#if 0 + else if (!spec[i] || spec[i] == ':') + /* check against `:' because there could be a modifier separator */ +#else + else + /* csh seems to allow anything to terminate the word spec here, + leaving it as an abbreviation. */ +#endif + last = -1; /* x- abbreviates x-$ omitting word `$' */ + } + + *caller_index = i; + + if (last >= first || last == '$' || last < 0) + result = history_arg_extract (first, last, from); + + return (result ? result : (char *)&error_pointer); +} + +/* Extract the args specified, starting at FIRST, and ending at LAST. + The args are taken from STRING. If either FIRST or LAST is < 0, + then make that arg count from the right (subtract from the number of + tokens, so that FIRST = -1 means the next to last token on the line). + If LAST is `$' the last arg from STRING is used. */ +char * +history_arg_extract (first, last, string) + int first, last; + const char *string; +{ + register int i, len; + char *result; + int size, offset; + char **list; + + /* XXX - think about making history_tokenize return a struct array, + each struct in array being a string and a length to avoid the + calls to strlen below. */ + if ((list = history_tokenize (string)) == NULL) + return ((char *)NULL); + + for (len = 0; list[len]; len++) + ; + + if (last < 0) + last = len + last - 1; + + if (first < 0) + first = len + first - 1; + + if (last == '$') + last = len - 1; + + if (first == '$') + first = len - 1; + + last++; + + if (first >= len || last > len || first < 0 || last < 0 || first > last) + result = ((char *)NULL); + else + { + for (size = 0, i = first; i < last; i++) + size += strlen (list[i]) + 1; + result = (char *)xmalloc (size + 1); + result[0] = '\0'; + + for (i = first, offset = 0; i < last; i++) + { + strcpy (result + offset, list[i]); + offset += strlen (list[i]); + if (i + 1 < last) + { + result[offset++] = ' '; + result[offset] = 0; + } + } + } + + for (i = 0; i < len; i++) + free (list[i]); + free (list); + + return (result); +} + +#define slashify_in_quotes "\\`\"$" + +/* 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 + WIND. The position in the returned array of strings is returned in + *INDP. */ +static char ** +history_tokenize_internal (string, wind, indp) + const char *string; + int 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. */ + if (indp && wind != -1) + *indp = -1; + + /* Get a token, and stuff it into RESULT. The tokens are split + 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++) + ; + if (string[i] == 0 || string[i] == history_comment_char) + return (result); + + start = i; + + if (member (string[i], "()\n")) + { + i++; + goto got_token; + } + + if (member (string[i], "<>;&|$")) + { + int peek = string[i + 1]; + + 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 (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]; + } + + 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; + } + + return (result); +} + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +char ** +history_tokenize (string) + const char *string; +{ + return (history_tokenize_internal (string, -1, (int *)NULL)); +} + +/* Find and return the word which contains the character at index IND + in the history line LINE. Used to save the word matched by the + last history !?string? search. */ +static char * +history_find_word (line, ind) + char *line; + int ind; +{ + char **words, *s; + int i, wind; + + words = history_tokenize_internal (line, ind, &wind); + if (wind == -1 || words == 0) + return ((char *)NULL); + s = words[wind]; + for (i = 0; i < wind; i++) + free (words[i]); + for (i = wind + 1; words[i]; i++) + free (words[i]); + free (words); + return s; +} diff --git a/readline-4.3/histfile.c b/readline-4.3/histfile.c new file mode 100644 index 0000000..60a9125 --- /dev/null +++ b/readline-4.3/histfile.c @@ -0,0 +1,479 @@ +/* histfile.c - functions to manipulate the history file. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include +#ifndef _MINIX +# include +#endif +#include "posixstat.h" +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (__EMX__) || defined (__CYGWIN__) +# undef HAVE_MMAP +#endif + +#ifdef HAVE_MMAP +# include + +# ifdef MAP_FILE +# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE) +# define MAP_WFLAGS (MAP_FILE|MAP_SHARED) +# else +# define MAP_RFLAGS MAP_PRIVATE +# define MAP_WFLAGS MAP_SHARED +# endif + +# ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +# endif + +#endif /* HAVE_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 + is no \n -> \r\n conversion performed. On other systems, we don't want to + mess around with O_BINARY at all, so we ensure that it's defined to 0. */ +#if defined (__EMX__) || defined (__CYGWIN__) +# ifndef O_BINARY +# define O_BINARY 0 +# endif +#else /* !__EMX__ && !__CYGWIN__ */ +# undef O_BINARY +# define O_BINARY 0 +#endif /* !__EMX__ && !__CYGWIN__ */ + +#include +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#include "history.h" +#include "histlib.h" + +#include "rlshell.h" +#include "xmalloc.h" + +/* 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 (). */ +static char * +history_filename (filename) + const char *filename; +{ + char *return_val; + const char *home; + int home_len; + + return_val = filename ? savestring (filename) : (char *)NULL; + + if (return_val) + return (return_val); + + home = sh_get_env_value ("HOME"); + + if (home == 0) + { + home = "."; + home_len = 1; + } + else + home_len = strlen (home); + + return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ + strcpy (return_val, home); + return_val[home_len] = '/'; +#if defined (__MSDOS__) + strcpy (return_val + home_len + 1, "_history"); +#else + strcpy (return_val + home_len + 1, ".history"); +#endif + + return (return_val); +} + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +int +read_history (filename) + const char *filename; +{ + return (read_history_range (filename, 0, -1)); +} + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +int +read_history_range (filename, from, to) + const char *filename; + int from, to; +{ + register char *line_start, *line_end; + char *input, *buffer, *bufend; + int file, current_line, chars_read; + struct stat finfo; + size_t file_size; + + buffer = (char *)NULL; + input = history_filename (filename); + file = open (input, O_RDONLY|O_BINARY, 0666); + + if ((file < 0) || (fstat (file, &finfo) == -1)) + goto error_and_exit; + + file_size = (size_t)finfo.st_size; + + /* 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 + goto error_and_exit; + } + +#ifdef HAVE_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; + chars_read = file_size; +#else + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + goto error_and_exit; + + chars_read = read (file, buffer, file_size); +#endif + if (chars_read < 0) + { + error_and_exit: + chars_read = errno; + if (file >= 0) + close (file); + + FREE (input); +#ifndef HAVE_MMAP + FREE (buffer); +#endif + + return (chars_read); + } + + close (file); + + /* Set TO to larger than end of file if negative. */ + if (to < 0) + to = chars_read; + + /* Start at beginning of file, work to end. */ + bufend = buffer + chars_read; + current_line = 0; + + /* Skip lines until we are at FROM. */ + 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; + } + + /* If there are lines left to gobble, then gobble them now. */ + for (line_end = line_start; line_end < bufend; line_end++) + if (*line_end == '\n') + { + *line_end = '\0'; + + if (*line_start) + add_history (line_start); + + current_line++; + + if (current_line >= to) + break; + + line_start = line_end + 1; + } + + FREE (input); +#ifndef HAVE_MMAP + FREE (buffer); +#else + munmap (buffer, file_size); +#endif + + return (0); +} + +/* Truncate the history file FNAME, leaving only LINES trailing lines. + If FNAME is NULL, then use ~/.history. Returns 0 on success, errno + on failure. */ +int +history_truncate_file (fname, lines) + const char *fname; + int lines; +{ + char *buffer, *filename, *bp; + int file, chars_read, rv; + struct stat finfo; + size_t file_size; + + buffer = (char *)NULL; + filename = history_filename (fname); + file = open (filename, O_RDONLY|O_BINARY, 0666); + rv = 0; + + /* Don't try to truncate non-regular files. */ + if (file == -1 || fstat (file, &finfo) == -1) + { + rv = errno; + if (file != -1) + close (file); + goto truncate_exit; + } + + if (S_ISREG (finfo.st_mode) == 0) + { + close (file); +#ifdef EFTYPE + rv = EFTYPE; +#else + rv = EINVAL; +#endif + goto truncate_exit; + } + + file_size = (size_t)finfo.st_size; + + /* check for overflow on very large files */ + if (file_size != finfo.st_size || file_size + 1 < file_size) + { + close (file); +#if defined (EFBIG) + rv = errno = EFBIG; +#elif defined (EOVERFLOW) + rv = errno = EOVERFLOW; +#else + rv = errno = EINVAL; +#endif + goto truncate_exit; + } + + buffer = (char *)malloc (file_size + 1); + if (buffer == 0) + { + close (file); + goto truncate_exit; + } + + chars_read = read (file, buffer, file_size); + close (file); + + if (chars_read <= 0) + { + rv = (chars_read < 0) ? errno : 0; + goto truncate_exit; + } + + /* Count backwards from the end of buffer until we have passed + LINES lines. */ + for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--) + { + if (*bp == '\n') + lines--; + } + + /* If this is the first line, then the file contains exactly the + number of lines we want to truncate to, so we don't need to do + anything. It's the first line if we don't find a newline between + 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; + } + + /* Write only if there are more lines in the file than we want to + truncate to. */ + if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) + { + write (file, bp, chars_read - (bp - buffer)); + +#if defined (__BEOS__) + /* BeOS ignores O_TRUNC. */ + ftruncate (file, chars_read - (bp - buffer)); +#endif + + close (file); + } + + truncate_exit: + + FREE (buffer); + + free (filename); + return rv; +} + +/* Workhorse function for writing history. Writes NELEMENT entries + from the history list to FILENAME. OVERWRITE is non-zero if you + wish to replace FILENAME with the entries. */ +static int +history_do_write (filename, nelements, overwrite) + const char *filename; + int nelements, overwrite; +{ + register int i; + char *output; + int file, mode, rv; + 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; +#endif + output = history_filename (filename); + rv = 0; + + if ((file = open (output, mode, 0600)) == -1) + { + FREE (output); + return (errno); + } + +#ifdef HAVE_MMAP + cursize = overwrite ? 0 : lseek (file, 0, SEEK_END); +#endif + + if (nelements > history_length) + nelements = history_length; + + /* Build a buffer of all the lines to write, and write them in one syscall. + Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */ + { + HIST_ENTRY **the_history; /* local */ + register int j; + int buffer_size; + char *buffer; + + 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); + + /* Allocate the buffer, and fill it. */ +#ifdef HAVE_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); + if ((void *)buffer == MAP_FAILED) + { +mmap_error: + rv = errno; + FREE (output); + close (file); + return rv; + } +#else + buffer = (char *)malloc (buffer_size); + if (buffer == 0) + { + rv = errno; + FREE (output); + close (file); + return rv; + } +#endif + + for (j = 0, i = history_length - nelements; i < history_length; i++) + { + strcpy (buffer + j, the_history[i]->line); + j += strlen (the_history[i]->line); + buffer[j++] = '\n'; + } + +#ifdef HAVE_MMAP + if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0) + rv = errno; +#else + if (write (file, buffer, buffer_size) < 0) + rv = errno; + free (buffer); +#endif + } + + close (file); + + FREE (output); + + return (rv); +} + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +int +append_history (nelements, filename) + int nelements; + const char *filename; +{ + return (history_do_write (filename, nelements, HISTORY_APPEND)); +} + +/* Overwrite FILENAME with the current history. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history ().*/ +int +write_history (filename) + const char *filename; +{ + return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); +} diff --git a/readline-4.3/histlib.h b/readline-4.3/histlib.h new file mode 100644 index 0000000..c39af71 --- /dev/null +++ b/readline-4.3/histlib.h @@ -0,0 +1,82 @@ +/* histlib.h -- internal definitions for the history library. */ +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_HISTLIB_H_) +#define _HISTLIB_H_ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#ifndef savestring +#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) +#endif + +#ifndef whitespace +#define whitespace(c) (((c) == ' ') || ((c) == '\t')) +#endif + +#ifndef _rl_digit_p +#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') +#endif + +#ifndef _rl_digit_value +#define _rl_digit_value(c) ((c) - '0') +#endif + +#ifndef member +# ifndef strchr +extern char *strchr (); +# endif +#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) +#endif + +#ifndef FREE +# define FREE(x) if (x) free (x) +#endif + +/* Possible history errors passed to hist_error. */ +#define EVENT_NOT_FOUND 0 +#define BAD_WORD_SPEC 1 +#define SUBST_FAILED 2 +#define BAD_MODIFIER 3 +#define NO_PREV_SUBST 4 + +/* Possible definitions for history starting point specification. */ +#define ANCHORED_SEARCH 1 +#define NON_ANCHORED_SEARCH 0 + +/* Possible definitions for what style of writing the history file we want. */ +#define HISTORY_APPEND 0 +#define HISTORY_OVERWRITE 1 + +/* Some variable definitions shared across history source files. */ +extern int history_offset; + +#endif /* !_HISTLIB_H_ */ diff --git a/readline-4.3/history.c b/readline-4.3/history.c new file mode 100644 index 0000000..4242f33 --- /dev/null +++ b/readline-4.3/history.c @@ -0,0 +1,381 @@ +/* History.c -- standalone history library */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +/* 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "history.h" +#include "histlib.h" + +#include "xmalloc.h" + +/* The number of slots to increase the_history by. */ +#define DEFAULT_HISTORY_GROW_SIZE 50 + +/* **************************************************************** */ +/* */ +/* History Functions */ +/* */ +/* **************************************************************** */ + +/* An array of HIST_ENTRY. This is where we store the history. */ +static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL; + +/* Non-zero means that we have enforced a limit on the amount of + history that we save. */ +static int history_stifled; + +/* The current number of slots allocated to the input_history. */ +static int history_size; + +/* If HISTORY_STIFLED is non-zero, then this is the maximum number of + entries to remember. */ +int history_max_entries; +int max_input_history; /* backwards compatibility */ + +/* The current location of the interactive history pointer. Just makes + life easier for outside callers. */ +int history_offset; + +/* The number of strings currently stored in the history list. */ +int history_length; + +/* The logical `base' of the history array. It defaults to 1. */ +int history_base = 1; + +/* Return the current HISTORY_STATE of the history. */ +HISTORY_STATE * +history_get_history_state () +{ + HISTORY_STATE *state; + + state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE)); + state->entries = the_history; + state->offset = history_offset; + state->length = history_length; + state->size = history_size; + state->flags = 0; + if (history_stifled) + state->flags |= HS_STIFLED; + + return (state); +} + +/* Set the state of the current history array to STATE. */ +void +history_set_history_state (state) + HISTORY_STATE *state; +{ + the_history = state->entries; + history_offset = state->offset; + history_length = state->length; + history_size = state->size; + if (state->flags & HS_STIFLED) + history_stifled = 1; +} + +/* Begin a session in which the history functions might be used. This + initializes interactive variables. */ +void +using_history () +{ + history_offset = history_length; +} + +/* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines. */ +int +history_total_bytes () +{ + register int i, result; + + for (i = result = 0; the_history && the_history[i]; i++) + result += strlen (the_history[i]->line); + + return (result); +} + +/* Returns the magic number which says what history element we are + looking at now. In this implementation, it returns history_offset. */ +int +where_history () +{ + return (history_offset); +} + +/* Make the current history item be the one at POS, an absolute index. + Returns zero if POS is out of range, else non-zero. */ +int +history_set_pos (pos) + int pos; +{ + if (pos > history_length || pos < 0 || !the_history) + return (0); + history_offset = pos; + return (1); +} + +/* Return the current history array. The caller has to be carefull, since this + is the actual array of data, and could be bashed or made corrupt easily. + The array is terminated with a NULL pointer. */ +HIST_ENTRY ** +history_list () +{ + return (the_history); +} + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +HIST_ENTRY * +current_history () +{ + return ((history_offset == history_length) || the_history == 0) + ? (HIST_ENTRY *)NULL + : the_history[history_offset]; +} + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry then return + a NULL pointer. */ +HIST_ENTRY * +previous_history () +{ + return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; +} + +/* Move history_offset forward to the next history entry, and return + a pointer to that entry. If there is no next entry then return a + NULL pointer. */ +HIST_ENTRY * +next_history () +{ + return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; +} + +/* Return the history entry which is logically at OFFSET in the history array. + OFFSET is relative to history_base. */ +HIST_ENTRY * +history_get (offset) + int offset; +{ + int local_index; + + local_index = offset - history_base; + return (local_index >= history_length || local_index < 0 || !the_history) + ? (HIST_ENTRY *)NULL + : the_history[local_index]; +} + +/* Place STRING at the end of the history list. The data field + is set to NULL. */ +void +add_history (string) + const char *string; +{ + HIST_ENTRY *temp; + + if (history_stifled && (history_length == history_max_entries)) + { + register int i; + + /* If the history is stifled, and history_length is zero, + and it equals history_max_entries, we don't save items. */ + if (history_length == 0) + return; + + /* If there is something in the slot, then remove it. */ + if (the_history[0]) + { + free (the_history[0]->line); + free (the_history[0]); + } + + /* Copy the rest of the entries, moving down one slot. */ + for (i = 0; i < history_length; i++) + the_history[i] = the_history[i + 1]; + + history_base++; + } + else + { + if (history_size == 0) + { + history_size = DEFAULT_HISTORY_GROW_SIZE; + the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); + history_length = 1; + } + else + { + if (history_length == (history_size - 1)) + { + history_size += DEFAULT_HISTORY_GROW_SIZE; + the_history = (HIST_ENTRY **) + xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); + } + history_length++; + } + } + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + temp->line = savestring (string); + temp->data = (char *)NULL; + + the_history[history_length] = (HIST_ENTRY *)NULL; + the_history[history_length - 1] = temp; +} + +/* 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. */ +HIST_ENTRY * +replace_history_entry (which, line, data) + int which; + const char *line; + histdata_t data; +{ + HIST_ENTRY *temp, *old_value; + + if (which >= history_length) + return ((HIST_ENTRY *)NULL); + + temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); + old_value = the_history[which]; + + temp->line = savestring (line); + temp->data = data; + the_history[which] = temp; + + return (old_value); +} + +/* Remove history element WHICH from the history. The removed + element is returned to you so you can free the line, data, + and containing structure. */ +HIST_ENTRY * +remove_history (which) + int 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]; + + for (i = which; i < history_length; i++) + the_history[i] = the_history[i + 1]; + + history_length--; + } + + return (return_value); +} + +/* Stifle the history list, remembering only MAX number of lines. */ +void +stifle_history (max) + int max; +{ + register int i, j; + + if (max < 0) + max = 0; + + if (history_length > 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]); + } + + history_base = i; + for (j = 0, i = history_length - max; j < max; i++, j++) + the_history[j] = the_history[i]; + the_history[j] = (HIST_ENTRY *)NULL; + history_length = j; + } + + history_stifled = 1; + max_input_history = history_max_entries = max; +} + +/* Stop stifling the history. This returns the previous maximum + number of history entries. The value is positive if the history + was stifled, negative if it wasn't. */ +int +unstifle_history () +{ + if (history_stifled) + { + history_stifled = 0; + return (history_max_entries); + } + else + return (-history_max_entries); +} + +int +history_is_stifled () +{ + return (history_stifled); +} + +void +clear_history () +{ + register int i; + + /* This loses because we cannot free the data. */ + for (i = 0; i < history_length; i++) + { + free (the_history[i]->line); + free (the_history[i]); + the_history[i] = (HIST_ENTRY *)NULL; + } + + history_offset = history_length = 0; +} diff --git a/readline-4.3/history.h b/readline-4.3/history.h new file mode 100644 index 0000000..58b5de4 --- /dev/null +++ b/readline-4.3/history.h @@ -0,0 +1,246 @@ +/* History.h -- the names of functions that you can call in history. */ +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _HISTORY_H_ +#define _HISTORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined READLINE_LIBRARY +# include "rlstdc.h" +# include "rltypedefs.h" +#else +# include +# include +#endif + +#ifdef __STDC__ +typedef void *histdata_t; +#else +typedef char *histdata_t; +#endif + +/* The structure used to store a history entry. */ +typedef struct _hist_entry { + char *line; + histdata_t data; +} HIST_ENTRY; + +/* 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. */ + 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; + +/* Flag values for the `flags' member of HISTORY_STATE. */ +#define HS_STIFLED 0x01 + +/* Initialization and state management. */ + +/* Begin a session in which the history functions might be used. This + just initializes the interactive variables. */ +extern void using_history PARAMS((void)); + +/* Return the current HISTORY_STATE of the history. */ +extern HISTORY_STATE *history_get_history_state PARAMS((void)); + +/* Set the state of the current history array to STATE. */ +extern void history_set_history_state PARAMS((HISTORY_STATE *)); + +/* Manage the history list. */ + +/* Place STRING at the end of the history list. + The associated data field (if any) is set to NULL. */ +extern void add_history 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)); + +/* 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. */ +extern HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t)); + +/* Clear the history list and start over. */ +extern void clear_history PARAMS((void)); + +/* Stifle the history list, remembering only MAX number of entries. */ +extern void stifle_history PARAMS((int)); + +/* Stop stifling the history. This returns the previous amount the + history was stifled by. The value is positive if the history was + stifled, negative if it wasn't. */ +extern int unstifle_history PARAMS((void)); + +/* Return 1 if the history is stifled, 0 if it is not. */ +extern int history_is_stifled PARAMS((void)); + +/* Information about the history list. */ + +/* Return a NULL terminated array of HIST_ENTRY which is the current input + history. Element 0 of this list is the beginning of time. If there + is no history, return NULL. */ +extern HIST_ENTRY **history_list PARAMS((void)); + +/* Returns the number which says what history element we are now + looking at. */ +extern int where_history PARAMS((void)); + +/* Return the history entry at the current position, as determined by + history_offset. If there is no entry there, return a NULL pointer. */ +extern HIST_ENTRY *current_history PARAMS((void)); + +/* Return the history entry which is logically at OFFSET in the history + array. OFFSET is relative to history_base. */ +extern HIST_ENTRY *history_get PARAMS((int)); + +/* 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)); + +/* Moving around the history list. */ + +/* Set the position in the history list to POS. */ +extern int history_set_pos PARAMS((int)); + +/* Back up history_offset to the previous history entry, and return + a pointer to that entry. If there is no previous entry, return + a NULL pointer. */ +extern HIST_ENTRY *previous_history PARAMS((void)); + +/* Move history_offset forward to the next item in the input_history, + and return the a pointer to that entry. If there is no next entry, + return a NULL pointer. */ +extern HIST_ENTRY *next_history PARAMS((void)); + +/* Searching the history list. */ + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, + else through subsequent. If the string is found, then + current_history () is the history entry, and the value of this function + is the offset in the line of that history entry that the string was + found in. Otherwise, nothing is changed, and a -1 is returned. */ +extern int history_search PARAMS((const char *, int)); + +/* Search the history for STRING, starting at history_offset. + The search is anchored: matching lines must begin with string. + DIRECTION is as in history_search(). */ +extern int history_search_prefix PARAMS((const char *, int)); + +/* Search for STRING in the history list, starting at POS, an + absolute index into the list. DIR, if negative, says to search + backwards from POS, else forwards. + Returns the absolute index of the history element where STRING + was found, or -1 otherwise. */ +extern int history_search_pos PARAMS((const char *, int, int)); + +/* Managing the history file. */ + +/* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ +extern int read_history PARAMS((const char *)); + +/* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ +extern int read_history_range PARAMS((const char *, int, int)); + +/* Write the current history to FILENAME. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history (). */ +extern int write_history PARAMS((const char *)); + +/* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ +extern int append_history PARAMS((int, const char *)); + +/* Truncate the history file, leaving only the last NLINES lines. */ +extern int history_truncate_file PARAMS((const char *, int)); + +/* History expansion. */ + +/* Expand the string STRING, placing the result into OUTPUT, a pointer + to a string. Returns: + + 0) If no expansions took place (or, if the only change in + the text was the de-slashifying of the history expansion + character) + 1) If expansions did take place + -1) If there was an error in expansion. + 2) If the returned line should just be printed. + + If an error ocurred in expansion, then OUTPUT contains a descriptive + error message. */ +extern int history_expand PARAMS((char *, char **)); + +/* Extract a string segment consisting of the FIRST through LAST + arguments present in STRING. Arguments are broken up as in + the shell. */ +extern char *history_arg_extract PARAMS((int, int, const char *)); + +/* Return the text of the history event beginning at the current + offset into STRING. Pass STRING with *INDEX equal to the + history_expansion_char that begins this specification. + DELIMITING_QUOTE is a character that is allowed to end the string + specification for what to search for in addition to the normal + characters `:', ` ', `\t', `\n', and sometimes `?'. */ +extern char *get_history_event PARAMS((const char *, int *, int)); + +/* Return an array of tokens, much as the shell might. The tokens are + parsed out of STRING. */ +extern char **history_tokenize PARAMS((const char *)); + +/* Exported history variables. */ +extern int history_base; +extern int history_length; +extern int history_max_entries; +extern char history_expansion_char; +extern char history_subst_char; +extern char *history_word_delimiters; +extern char history_comment_char; +extern char *history_no_expand_chars; +extern char *history_search_delimiter_chars; +extern int history_quotes_inhibit_expansion; + +/* Backwards compatibility */ +extern int max_input_history; + +/* If set, this function is called to decide whether or not a particular + history expansion should be treated as a special case for the calling + application and not expanded. */ +extern rl_linebuf_func_t *history_inhibit_expansion_function; + +#ifdef __cplusplus +} +#endif + +#endif /* !_HISTORY_H_ */ diff --git a/readline-4.3/histsearch.c b/readline-4.3/histsearch.c new file mode 100644 index 0000000..d94fd6c --- /dev/null +++ b/readline-4.3/histsearch.c @@ -0,0 +1,195 @@ +/* histsearch.c -- searching the history list. */ + +/* Copyright (C) 1989, 1992 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. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#include "history.h" +#include "histlib.h" + +/* The list of alternate characters that can delimit a history search + string. */ +char *history_search_delimiter_chars = (char *)NULL; + +static int history_search_internal PARAMS((const char *, int, int)); + +/* Search the history for STRING, starting at history_offset. + If DIRECTION < 0, then the search is through previous entries, else + through subsequent. If ANCHORED is non-zero, the string must + appear at the beginning of a history line, otherwise, the string + may appear anywhere in the line. If the string is found, then + current_history () is the history entry, and the value of this + function is the offset in the line of that history entry that the + string was found in. Otherwise, nothing is changed, and a -1 is + returned. */ + +static int +history_search_internal (string, direction, anchored) + const char *string; + int direction, anchored; +{ + register int i, reverse; + register char *line; + register int line_index; + int string_len; + HIST_ENTRY **the_history; /* local */ + + i = history_offset; + reverse = (direction < 0); + + /* Take care of trivial cases first. */ + if (string == 0 || *string == '\0') + return (-1); + + if (!history_length || ((i == history_length) && !reverse)) + return (-1); + + if (reverse && (i == history_length)) + i--; + +#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) + + the_history = history_list (); + string_len = strlen (string); + while (1) + { + /* Search each line in the history list for STRING. */ + + /* At limit for direction? */ + if ((reverse && i < 0) || (!reverse && i == history_length)) + return (-1); + + line = the_history[i]->line; + line_index = strlen (line); + + /* If STRING is longer than line, no match. */ + if (string_len > line_index) + { + NEXT_LINE (); + continue; + } + + /* Handle anchored searches first. */ + if (anchored == ANCHORED_SEARCH) + { + if (STREQN (string, line, string_len)) + { + history_offset = i; + return (0); + } + + NEXT_LINE (); + continue; + } + + /* Do substring search. */ + if (reverse) + { + line_index -= string_len; + + while (line_index >= 0) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index--; + } + } + else + { + register int limit; + + limit = line_index - string_len + 1; + line_index = 0; + + while (line_index < limit) + { + if (STREQN (string, line + line_index, string_len)) + { + history_offset = i; + return (line_index); + } + line_index++; + } + } + NEXT_LINE (); + } +} + +/* Do a non-anchored search for STRING through the history in DIRECTION. */ +int +history_search (string, direction) + const char *string; + int direction; +{ + return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); +} + +/* Do an anchored search for string through the history in DIRECTION. */ +int +history_search_prefix (string, direction) + const char *string; + int direction; +{ + return (history_search_internal (string, direction, ANCHORED_SEARCH)); +} + +/* Search for STRING in the history list. DIR is < 0 for searching + backwards. POS is an absolute index into the history list at + which point to begin searching. */ +int +history_search_pos (string, dir, pos) + const char *string; + int dir, pos; +{ + int ret, old; + + old = where_history (); + history_set_pos (pos); + if (history_search (string, dir) == -1) + { + history_set_pos (old); + return (-1); + } + ret = where_history (); + history_set_pos (old); + return ret; +} diff --git a/readline-4.3/input.c b/readline-4.3/input.c new file mode 100644 index 0000000..841f05d --- /dev/null +++ b/readline-4.3/input.c @@ -0,0 +1,540 @@ +/* input.c -- character input functions for readline. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#if defined (FIONREAD_IN_SYS_IOCTL) +# include +#endif + +#include +#include + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* What kind of non-blocking I/O do we have? */ +#if !defined (O_NDELAY) && defined (O_NONBLOCK) +# define O_NDELAY O_NONBLOCK /* Posix style */ +#endif + +/* Non-null means it is a pointer to a function to run while waiting for + character input. */ +rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; + +rl_getc_func_t *rl_getc_function = rl_getc; + +static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */ + +static int ibuffer_space PARAMS((void)); +static int rl_get_char PARAMS((int *)); +static int rl_gather_tyi PARAMS((void)); + +/* **************************************************************** */ +/* */ +/* Character Input Buffering */ +/* */ +/* **************************************************************** */ + +static int pop_index, push_index; +static unsigned char ibuffer[512]; +static int ibuffer_len = sizeof (ibuffer) - 1; + +#define any_typein (push_index != pop_index) + +int +_rl_any_typein () +{ + return any_typein; +} + +/* Return the amount of space available in the buffer for stuffing + characters. */ +static int +ibuffer_space () +{ + if (pop_index > push_index) + return (pop_index - push_index - 1); + else + return (ibuffer_len - (push_index - pop_index)); +} + +/* Get a key from the buffer of characters to be read. + Return the key in KEY. + Result is KEY if there was a key, or 0 if there wasn't. */ +static int +rl_get_char (key) + int *key; +{ + if (push_index == pop_index) + return (0); + + *key = ibuffer[pop_index++]; + + if (pop_index >= ibuffer_len) + pop_index = 0; + + return (1); +} + +/* Stuff KEY into the *front* of the input buffer. + Returns non-zero if successful, zero if there is + no space left in the buffer. */ +int +_rl_unget_char (key) + int key; +{ + if (ibuffer_space ()) + { + pop_index--; + if (pop_index < 0) + pop_index = ibuffer_len - 1; + ibuffer[pop_index] = key; + return (1); + } + return (0); +} + +/* 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). */ +static int +rl_gather_tyi () +{ + int tty; + register int tem, result; + int chars_avail; + char input; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = _keyboard_input_timeout; + result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); + if (result <= 0) + return 0; /* Nothing to read. */ +#endif + + result = -1; +#if defined (FIONREAD) + errno = 0; + result = ioctl (tty, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; +#endif + +#if defined (O_NDELAY) + if (result == -1) + { + tem = fcntl (tty, F_GETFL, 0); + + fcntl (tty, F_SETFL, (tem | O_NDELAY)); + chars_avail = read (tty, &input, 1); + + fcntl (tty, F_SETFL, tem); + if (chars_avail == -1 && errno == EAGAIN) + return 0; + } +#endif /* O_NDELAY */ + + /* If there's nothing available, don't waste time trying to read + something. */ + if (chars_avail <= 0) + return 0; + + tem = ibuffer_space (); + + if (chars_avail > tem) + chars_avail = tem; + + /* One cannot read all of the available input. I can only read a single + character at a time, or else programs which require input can be + thwarted. If the buffer is larger than one character, I lose. + Damn! */ + if (tem < ibuffer_len) + chars_avail = 0; + + if (result != -1) + { + while (chars_avail--) + rl_stuff_char ((*rl_getc_function) (rl_instream)); + } + else + { + if (chars_avail) + rl_stuff_char (input); + } + + return 1; +} + +int +rl_set_keyboard_input_timeout (u) + int u; +{ + int o; + + o = _keyboard_input_timeout; + if (u > 0) + _keyboard_input_timeout = u; + return (o); +} + +/* Is there input available to be read on the readline input file + descriptor? Only works if the system has select(2) or FIONREAD. + Uses the value of _keyboard_input_timeout as the timeout; if another + readline function wants to specify a timeout and not leave it up to + the user, it should use _rl_input_queued(timeout_value_in_microseconds) + instead. */ +int +_rl_input_available () +{ +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; + struct timeval timeout; +#endif +#if !defined (HAVE_SELECT) && defined(FIONREAD) + int chars_avail; +#endif + int tty; + + tty = fileno (rl_instream); + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (tty, &readfds); + FD_SET (tty, &exceptfds); + timeout.tv_sec = 0; + timeout.tv_usec = _keyboard_input_timeout; + return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); +#else + +#if defined (FIONREAD) + if (ioctl (tty, FIONREAD, &chars_avail) == 0) + return (chars_avail); +#endif + +#endif + + return 0; +} + +int +_rl_input_queued (t) + int t; +{ + int old_timeout, r; + + old_timeout = rl_set_keyboard_input_timeout (t); + r = _rl_input_available (); + rl_set_keyboard_input_timeout (old_timeout); + return r; +} + +void +_rl_insert_typein (c) + int c; +{ + int key, t, i; + char *string; + + i = key = 0; + string = (char *)xmalloc (ibuffer_len + 1); + string[i++] = (char) c; + + while ((t = rl_get_char (&key)) && + _rl_keymap[key].type == ISFUNC && + _rl_keymap[key].function == rl_insert) + string[i++] = key; + + if (t) + _rl_unget_char (key); + + string[i] = '\0'; + rl_insert_text (string); + free (string); +} + +/* Add KEY to the buffer of characters to be read. Returns 1 if the + character was stuffed correctly; 0 otherwise. */ +int +rl_stuff_char (key) + int key; +{ + if (ibuffer_space () == 0) + return 0; + + if (key == EOF) + { + key = NEWLINE; + rl_pending_input = EOF; + RL_SETSTATE (RL_STATE_INPUTPENDING); + } + ibuffer[push_index++] = key; + if (push_index >= ibuffer_len) + push_index = 0; + + return 1; +} + +/* Make C be the next command to be executed. */ +int +rl_execute_next (c) + int c; +{ + rl_pending_input = c; + RL_SETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* Clear any pending input pushed with rl_execute_next() */ +int +rl_clear_pending_input () +{ + rl_pending_input = 0; + RL_UNSETSTATE (RL_STATE_INPUTPENDING); + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Input */ +/* */ +/* **************************************************************** */ + +/* Read a key, including pending input. */ +int +rl_read_key () +{ + int c; + + rl_key_sequence_length++; + + if (rl_pending_input) + { + c = rl_pending_input; + rl_clear_pending_input (); + } + else + { + /* If input is coming from a macro, then use that. */ + if (c = _rl_next_macro_key ()) + return (c); + + /* If the user has an event function, then call it periodically. */ + if (rl_event_hook) + { + while (rl_event_hook && rl_get_char (&c) == 0) + { + (*rl_event_hook) (); + if (rl_done) /* XXX - experimental */ + return ('\n'); + if (rl_gather_tyi () < 0) /* XXX - EIO */ + { + rl_done = 1; + return ('\n'); + } + } + } + else + { + if (rl_get_char (&c) == 0) + c = (*rl_getc_function) (rl_instream); + } + } + + return (c); +} + +int +rl_getc (stream) + FILE *stream; +{ + int result; + unsigned char c; + + while (1) + { + result = read (fileno (stream), &c, sizeof (unsigned char)); + + if (result == sizeof (unsigned char)) + return (c); + + /* If zero characters are returned, then the file that we are + reading from is empty! Return EOF in that case. */ + if (result == 0) + return (EOF); + +#if defined (__BEOS__) + if (errno == EINTR) + continue; +#endif + +#if defined (EWOULDBLOCK) +# define X_EWOULDBLOCK EWOULDBLOCK +#else +# define X_EWOULDBLOCK -99 +#endif + +#if defined (EAGAIN) +# define X_EAGAIN EAGAIN +#else +# define X_EAGAIN -99 +#endif + + if (errno == X_EWOULDBLOCK || errno == X_EAGAIN) + { + if (sh_unset_nodelay_mode (fileno (stream)) < 0) + return (EOF); + continue; + } + +#undef X_EWOULDBLOCK +#undef X_EAGAIN + + /* If the error that we received was SIGINT, then try again, + this is simply an interrupted system call to read (). + Otherwise, some error ocurred, also signifying EOF. */ + if (errno != EINTR) + return (EOF); + } +} + +#if defined (HANDLE_MULTIBYTE) +/* read multibyte char */ +int +_rl_read_mbchar (mbchar, size) + char *mbchar; + int size; +{ + int mb_len = 0; + size_t mbchar_bytes_length; + wchar_t wc; + mbstate_t ps, ps_back; + + memset(&ps, 0, sizeof (mbstate_t)); + memset(&ps_back, 0, sizeof (mbstate_t)); + + while (mb_len < size) + { + RL_SETSTATE(RL_STATE_MOREINPUT); + mbchar[mb_len++] = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps); + if (mbchar_bytes_length == (size_t)(-1)) + break; /* invalid byte sequence for the current locale */ + else if (mbchar_bytes_length == (size_t)(-2)) + { + /* shorted bytes */ + ps = ps_back; + continue; + } + else if (mbchar_bytes_length > (size_t)(0)) + break; + } + + return mb_len; +} + +/* Read a multibyte-character string whose first character is FIRST into + the buffer MB of length MBLEN. Returns the last character read, which + may be FIRST. Used by the search functions, among others. Very similar + to _rl_read_mbchar. */ +int +_rl_read_mbstring (first, mb, mblen) + int first; + char *mb; + int mblen; +{ + int i, c; + mbstate_t ps; + + c = first; + memset (mb, 0, mblen); + for (i = 0; i < mblen; i++) + { + mb[i] = (char)c; + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_get_char_len (mb, &ps) == -2) + { + /* Read more for multibyte character */ + RL_SETSTATE (RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE (RL_STATE_MOREINPUT); + } + else + break; + } + return c; +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/readline-4.3/isearch.c b/readline-4.3/isearch.c new file mode 100644 index 0000000..c1ea5b3 --- /dev/null +++ b/readline-4.3/isearch.c @@ -0,0 +1,560 @@ +/* **************************************************************** */ +/* */ +/* I-Search and Searching */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2002 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Variables exported to other files in the readline library. */ +char *_rl_isearch_terminators = (char *)NULL; + +/* 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)); + +/* 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; + +/* Last search string and its length. */ +static char *last_isearch_string; +static int last_isearch_string_len; + +static char *default_isearch_terminators = "\033\012"; + +/* Search backwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_reverse_search_history (sign, key) + int sign, key; +{ + return (rl_search_history (-sign, key)); +} + +/* Search forwards through the history looking for a string which is typed + interactively. Start with the current line. */ +int +rl_forward_search_history (sign, key) + int sign, key; +{ + return (rl_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, + WHERE is the history list number of the current line. If it is + -1, then this line is the starting one. */ +static void +rl_display_search (search_string, reverse_p, where) + char *search_string; + int reverse_p, where; +{ + char *message; + int msglen, searchlen; + + searchlen = (search_string && *search_string) ? strlen (search_string) : 0; + + message = (char *)xmalloc (searchlen + 33); + msglen = 0; + +#if defined (NOTDEF) + if (where != -1) + { + sprintf (message, "[%d]", where + history_base); + msglen = strlen (message); + } +#endif /* NOTDEF */ + + message[msglen++] = '('; + + if (reverse_p) + { + strcpy (message + msglen, "reverse-"); + msglen += 8; + } + + strcpy (message + msglen, "i-search)`"); + msglen += 10; + + if (search_string) + { + strcpy (message + msglen, search_string); + msglen += searchlen; + } + + strcpy (message + msglen, "': "); + + rl_message ("%s", message); + free (message); + (*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; +{ + /* 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; + + 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; + + /* 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; + + 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 + : default_isearch_terminators; + + /* Create an arrary of pointers to the lines that we want to search. */ + rl_maybe_replace_line (); + i = 0; + if (hlist) + for (i = 0; hlist[i]; i++); + + /* 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; + + if (_rl_saved_line_for_history) + 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; + } + + hlen++; + + /* The line where we start the search. */ + i = orig_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 */ + + /* Normalize DIRECTION into 1 or -1. */ + direction = (direction >= 0) ? 1 : -1; + + rl_display_search (search_string, reverse, -1); + + sline = rl_line_buffer; + sline_len = strlen (sline); + line_index = rl_point; + + found = failed = 0; + for (;;) + { + rl_command_func_t *f = (rl_command_func_t *)NULL; + + /* Read a key and decide how to proceed. */ + 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, 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; + } + + /* 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; + } + +#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 (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c)) + { + /* This sets rl_pending_input to c; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (c); + break; + } + } + else +#endif + if (c >= 0 && ENDSRCH_CHAR (c)) + { + /* This sets rl_pending_input to c; it will be picked up the next + time rl_read_key is called. */ + rl_execute_next (c); + break; + } + + switch (c) + { + 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 (); + break; + + /* switch directions */ + case -2: + direction = -direction; + reverse = direction < 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; + + 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) + { + rl_ding (); + 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; + + case -6: /* C-Y */ + /* skip over portion of line we already matched */ + wstart = rl_point + search_string_index; + if (wstart >= rl_end) + { + rl_ding (); + 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; + } + + for (found = failed = 0;;) + { + int limit = sline_len - search_string_index + 1; + + /* 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; + + /* 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 (failed) + break; + + /* Now set up the line for searching... */ + line_index = reverse ? sline_len - search_string_index : 0; + } + + if (failed) + { + /* We cannot find the search string. Ding the bell. */ + rl_ding (); + i = last_found_line; + continue; /* XXX - was 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 (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); + } + } + + /* 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. */ + + /* First put back the original state. */ + strcpy (rl_line_buffer, lines[orig_line]); + + rl_restore_prompt (); + + /* Save the search string for possible later use. */ + FREE (last_isearch_string); + last_isearch_string = search_string; + last_isearch_string_len = search_string_index; + + 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 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) + { + if (last_found_line == orig_line) + line_index = orig_point; + else + line_index = strlen (rl_line_buffer); + rl_mark = orig_mark; + } + + 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 (); + + FREE (allocated_line); + free (lines); + + RL_UNSETSTATE(RL_STATE_ISEARCH); + + return 0; +} diff --git a/readline-4.3/keymaps.c b/readline-4.3/keymaps.c new file mode 100644 index 0000000..12506d3 --- /dev/null +++ b/readline-4.3/keymaps.c @@ -0,0 +1,150 @@ +/* keymaps.c -- Functions and keymaps for the GNU Readline library. */ + +/* Copyright (C) 1988,1989 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include /* for FILE * definition for readline.h */ + +#include "readline.h" +#include "rlconf.h" + +#include "emacs_keymap.c" + +#if defined (VI_MODE) +#include "vi_keymap.c" +#endif + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Functions for manipulating Keymaps. */ +/* */ +/* **************************************************************** */ + + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +Keymap +rl_make_bare_keymap () +{ + register int i; + Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY)); + + for (i = 0; i < KEYMAP_SIZE; i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = (rl_command_func_t *)NULL; + } + + for (i = 'A'; i < ('Z' + 1); i++) + { + keymap[i].type = ISFUNC; + keymap[i].function = rl_do_lowercase_version; + } + + return (keymap); +} + +/* Return a new keymap which is a copy of MAP. */ +Keymap +rl_copy_keymap (map) + Keymap map; +{ + register int i; + Keymap temp = rl_make_bare_keymap (); + + for (i = 0; i < KEYMAP_SIZE; i++) + { + temp[i].type = map[i].type; + temp[i].function = map[i].function; + } + return (temp); +} + +/* Return a new keymap with the printing characters bound to rl_insert, + the uppercase Meta characters bound to run their lowercase equivalents, + and the Meta digits bound to produce numeric arguments. */ +Keymap +rl_make_keymap () +{ + register int i; + Keymap newmap; + + newmap = rl_make_bare_keymap (); + + /* All ASCII printing characters are self-inserting. */ + for (i = ' '; i < 127; i++) + newmap[i].function = rl_insert; + + newmap[TAB].function = rl_insert; + newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */ + 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++) + newmap[i].function = rl_insert; +#endif /* KEYMAP_SIZE > 128 */ + + return (newmap); +} + +/* Free the storage associated with MAP. */ +void +rl_discard_keymap (map) + Keymap map; +{ + int i; + + if (!map) + return; + + for (i = 0; i < KEYMAP_SIZE; i++) + { + switch (map[i].type) + { + case ISFUNC: + break; + + case ISKMAP: + rl_discard_keymap ((Keymap)map[i].function); + break; + + case ISMACR: + free ((char *)map[i].function); + break; + } + } +} diff --git a/readline-4.3/keymaps.h b/readline-4.3/keymaps.h new file mode 100644 index 0000000..66fa2a5 --- /dev/null +++ b/readline-4.3/keymaps.h @@ -0,0 +1,103 @@ +/* keymaps.h -- Manipulation of readline keymaps. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _KEYMAPS_H_ +#define _KEYMAPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "chardefs.h" +# include "rltypedefs.h" +#else +# include +# include +# include +#endif + +/* A keymap contains one entry for each key in the ASCII set. + Each entry consists of a type and a pointer. + FUNCTION is the address of a function to run, or the + address of a keymap to indirect through. + TYPE says which kind of thing FUNCTION is. */ +typedef struct _keymap_entry { + char type; + rl_command_func_t *function; +} KEYMAP_ENTRY; + +/* This must be large enough to hold bindings for all of the characters + in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x, + and so on) plus one for subsequence matching. */ +#define KEYMAP_SIZE 257 +#define ANYOTHERKEY KEYMAP_SIZE-1 + +/* I wanted to make the above structure contain a union of: + union { rl_command_func_t *function; struct _keymap_entry *keymap; } value; + but this made it impossible for me to create a static array. + Maybe I need C lessons. */ + +typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; +typedef KEYMAP_ENTRY *Keymap; + +/* The values that TYPE can have in a keymap entry. */ +#define ISFUNC 0 +#define ISKMAP 1 +#define ISMACR 2 + +extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap; + +/* Return a new, empty keymap. + Free it with free() when you are done. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); + +/* Return a new keymap which is a copy of MAP. */ +extern Keymap rl_copy_keymap PARAMS((Keymap)); + +/* 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. */ +extern Keymap rl_make_keymap PARAMS((void)); + +/* Free the storage associated with a keymap. */ +extern void rl_discard_keymap PARAMS((Keymap)); + +/* These functions actually appear in bind.c */ + +/* Return the keymap corresponding to a given name. Names look like + `emacs' or `emacs-meta' or `vi-insert'. */ +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); + +/* Return the current keymap. */ +extern Keymap rl_get_keymap PARAMS((void)); + +/* Set the current keymap to MAP. */ +extern void rl_set_keymap PARAMS((Keymap)); + +#ifdef __cplusplus +} +#endif + +#endif /* _KEYMAPS_H_ */ diff --git a/readline-4.3/kill.c b/readline-4.3/kill.c new file mode 100644 index 0000000..a616b92 --- /dev/null +++ b/readline-4.3/kill.c @@ -0,0 +1,652 @@ +/* kill.c -- kill ring management. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Killing Mechanism */ +/* */ +/* **************************************************************** */ + +/* What we assume for a max number of kills. */ +#define DEFAULT_MAX_KILLS 10 + +/* The real variable to look at to find out when to flush kills. */ +static int rl_max_kills = DEFAULT_MAX_KILLS; + +/* Where to store killed text. */ +static char **rl_kill_ring = (char **)NULL; + +/* Where we are in the kill ring. */ +static int rl_kill_index; + +/* How many slots we have in the kill ring. */ +static int rl_kill_ring_length; + +static int _rl_copy_to_kill_ring PARAMS((char *, int)); +static int region_kill_internal PARAMS((int)); +static int _rl_copy_word_as_kill PARAMS((int, int)); +static int rl_yank_nth_arg_internal PARAMS((int, int, int)); + +/* How to say that you only want to save a certain amount + of kill material. */ +int +rl_set_retained_kills (num) + int num; +{ + return 0; +} + +/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary. + This uses TEXT directly, so the caller must not free it. If APPEND is + non-zero, and the last command was a kill, the text is appended to the + current kill ring slot, otherwise prepended. */ +static int +_rl_copy_to_kill_ring (text, append) + char *text; + int append; +{ + char *old, *new; + int slot; + + /* First, find the slot to work with. */ + if (_rl_last_command_was_kill == 0) + { + /* Get a new slot. */ + if (rl_kill_ring == 0) + { + /* If we don't have any defined, then make one. */ + rl_kill_ring = (char **) + xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *)); + rl_kill_ring[slot = 0] = (char *)NULL; + } + else + { + /* We have to add a new slot on the end, unless we have + exceeded the max limit for remembering kills. */ + slot = rl_kill_ring_length; + if (slot == rl_max_kills) + { + register int i; + free (rl_kill_ring[0]); + for (i = 0; i < slot; i++) + rl_kill_ring[i] = rl_kill_ring[i + 1]; + } + else + { + slot = rl_kill_ring_length += 1; + rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); + } + rl_kill_ring[--slot] = (char *)NULL; + } + } + else + slot = rl_kill_ring_length - 1; + + /* If the last command was a kill, prepend or append. */ + if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) + { + old = rl_kill_ring[slot]; + new = (char *)xmalloc (1 + strlen (old) + strlen (text)); + + if (append) + { + strcpy (new, old); + strcat (new, text); + } + else + { + strcpy (new, text); + strcat (new, old); + } + free (old); + free (text); + rl_kill_ring[slot] = new; + } + else + rl_kill_ring[slot] = text; + + rl_kill_index = slot; + return 0; +} + +/* The way to kill something. This appends or prepends to the last + kill, if the last command was a kill command. if FROM is less + than TO, then the text is appended, otherwise prepended. If the + last command was not a kill command, then a new slot is made for + this kill. */ +int +rl_kill_text (from, to) + int from, to; +{ + char *text; + + /* Is there anything to kill? */ + if (from == to) + { + _rl_last_command_was_kill++; + return 0; + } + + text = rl_copy_text (from, to); + + /* Delete the copied text from the line. */ + rl_delete_text (from, to); + + _rl_copy_to_kill_ring (text, from < to); + + _rl_last_command_was_kill++; + return 0; +} + +/* Now REMEMBER! In order to do prepending or appending correctly, kill + commands always make rl_point's original position be the FROM argument, + and rl_point's extent be the TO argument. */ + +/* **************************************************************** */ +/* */ +/* Killing Commands */ +/* */ +/* **************************************************************** */ + +/* Delete the word at point, saving the text in the kill ring. */ +int +rl_kill_word (count, key) + int count, key; +{ + int orig_point; + + if (count < 0) + return (rl_backward_kill_word (-count, key)); + else + { + orig_point = rl_point; + rl_forward_word (count, key); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Rubout the word before point, placing it on the kill ring. */ +int +rl_backward_kill_word (count, ignore) + int count, ignore; +{ + int orig_point; + + if (count < 0) + return (rl_kill_word (-count, ignore)); + else + { + orig_point = rl_point; + rl_backward_word (count, ignore); + + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill from here to the end of the line. If DIRECTION is negative, kill + back to the line start instead. */ +int +rl_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point; + + if (direction < 0) + return (rl_backward_kill_line (1, ignore)); + else + { + orig_point = rl_point; + rl_end_of_line (1, ignore); + if (orig_point != rl_point) + rl_kill_text (orig_point, rl_point); + rl_point = orig_point; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Kill backwards to the start of the line. If DIRECTION is negative, kill + forwards to the line end instead. */ +int +rl_backward_kill_line (direction, ignore) + int direction, ignore; +{ + int orig_point; + + if (direction < 0) + return (rl_kill_line (1, ignore)); + else + { + if (!rl_point) + rl_ding (); + else + { + orig_point = rl_point; + rl_beg_of_line (1, ignore); + if (rl_point != orig_point) + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + } + return 0; +} + +/* Kill the whole line, no matter where point is. */ +int +rl_kill_full_line (count, ignore) + int count, ignore; +{ + rl_begin_undo_group (); + rl_point = 0; + rl_kill_text (rl_point, rl_end); + rl_mark = 0; + rl_end_undo_group (); + return 0; +} + +/* The next two functions mimic unix line editing behaviour, except they + save the deleted text on the kill ring. This is safer than not saving + it, and since we have a ring, nobody should get screwed. */ + +/* This does what C-w does in Unix. We can't prevent people from + using behaviour that they expect. */ +int +rl_unix_word_rubout (count, key) + int count, key; +{ + int orig_point; + + if (rl_point == 0) + rl_ding (); + else + { + orig_point = rl_point; + if (count <= 0) + count = 1; + + while (count--) + { + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) + rl_point--; + } + + rl_kill_text (orig_point, rl_point); + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Here is C-u doing what Unix does. You don't *have* to use these + key-bindings. We have a choice of killing the entire line, or + killing from where we are to the start of the line. We choose the + latter, because if you are a Unix weenie, then you haven't backspaced + into the line at all, and if you aren't, then you know what you are + doing. */ +int +rl_unix_line_discard (count, key) + int count, key; +{ + if (rl_point == 0) + rl_ding (); + else + { + rl_kill_text (rl_point, 0); + rl_point = 0; + if (rl_editing_mode == emacs_mode) + rl_mark = rl_point; + } + return 0; +} + +/* Copy the text in the `region' to the kill ring. If DELETE is non-zero, + delete the text from the line as well. */ +static int +region_kill_internal (delete) + int delete; +{ + char *text; + + if (rl_mark != rl_point) + { + text = rl_copy_text (rl_point, rl_mark); + if (delete) + rl_delete_text (rl_point, rl_mark); + _rl_copy_to_kill_ring (text, rl_point < rl_mark); + } + + _rl_last_command_was_kill++; + return 0; +} + +/* Copy the text in the region to the kill ring. */ +int +rl_copy_region_to_kill (count, ignore) + int count, ignore; +{ + return (region_kill_internal (0)); +} + +/* Kill the text between the point and mark. */ +int +rl_kill_region (count, ignore) + int count, ignore; +{ + int r, npoint; + + npoint = (rl_point < rl_mark) ? rl_point : rl_mark; + r = region_kill_internal (1); + _rl_fix_point (1); + rl_point = npoint; + return r; +} + +/* Copy COUNT words to the kill ring. DIR says which direction we look + to find the words. */ +static int +_rl_copy_word_as_kill (count, dir) + int count, dir; +{ + int om, op, r; + + om = rl_mark; + op = rl_point; + + if (dir > 0) + rl_forward_word (count, 0); + else + rl_backward_word (count, 0); + + rl_mark = rl_point; + + if (dir > 0) + rl_backward_word (count, 0); + else + rl_forward_word (count, 0); + + r = region_kill_internal (0); + + rl_mark = om; + rl_point = op; + + return r; +} + +int +rl_copy_forward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_backward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, 1)); +} + +int +rl_copy_backward_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_copy_forward_word (-count, key)); + + return (_rl_copy_word_as_kill (count, -1)); +} + +/* Yank back the last killed text. This ignores arguments. */ +int +rl_yank (count, ignore) + int count, ignore; +{ + if (rl_kill_ring == 0) + { + _rl_abort_internal (); + return -1; + } + + _rl_set_mark_at_pos (rl_point); + rl_insert_text (rl_kill_ring[rl_kill_index]); + return 0; +} + +/* If the last command was yank, or yank_pop, and the text just + before point is identical to the current kill item, then + delete that text from the line, rotate the index down, and + yank back some other text. */ +int +rl_yank_pop (count, key) + int count, key; +{ + int l, n; + + if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) || + !rl_kill_ring) + { + _rl_abort_internal (); + return -1; + } + + l = strlen (rl_kill_ring[rl_kill_index]); + n = rl_point - l; + if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l)) + { + rl_delete_text (n, rl_point); + rl_point = n; + rl_kill_index--; + if (rl_kill_index < 0) + rl_kill_index = rl_kill_ring_length - 1; + rl_yank (1, 0); + return 0; + } + else + { + _rl_abort_internal (); + return -1; + } +} + +/* Yank the COUNTh argument from the previous history line, skipping + HISTORY_SKIP lines before looking for the `previous line'. */ +static int +rl_yank_nth_arg_internal (count, ignore, history_skip) + int count, ignore, history_skip; +{ + register HIST_ENTRY *entry; + char *arg; + int i, pos; + + pos = where_history (); + + if (history_skip) + { + for (i = 0; i < history_skip; i++) + entry = previous_history (); + } + + entry = previous_history (); + + history_set_pos (pos); + + if (entry == 0) + { + rl_ding (); + return -1; + } + + arg = history_arg_extract (count, count, entry->line); + if (!arg || !*arg) + { + rl_ding (); + return -1; + } + + rl_begin_undo_group (); + + _rl_set_mark_at_pos (rl_point); + +#if defined (VI_MODE) + /* Vi mode always inserts a space before yanking the argument, and it + inserts it right *after* rl_point. */ + if (rl_editing_mode == vi_mode) + { + rl_vi_append_mode (1, ignore); + rl_insert_text (" "); + } +#endif /* VI_MODE */ + + rl_insert_text (arg); + free (arg); + + rl_end_undo_group (); + return 0; +} + +/* Yank the COUNTth argument from the previous history line. */ +int +rl_yank_nth_arg (count, ignore) + int count, ignore; +{ + return (rl_yank_nth_arg_internal (count, ignore, 0)); +} + +/* Yank the last argument from the previous history line. This `knows' + how rl_yank_nth_arg treats a count of `$'. With an argument, this + behaves the same as rl_yank_nth_arg. */ +int +rl_yank_last_arg (count, key) + int count, key; +{ + static int history_skip = 0; + static int explicit_arg_p = 0; + static int count_passed = 1; + static int direction = 1; + static int undo_needed = 0; + int retval; + + if (rl_last_func != rl_yank_last_arg) + { + history_skip = 0; + explicit_arg_p = rl_explicit_arg; + count_passed = count; + direction = 1; + } + else + { + if (undo_needed) + rl_do_undo (); + if (count < 1) + direction = -direction; + history_skip += direction; + if (history_skip < 0) + history_skip = 0; + } + + if (explicit_arg_p) + retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); + else + retval = rl_yank_nth_arg_internal ('$', key, history_skip); + + undo_needed = retval == 0; + return retval; +} + +/* A special paste command for users of Cygnus's cygwin32. */ +#if defined (__CYGWIN__) +#include + +int +rl_paste_from_clipboard (count, key) + int count, key; +{ + char *data, *ptr; + int len; + + if (OpenClipboard (NULL) == 0) + return (0); + + data = (char *)GetClipboardData (CF_TEXT); + if (data) + { + ptr = strchr (data, '\r'); + if (ptr) + { + len = ptr - data; + ptr = (char *)xmalloc (len + 1); + ptr[len] = '\0'; + strncpy (ptr, data, len); + } + else + ptr = data; + _rl_set_mark_at_pos (rl_point); + rl_insert_text (ptr); + if (ptr != data) + free (ptr); + CloseClipboard (); + } + return (0); +} +#endif /* __CYGWIN__ */ diff --git a/readline-4.3/macro.c b/readline-4.3/macro.c new file mode 100644 index 0000000..b73c3af --- /dev/null +++ b/readline-4.3/macro.c @@ -0,0 +1,262 @@ +/* macro.c -- keyboard macros for readline. */ + +/* Copyright (C) 1994 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Hacking Keyboard Macros */ +/* */ +/* **************************************************************** */ + +/* The currently executing macro string. If this is non-zero, + then it is a malloc ()'ed string where input is coming from. */ +char *rl_executing_macro = (char *)NULL; + +/* The offset in the above string to the next character to be read. */ +static int executing_macro_index; + +/* The current macro string being built. Characters get stuffed + in here by add_macro_char (). */ +static char *current_macro = (char *)NULL; + +/* The size of the buffer allocated to current_macro. */ +static int current_macro_size; + +/* The index at which characters are being added to current_macro. */ +static int current_macro_index; + +/* A structure used to save nested macro strings. + It is a linked list of string/index for each saved macro. */ +struct saved_macro { + struct saved_macro *next; + char *string; + int sindex; +}; + +/* The list of saved macros. */ +static struct saved_macro *macro_list = (struct saved_macro *)NULL; + +/* Set up to read subsequent input from STRING. + STRING is free ()'ed when we are done with it. */ +void +_rl_with_macro_input (string) + char *string; +{ + _rl_push_executing_macro (); + rl_executing_macro = string; + executing_macro_index = 0; + RL_SETSTATE(RL_STATE_MACROINPUT); +} + +/* Return the next character available from a macro, or 0 if + there are no macro characters. */ +int +_rl_next_macro_key () +{ + if (rl_executing_macro == 0) + return (0); + + if (rl_executing_macro[executing_macro_index] == 0) + { + _rl_pop_executing_macro (); + return (_rl_next_macro_key ()); + } + + return (rl_executing_macro[executing_macro_index++]); +} + +/* Save the currently executing macro on a stack of saved macros. */ +void +_rl_push_executing_macro () +{ + struct saved_macro *saver; + + saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); + saver->next = macro_list; + saver->sindex = executing_macro_index; + saver->string = rl_executing_macro; + + macro_list = saver; +} + +/* Discard the current macro, replacing it with the one + on the top of the stack of saved macros. */ +void +_rl_pop_executing_macro () +{ + struct saved_macro *macro; + + FREE (rl_executing_macro); + rl_executing_macro = (char *)NULL; + executing_macro_index = 0; + + if (macro_list) + { + macro = macro_list; + rl_executing_macro = macro_list->string; + executing_macro_index = macro_list->sindex; + macro_list = macro_list->next; + free (macro); + } + + if (rl_executing_macro == 0) + RL_UNSETSTATE(RL_STATE_MACROINPUT); +} + +/* Add a character to the macro being built. */ +void +_rl_add_macro_char (c) + int c; +{ + if (current_macro_index + 1 >= current_macro_size) + { + if (current_macro == 0) + current_macro = (char *)xmalloc (current_macro_size = 25); + else + current_macro = (char *)xrealloc (current_macro, current_macro_size += 25); + } + + current_macro[current_macro_index++] = c; + current_macro[current_macro_index] = '\0'; +} + +void +_rl_kill_kbd_macro () +{ + if (current_macro) + { + free (current_macro); + current_macro = (char *) NULL; + } + current_macro_size = current_macro_index = 0; + + FREE (rl_executing_macro); + rl_executing_macro = (char *) NULL; + executing_macro_index = 0; + + RL_UNSETSTATE(RL_STATE_MACRODEF); +} + +/* Begin defining a keyboard macro. + Keystrokes are recorded as they are executed. + End the definition with rl_end_kbd_macro (). + If a numeric argument was explicitly typed, then append this + definition to the end of the existing macro, and start by + re-executing the existing macro. */ +int +rl_start_kbd_macro (ignore1, ignore2) + int ignore1, ignore2; +{ + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + _rl_abort_internal (); + return -1; + } + + if (rl_explicit_arg) + { + if (current_macro) + _rl_with_macro_input (savestring (current_macro)); + } + else + current_macro_index = 0; + + RL_SETSTATE(RL_STATE_MACRODEF); + return 0; +} + +/* Stop defining a keyboard macro. + A numeric argument says to execute the macro right now, + that many times, counting the definition as the first time. */ +int +rl_end_kbd_macro (count, ignore) + int count, ignore; +{ + if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) + { + _rl_abort_internal (); + return -1; + } + + current_macro_index -= rl_key_sequence_length - 1; + current_macro[current_macro_index] = '\0'; + + RL_UNSETSTATE(RL_STATE_MACRODEF); + + return (rl_call_last_kbd_macro (--count, 0)); +} + +/* Execute the most recently defined keyboard macro. + COUNT says how many times to execute it. */ +int +rl_call_last_kbd_macro (count, ignore) + int count, ignore; +{ + if (current_macro == 0) + _rl_abort_internal (); + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + { + rl_ding (); /* no recursive macros */ + current_macro[--current_macro_index] = '\0'; /* erase this char */ + return 0; + } + + while (count--) + _rl_with_macro_input (savestring (current_macro)); + return 0; +} + +void +rl_push_macro_input (macro) + char *macro; +{ + _rl_with_macro_input (macro); +} diff --git a/readline-4.3/mbutil.c b/readline-4.3/mbutil.c new file mode 100644 index 0000000..50302f0 --- /dev/null +++ b/readline-4.3/mbutil.c @@ -0,0 +1,337 @@ +/* mbutil.c -- readline multibyte character utility functions */ + +/* Copyright (C) 2001 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Declared here so it can be shared between the readline and history + libraries. */ +#if defined (HANDLE_MULTIBYTE) +int rl_byte_oriented = 0; +#else +int rl_byte_oriented = 1; +#endif + +/* **************************************************************** */ +/* */ +/* Multibyte Character Utility Functions */ +/* */ +/* **************************************************************** */ + +#if defined(HANDLE_MULTIBYTE) + +static int +_rl_find_next_mbchar_internal (string, seed, count, find_non_zero) + char *string; + int seed, count, find_non_zero; +{ + size_t tmp = 0; + mbstate_t ps; + int point = 0; + wchar_t wc; + + memset(&ps, 0, sizeof (mbstate_t)); + if (seed < 0) + seed = 0; + if (count <= 0) + return seed; + + 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 --; + + 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) + { + /* invalid bytes. asume a byte represents a character */ + point++; + count--; + /* reset states. */ + memset(&ps, 0, sizeof(mbstate_t)); + } + else if (tmp == (size_t)0) + /* found '\0' char */ + break; + else + { + /* valid bytes */ + point += tmp; + if (find_non_zero) + { + if (wcwidth (wc) == 0) + continue; + else + count--; + } + else + count--; + } + } + + if (find_non_zero) + { + tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps); + while (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)) + break; + } + } + return point; +} + +static int +_rl_find_prev_mbchar_internal (string, seed, find_non_zero) + char *string; + int seed, find_non_zero; +{ + mbstate_t ps; + int prev, non_zero_prev, point, length; + size_t tmp; + wchar_t wc; + + memset(&ps, 0, sizeof(mbstate_t)); + length = strlen(string); + + if (seed < 0) + return 0; + else if (length < seed) + return length; + + prev = non_zero_prev = point = 0; + while (point < seed) + { + tmp = mbrtowc (&wc, string + point, length - point, &ps); + if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + { + /* in this case, bytes are invalid or shorted to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + tmp = 1; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + memset(&ps, 0, sizeof (mbstate_t)); + } + else if (tmp == 0) + break; /* Found '\0' char. Can this happen? */ + else + { + if (find_non_zero) + { + if (wcwidth (wc) != 0) + prev = point; + } + else + prev = point; + } + + point += tmp; + } + + return prev; +} + +/* return the number of bytes parsed from the multibyte sequence starting + at src, if a non-L'\0' wide character was recognized. It returns 0, + if a L'\0' wide character was recognized. It returns (size_t)(-1), + if an invalid multibyte sequence was encountered. It returns (size_t)(-2) + if it couldn't parse a complete multibyte character. */ +int +_rl_get_char_len (src, ps) + char *src; + mbstate_t *ps; +{ + size_t tmp; + + tmp = mbrlen((const char *)src, (size_t)strlen (src), ps); + if (tmp == (size_t)(-2)) + { + /* shorted to compose multibyte char */ + memset (ps, 0, sizeof(mbstate_t)); + return -2; + } + else if (tmp == (size_t)(-1)) + { + /* invalid to compose multibyte char */ + /* initialize the conversion state */ + memset (ps, 0, sizeof(mbstate_t)); + return -1; + } + else if (tmp == (size_t)0) + return 0; + else + return (int)tmp; +} + +/* compare the specified two characters. If the characters matched, + return 1. Otherwise return 0. */ +int +_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) + char *buf1, *buf2; + mbstate_t *ps1, *ps2; + int pos1, pos2; +{ + int i, w1, w2; + + if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || + (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 || + (w1 != w2) || + (buf1[pos1] != buf2[pos2])) + return 0; + + for (i = 1; i < w1; i++) + if (buf1[pos1+i] != buf2[pos2+i]) + return 0; + + return 1; +} + +/* adjust pointed byte and find mbstate of the point of string. + adjusted point will be point <= adjusted_point, and returns + differences of the byte(adjusted_point - point). + if point is invalied (point < 0 || more than string length), + it returns -1 */ +int +_rl_adjust_point(string, point, ps) + char *string; + int point; + mbstate_t *ps; +{ + size_t tmp = 0; + int length; + int pos = 0; + + length = strlen(string); + if (point < 0) + return -1; + if (length < point) + return -1; + + while (pos < point) + { + tmp = mbrlen (string + pos, length - pos, ps); + if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) + { + /* in this case, bytes are invalid or shorted to compose + multibyte char, so assume that the first byte represents + a single character anyway. */ + pos++; + /* clear the state of the byte sequence, because + in this case effect of mbstate is undefined */ + memset (ps, 0, sizeof (mbstate_t)); + } + else + pos += tmp; + } + + return (pos - point); +} + +int +_rl_is_mbchar_matched (string, seed, end, mbchar, length) + char *string; + int seed, end; + char *mbchar; + int length; +{ + int i; + + if ((end - seed) < length) + return 0; + + for (i = 0; i < length; i++) + if (string[seed + i] != mbchar[i]) + return 0; + return 1; +} +#endif /* HANDLE_MULTIBYTE */ + +/* Find next `count' characters started byte point of the specified seed. + If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte + characters. */ +#undef _rl_find_next_mbchar +int +_rl_find_next_mbchar (string, seed, count, flags) + char *string; + int seed, count, flags; +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_next_mbchar_internal (string, seed, count, flags); +#else + return (seed + count); +#endif +} + +/* Find previous character started byte point of the specified seed. + Returned point will be point <= seed. If flags is MB_FIND_NONZERO, + we look for non-zero-width multibyte characters. */ +#undef _rl_find_prev_mbchar +int +_rl_find_prev_mbchar (string, seed, flags) + char *string; + int seed, flags; +{ +#if defined (HANDLE_MULTIBYTE) + return _rl_find_prev_mbchar_internal (string, seed, flags); +#else + return ((seed == 0) ? seed : seed - 1); +#endif +} diff --git a/readline-4.3/misc.c b/readline-4.3/misc.c new file mode 100644 index 0000000..f3775d3 --- /dev/null +++ b/readline-4.3/misc.c @@ -0,0 +1,496 @@ +/* misc.c -- miscellaneous bindable readline functions. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +static int rl_digit_loop PARAMS((void)); +static void _rl_history_set_point PARAMS((void)); + +/* Forward declarations used in this file */ +void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +/* If non-zero, rl_get_previous_history and rl_get_next_history attempt + to preserve the value of rl_point from line to line. */ +int _rl_history_preserve_point = 0; + +/* 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; + +/* **************************************************************** */ +/* */ +/* Numeric Arguments */ +/* */ +/* **************************************************************** */ + +/* Handle C-u style numeric args, as well as M--, and M-digits. */ +static int +rl_digit_loop () +{ + int key, c, sawminus, sawdigits; + + rl_save_prompt (); + + 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; + } + + /* 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)); + } + } + + c = UNMETA (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) + { + rl_numeric_arg = sawminus = 1; + rl_arg_sign = -1; + } + else + { + /* Make M-- command equivalent to M--1 command. */ + if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0) + rl_explicit_arg = 1; + rl_restore_prompt (); + rl_clear_message (); + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return (_rl_dispatch (key, _rl_keymap)); + } + } + + /*NOTREACHED*/ +} + +/* 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 ()); +} + +/* What to do when you abort reading an argument. */ +int +rl_discard_argument () +{ + rl_ding (); + rl_clear_message (); + _rl_init_argument (); + return 0; +} + +/* Create a default argument. */ +int +_rl_init_argument () +{ + rl_numeric_arg = rl_arg_sign = 1; + rl_explicit_arg = 0; + return 0; +} + +/* C-u, universal argument. Multiply the current argument by 4. + Read a key. If the key has nothing to do with arguments, then + dispatch on it. If the key is the abort character then abort. */ +int +rl_universal_argument (count, key) + int count, key; +{ + rl_numeric_arg *= 4; + return (rl_digit_loop ()); +} + +/* **************************************************************** */ +/* */ +/* History Utilities */ +/* */ +/* **************************************************************** */ + +/* We already have a history library, and that is what we use to control + the history features of readline. This is our local interface to + the history mechanism. */ + +/* While we are editing the history, this is the saved + version of the original line. */ +HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL; + +/* Set the history pointer back to the last entry in the history. */ +void +_rl_start_using_history () +{ + using_history (); + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Free the contents (and containing structure) of a HIST_ENTRY. */ +void +_rl_free_history_entry (entry) + HIST_ENTRY *entry; +{ + if (entry == 0) + return; + if (entry->line) + free (entry->line); + free (entry); +} + +/* Perhaps put back the current line if it has changed. */ +int +rl_maybe_replace_line () +{ + HIST_ENTRY *temp; + + temp = current_history (); + /* If the current line has changed, save the changes. */ + if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) + { + temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); + free (temp->line); + free (temp); + } + return 0; +} + +/* Restore the _rl_saved_line_for_history if there is one. */ +int +rl_maybe_unsave_line () +{ + if (_rl_saved_line_for_history) + { + 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); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + rl_point = rl_end; /* rl_replace_line sets rl_end */ + } + else + rl_ding (); + return 0; +} + +/* Save the current line in _rl_saved_line_for_history. */ +int +rl_maybe_save_line () +{ + if (_rl_saved_line_for_history == 0) + { + _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->data = (char *)rl_undo_list; + } + return 0; +} + +int +_rl_free_saved_history_line () +{ + if (_rl_saved_line_for_history) + { + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + } + return 0; +} + +static void +_rl_history_set_point () +{ + rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) + ? _rl_history_saved_point + : rl_end; + if (rl_point > rl_end) + rl_point = rl_end; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_point = 0; +#endif /* VI_MODE */ + + if (rl_editing_mode == emacs_mode) + rl_mark = (rl_point == rl_end ? 0 : rl_end); +} + +void +rl_replace_from_history (entry, flags) + HIST_ENTRY *entry; + int flags; /* currently unused */ +{ + rl_replace_line (entry->line, 0); + rl_undo_list = (UNDO_LIST *)entry->data; + rl_point = rl_end; + rl_mark = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + rl_point = 0; + rl_mark = rl_end; + } +#endif +} + +/* **************************************************************** */ +/* */ +/* History Commands */ +/* */ +/* **************************************************************** */ + +/* Meta-< goes to the start of the history. */ +int +rl_beginning_of_history (count, key) + int count, key; +{ + return (rl_get_previous_history (1 + where_history (), key)); +} + +/* Meta-> goes to the end of the history. (The current line). */ +int +rl_end_of_history (count, key) + int count, key; +{ + rl_maybe_replace_line (); + using_history (); + rl_maybe_unsave_line (); + return 0; +} + +/* Move down to the next history line. */ +int +rl_get_next_history (count, key) + int count, key; +{ + HIST_ENTRY *temp; + + if (count < 0) + return (rl_get_previous_history (-count, key)); + + if (count == 0) + return 0; + + rl_maybe_replace_line (); + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = next_history (); + if (!temp) + break; + --count; + } + + if (temp == 0) + rl_maybe_unsave_line (); + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + return 0; +} + +/* Get the previous item out of our interactive history, making it the current + line. If there is no previous history, just ding. */ +int +rl_get_previous_history (count, key) + int count, key; +{ + HIST_ENTRY *old_temp, *temp; + + if (count < 0) + return (rl_get_next_history (-count, key)); + + if (count == 0) + return 0; + + /* either not saved by rl_newline or at end of line, so set appropriately. */ + if (_rl_history_saved_point == -1 && (rl_point || rl_end)) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + /* If we don't have a line saved, then save this one. */ + rl_maybe_save_line (); + + /* If the current line has changed, save the changes. */ + rl_maybe_replace_line (); + + temp = old_temp = (HIST_ENTRY *)NULL; + while (count) + { + temp = previous_history (); + if (temp == 0) + break; + + old_temp = temp; + --count; + } + + /* If there was a large argument, and we moved back to the start of the + history, that is not an error. So use the last value found. */ + if (!temp && old_temp) + temp = old_temp; + + if (temp == 0) + rl_ding (); + else + { + rl_replace_from_history (temp, 0); + _rl_history_set_point (); + } + return 0; +} + +/* **************************************************************** */ +/* */ +/* Editing Modes */ +/* */ +/* **************************************************************** */ +/* How to toggle back and forth between editing modes. */ +int +rl_vi_editing_mode (count, key) + int count, key; +{ +#if defined (VI_MODE) + _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ + rl_editing_mode = vi_mode; + rl_vi_insertion_mode (1, key); +#endif /* VI_MODE */ + + return 0; +} + +int +rl_emacs_editing_mode (count, key) + int count, key; +{ + rl_editing_mode = emacs_mode; + _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ + _rl_keymap = emacs_standard_keymap; + return 0; +} + +/* Function for the rest of the library to use to set insert/overwrite mode. */ +void +_rl_set_insert_mode (im, force) + int im, force; +{ +#ifdef CURSOR_MODE + _rl_set_cursor (im, force); +#endif + + rl_insert_mode = im; +} + +/* Toggle overwrite mode. A positive explicit argument selects overwrite + mode. A negative or zero explicit argument selects insert mode. */ +int +rl_overwrite_mode (count, key) + int count, key; +{ + if (rl_explicit_arg == 0) + _rl_set_insert_mode (rl_insert_mode ^ 1, 0); + else if (count > 0) + _rl_set_insert_mode (RL_IM_OVERWRITE, 0); + else + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return 0; +} diff --git a/readline-4.3/nls.c b/readline-4.3/nls.c new file mode 100644 index 0000000..706c819 --- /dev/null +++ b/readline-4.3/nls.c @@ -0,0 +1,225 @@ +/* nls.c -- skeletal internationalization code. */ + +/* Copyright (C) 1996 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +#include "rldefs.h" +#include "readline.h" +#include "rlshell.h" +#include "rlprivate.h" + +#if !defined (HAVE_SETLOCALE) +/* A list of legal values for the LANG or LC_CTYPE environment variables. + If a locale name in this list is the value for the LC_ALL, LC_CTYPE, + or LANG environment variable (using the first of those with a value), + readline eight-bit mode is enabled. */ +static char *legal_lang_values[] = +{ + "iso88591", + "iso88592", + "iso88593", + "iso88594", + "iso88595", + "iso88596", + "iso88597", + "iso88598", + "iso88599", + "iso885910", + "koi8r", + 0 +}; + +static char *normalize_codeset PARAMS((char *)); +static char *find_codeset PARAMS((char *, size_t *)); +#endif /* !HAVE_SETLOCALE */ + +/* 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. */ +int +_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; + + /* Set the LC_CTYPE locale category from environment variables. */ + t = setlocale (LC_CTYPE, ""); + if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + return (1); + } + else + return (0); + +#else /* !HAVE_SETLOCALE */ + char *lspec, *t; + int i; + + /* 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"); + if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) + return (0); + for (i = 0; t && legal_lang_values[i]; i++) + if (STREQ (t, legal_lang_values[i])) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + break; + } + free (t); + return (legal_lang_values[i] ? 1 : 0); + +#endif /* !HAVE_SETLOCALE */ +} + +#if !defined (HAVE_SETLOCALE) +static char * +normalize_codeset (codeset) + char *codeset; +{ + size_t namelen, i; + int len, all_digits; + char *wp, *retval; + + codeset = find_codeset (codeset, &namelen); + + if (codeset == 0) + return (codeset); + + all_digits = 1; + for (len = 0, i = 0; i < namelen; i++) + { + if (ISALNUM ((unsigned char)codeset[i])) + { + len++; + all_digits &= _rl_digit_p (codeset[i]); + } + } + + retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1); + if (retval == 0) + return ((char *)0); + + wp = retval; + /* Add `iso' to beginning of an all-digit codeset */ + if (all_digits) + { + *wp++ = 'i'; + *wp++ = 's'; + *wp++ = 'o'; + } + + for (i = 0; i < namelen; i++) + if (ISALPHA ((unsigned char)codeset[i])) + *wp++ = _rl_to_lower (codeset[i]); + else if (_rl_digit_p (codeset[i])) + *wp++ = codeset[i]; + *wp = '\0'; + + return retval; +} + +/* Isolate codeset portion of locale specification. */ +static char * +find_codeset (name, lenp) + char *name; + size_t *lenp; +{ + char *cp, *language, *result; + + cp = language = name; + result = (char *)0; + + while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',') + cp++; + + /* This does not make sense: language has to be specified. As + an exception we allow the variable to contain only the codeset + name. Perhaps there are funny codeset names. */ + if (language == cp) + { + *lenp = strlen (language); + result = language; + } + else + { + /* Next is the territory. */ + if (*cp == '_') + do + ++cp; + while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_'); + + /* Now, finally, is the codeset. */ + result = cp; + if (*cp == '.') + do + ++cp; + while (*cp && *cp != '@'); + + if (cp - result > 2) + { + result++; + *lenp = cp - result; + } + else + { + *lenp = strlen (language); + result = language; + } + } + + return result; +} +#endif /* !HAVE_SETLOCALE */ diff --git a/readline-4.3/parens.c b/readline-4.3/parens.c new file mode 100644 index 0000000..54ef1f3 --- /dev/null +++ b/readline-4.3/parens.c @@ -0,0 +1,179 @@ +/* parens.c -- Implementation of matching parentheses feature. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 "rlconf.h" + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT +#endif + +#if defined (HAVE_SELECT) +# include +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#include "readline.h" +#include "rlprivate.h" + +static int find_matching_open PARAMS((char *, int, int)); + +/* Non-zero means try to blink the matching open parenthesis when the + close parenthesis is inserted. */ +#if defined (HAVE_SELECT) +int rl_blink_matching_paren = 1; +#else /* !HAVE_SELECT */ +int rl_blink_matching_paren = 0; +#endif /* !HAVE_SELECT */ + +static int _paren_blink_usec = 500000; + +/* Change emacs_standard_keymap to have bindings for paren matching when + ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */ +void +_rl_enable_paren_matching (on_or_off) + int on_or_off; +{ + if (on_or_off) + { /* ([{ */ + rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap); + } + else + { /* ([{ */ + rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap); + rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap); + } +} + +int +rl_set_paren_blink_timeout (u) + int u; +{ + int o; + + o = _paren_blink_usec; + if (u > 0) + _paren_blink_usec = u; + return (o); +} + +int +rl_insert_close (count, invoking_key) + int count, invoking_key; +{ + if (rl_explicit_arg || !rl_blink_matching_paren) + _rl_insert_char (count, invoking_key); + else + { +#if defined (HAVE_SELECT) + int orig_point, match_point, ready; + struct timeval timer; + fd_set readfds; + + _rl_insert_char (1, invoking_key); + (*rl_redisplay_function) (); + match_point = + find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); + + /* Emacs might message or ring the bell here, but I don't. */ + if (match_point < 0) + return -1; + + FD_ZERO (&readfds); + FD_SET (fileno (rl_instream), &readfds); + timer.tv_sec = 0; + timer.tv_usec = _paren_blink_usec; + + orig_point = rl_point; + rl_point = match_point; + (*rl_redisplay_function) (); + ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); + rl_point = orig_point; +#else /* !HAVE_SELECT */ + _rl_insert_char (count, invoking_key); +#endif /* !HAVE_SELECT */ + } + return 0; +} + +static int +find_matching_open (string, from, closer) + char *string; + int from, closer; +{ + register int i; + int opener, level, delimiter; + + switch (closer) + { + case ']': opener = '['; break; + case '}': opener = '{'; break; + case ')': opener = '('; break; + default: + return (-1); + } + + level = 1; /* The closer passed in counts as 1. */ + delimiter = 0; /* Delimited state unknown. */ + + for (i = from; i > -1; i--) + { + if (delimiter && (string[i] == delimiter)) + delimiter = 0; + else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i])) + delimiter = string[i]; + else if (!delimiter && (string[i] == closer)) + level++; + else if (!delimiter && (string[i] == opener)) + level--; + + if (!level) + break; + } + return (i); +} diff --git a/readline-4.3/posixdir.h b/readline-4.3/posixdir.h new file mode 100644 index 0000000..505e279 --- /dev/null +++ b/readline-4.3/posixdir.h @@ -0,0 +1,57 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +/* This file should be included instead of or . */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include +# define D_NAMLEN(d) (strlen ((d)->d_name)) +#else +# if defined (HAVE_SYS_NDIR_H) +# include +# endif +# if defined (HAVE_SYS_DIR_H) +# include +# endif +# if defined (HAVE_NDIR_H) +# include +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO) +# define d_fileno d_ino +#endif + +#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_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 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* _POSIX_SOURCE */ + +#endif /* !_POSIXDIR_H_ */ diff --git a/readline-4.3/posixjmp.h b/readline-4.3/posixjmp.h new file mode 100644 index 0000000..b52aa00 --- /dev/null +++ b/readline-4.3/posixjmp.h @@ -0,0 +1,40 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf +# if !defined (__OPENNT) +# undef setjmp +# define setjmp(x) sigsetjmp((x), 1) +# undef longjmp +# define longjmp(x, n) siglongjmp((x), (n)) +# endif /* !__OPENNT */ +#else +# define procenv_t jmp_buf +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/readline-4.3/posixstat.h b/readline-4.3/posixstat.h new file mode 100644 index 0000000..c93b528 --- /dev/null +++ b/readline-4.3/posixstat.h @@ -0,0 +1,142 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/readline-4.3/readline.c b/readline-4.3/readline.c new file mode 100644 index 0000000..28801f1 --- /dev/null +++ b/readline-4.3/readline.c @@ -0,0 +1,973 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include +#include "posixjmp.h" + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#ifndef RL_LIBRARY_VERSION +# define RL_LIBRARY_VERSION "4.3" +#endif + +#ifndef RL_READLINE_VERSION +# define RL_READLINE_VERSION 0x0403 +#endif + +extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +/* Forward declarations used in this file. */ +static char *readline_internal PARAMS((void)); +static void readline_initialize_everything PARAMS((void)); + +static void bind_arrow_keys_internal PARAMS((Keymap)); +static void bind_arrow_keys PARAMS((void)); + +static void readline_default_bindings PARAMS((void)); + +/* **************************************************************** */ +/* */ +/* Line editing input utility */ +/* */ +/* **************************************************************** */ + +const char *rl_library_version = RL_LIBRARY_VERSION; + +int rl_readline_version = RL_READLINE_VERSION; + +/* True if this is `real' readline as opposed to some stub substitute. */ +int rl_gnu_readline_p = 1; + +/* A pointer to the keymap that is currently in use. + 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; + +/* The current insert mode: input (the default) or overwrite */ +int rl_insert_mode = RL_IM_DEFAULT; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +int rl_dispatching; + +/* Non-zero if the previous command was a kill command. */ +int _rl_last_command_was_kill = 0; + +/* The current value of the numeric argument specified by the user. */ +int rl_numeric_arg = 1; + +/* Non-zero if an argument was typed. */ +int rl_explicit_arg = 0; + +/* Temporary value used while generating the argument. */ +int rl_arg_sign = 1; + +/* Non-zero means we have been called at least once before. */ +static int rl_initialized; + +#if 0 +/* If non-zero, this program is running in an EMACS buffer. */ +static int running_in_emacs; +#endif + +/* Flags word encapsulating the current readline state. */ +int rl_readline_state = RL_STATE_NONE; + +/* The current offset in the current input line. */ +int rl_point; + +/* Mark in the current input line. */ +int rl_mark; + +/* Length of the current input line. */ +int rl_end; + +/* Make this non-zero to return the current input_line. */ +int rl_done; + +/* The last function executed by readline. */ +rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL; + +/* Top level environment for readline_internal (). */ +procenv_t readline_top_level; + +/* The streams we interact with. */ +FILE *_rl_in_stream, *_rl_out_stream; + +/* The names of the streams that we do input and output to. */ +FILE *rl_instream = (FILE *)NULL; +FILE *rl_outstream = (FILE *)NULL; + +/* Non-zero means echo characters as they are read. Defaults to no echo; + set to 1 if there is a controlling terminal, we can get its attributes, + and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings + for the code that sets it. */ +int readline_echoing_p = 0; + +/* Current prompt. */ +char *rl_prompt = (char *)NULL; +int rl_visible_prompt_length = 0; + +/* Set to non-zero by calling application if it has already printed rl_prompt + and does not want readline to do it the first time. */ +int rl_already_prompted = 0; + +/* The number of characters read in order to type this complete command. */ +int rl_key_sequence_length = 0; + +/* If non-zero, then this is the address of a function to call just + before readline_internal_setup () prints the first prompt. */ +rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL; + +/* What we use internally. You should always refer to RL_LINE_BUFFER. */ +static char *the_line; + +/* The character that can generate an EOF. Really read from + the terminal driver... just defaulted here. */ +int _rl_eof_char = CTRL ('D'); + +/* Non-zero makes this the next keystroke to read. */ +int rl_pending_input = 0; + +/* Pointer to a useful terminal name. */ +const char *rl_terminal_name = (const char *)NULL; + +/* Non-zero means to always use horizontal scrolling in line display. */ +int _rl_horizontal_scroll_mode = 0; + +/* Non-zero means to display an asterisk at the starts of history lines + which have been modified. */ +int _rl_mark_modified_lines = 0; + +/* The style of `bell' notification preferred. This can be set to NO_BELL, + AUDIBLE_BELL, or VISIBLE_BELL. */ +int _rl_bell_preference = AUDIBLE_BELL; + +/* String inserted into the line by rl_insert_comment (). */ +char *_rl_comment_begin; + +/* Keymap holding the function currently being executed. */ +Keymap rl_executing_keymap; + +/* Non-zero means to erase entire line, including prompt, on empty input lines. */ +int rl_erase_empty_line = 0; + +/* Non-zero means to read only this many characters rather than up to a + character bound to accept-line. */ +int rl_num_chars_to_read; + +/* Line buffer and maintenence. */ +char *rl_line_buffer = (char *)NULL; +int rl_line_buffer_len = 0; + +/* Forward declarations used by the display, termcap, and history code. */ + +/* **************************************************************** */ +/* */ +/* `Forward' declarations */ +/* */ +/* **************************************************************** */ + +/* Non-zero means do not parse any lines other than comments and + parser directives. */ +unsigned char _rl_parsing_conditionalized_out = 0; + +/* Non-zero means to convert characters with the meta bit set to + escape-prefixed characters so we can indirect through + emacs_meta_keymap or vi_escape_keymap. */ +int _rl_convert_meta_chars_to_ascii = 1; + +/* Non-zero means to output characters with the meta bit set directly + rather than as a meta-prefixed escape sequence. */ +int _rl_output_meta_chars = 0; + +/* **************************************************************** */ +/* */ +/* Top Level Functions */ +/* */ +/* **************************************************************** */ + +/* Non-zero means treat 0200 bit in terminal input as Meta bit. */ +int _rl_meta_flag = 0; /* Forward declaration */ + +/* Set up the prompt and expand it. Called from readline() and + rl_callback_handler_install (). */ +int +rl_set_prompt (prompt) + const char *prompt; +{ + FREE (rl_prompt); + rl_prompt = prompt ? savestring (prompt) : (char *)NULL; + + rl_visible_prompt_length = rl_expand_prompt (rl_prompt); + return 0; +} + +/* Read a line of input. Prompt with PROMPT. An empty PROMPT means + none. A return value of NULL means that EOF was encountered. */ +char * +readline (prompt) + const char *prompt; +{ + char *value; + + /* If we are at EOF return a NULL string. */ + if (rl_pending_input == EOF) + { + rl_clear_pending_input (); + return ((char *)NULL); + } + + rl_set_prompt (prompt); + + rl_initialize (); + (*rl_prep_term_function) (_rl_meta_flag); + +#if defined (HANDLE_SIGNALS) + rl_set_signals (); +#endif + + value = readline_internal (); + (*rl_deprep_term_function) (); + +#if defined (HANDLE_SIGNALS) + rl_clear_signals (); +#endif + + return (value); +} + +#if defined (READLINE_CALLBACKS) +# define STATIC_CALLBACK +#else +# define STATIC_CALLBACK static +#endif + +STATIC_CALLBACK void +readline_internal_setup () +{ + char *nprompt; + + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + if (rl_startup_hook) + (*rl_startup_hook) (); + + /* If we're not echoing, we still want to at least print a prompt, because + rl_redisplay will not do it for us. If the calling application has a + custom redisplay function, though, let that function handle it. */ + if (readline_echoing_p == 0 && rl_redisplay_function == rl_redisplay) + { + if (rl_prompt && rl_already_prompted == 0) + { + nprompt = _rl_strip_prompt (rl_prompt); + fprintf (_rl_out_stream, "%s", nprompt); + fflush (_rl_out_stream); + free (nprompt); + } + } + else + { + if (rl_prompt && rl_already_prompted) + rl_on_new_line_with_prompt (); + else + rl_on_new_line (); + (*rl_redisplay_function) (); + } + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + rl_vi_insertion_mode (1, 0); +#endif /* VI_MODE */ + + if (rl_pre_input_hook) + (*rl_pre_input_hook) (); +} + +STATIC_CALLBACK char * +readline_internal_teardown (eof) + int eof; +{ + char *temp; + HIST_ENTRY *entry; + + /* Restore the original of this history line, iff the line that we + are editing was originally in the history, AND the line has changed. */ + entry = current_history (); + + if (entry && rl_undo_list) + { + temp = savestring (the_line); + rl_revert_line (1, 0); + entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL); + _rl_free_history_entry (entry); + + strcpy (the_line, temp); + free (temp); + } + + /* At any rate, it is highly likely that this line has an undo list. Get + rid of it now. */ + if (rl_undo_list) + rl_free_undo_list (); + + /* Restore normal cursor, if available. */ + _rl_set_insert_mode (RL_IM_INSERT, 0); + + return (eof ? (char *)NULL : savestring (the_line)); +} + +STATIC_CALLBACK int +#if defined (READLINE_CALLBACKS) +readline_internal_char () +#else +readline_internal_charloop () +#endif +{ + static int lastc, eof_found; + int c, code, lk; + + lastc = -1; + eof_found = 0; + +#if !defined (READLINE_CALLBACKS) + while (rl_done == 0) + { +#endif + lk = _rl_last_command_was_kill; + + code = setjmp (readline_top_level); + + if (code) + (*rl_redisplay_function) (); + + if (rl_pending_input == 0) + { + /* Then initialize the argument and number of keys read. */ + _rl_init_argument (); + rl_key_sequence_length = 0; + } + + RL_SETSTATE(RL_STATE_READCMD); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_READCMD); + + /* EOF typed to a non-blank line is a . */ + if (c == EOF && rl_end) + c = NEWLINE; + + /* The character _rl_eof_char typed to blank line, and not as the + previous character is interpreted as EOF. */ + if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end) + { +#if defined (READLINE_CALLBACKS) + RL_SETSTATE(RL_STATE_DONE); + return (rl_done = 1); +#else + eof_found = 1; + break; +#endif + } + + lastc = c; + _rl_dispatch ((unsigned char)c, _rl_keymap); + + /* If there was no change in _rl_last_command_was_kill, then no kill + has taken place. Note that if input is pending we are reading + a prefix command, so nothing has changed yet. */ + 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 (); + +#if defined (READLINE_CALLBACKS) + return 0; +#else + } + + return (eof_found); +#endif +} + +#if defined (READLINE_CALLBACKS) +static int +readline_internal_charloop () +{ + int eof = 1; + + while (rl_done == 0) + eof = readline_internal_char (); + return (eof); +} +#endif /* READLINE_CALLBACKS */ + +/* Read a line of input from the global rl_instream, doing output on + the global rl_outstream. + If rl_prompt is non-null, then that is our prompt. */ +static char * +readline_internal () +{ + int eof; + + readline_internal_setup (); + eof = readline_internal_charloop (); + return (readline_internal_teardown (eof)); +} + +void +_rl_init_line_state () +{ + rl_point = rl_end = rl_mark = 0; + the_line = rl_line_buffer; + the_line[0] = 0; +} + +void +_rl_set_the_line () +{ + the_line = rl_line_buffer; +} + +/* 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. */ +int +_rl_dispatch (key, map) + register int key; + Keymap map; +{ + return _rl_dispatch_subseq (key, map, 0); +} + +int +_rl_dispatch_subseq (key, map, got_subseq) + register int key; + Keymap map; + int got_subseq; +{ + int r, newkey; + char *macro; + rl_command_func_t *func; + + if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) + { + if (map[ESC].type == ISKMAP) + { + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (ESC); + map = FUNCTION_TO_KEYMAP (map, ESC); + key = UNMETA (key); + rl_key_sequence_length += 2; + return (_rl_dispatch (key, map)); + } + else + rl_ding (); + return 0; + } + + if (RL_ISSTATE (RL_STATE_MACRODEF)) + _rl_add_macro_char (key); + + r = 0; + switch (map[key].type) + { + case ISFUNC: + func = map[key].function; + if (func) + { + /* Special case rl_do_lowercase_version (). */ + if (func == rl_do_lowercase_version) + return (_rl_dispatch (_rl_to_lower (key), map)); + + 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); + RL_UNSETSTATE(RL_STATE_DISPATCHING); + rl_dispatching = 0; + + /* If we have input pending, then the last command was a prefix + command. Don't change the state of rl_last_func. Otherwise, + remember the last command executed in this variable. */ + if (rl_pending_input == 0 && map[key].function != rl_digit_argument) + rl_last_func = map[key].function; + } + else if (map[ANYOTHERKEY].function) + { + /* OK, there's no function bound in this map, but there is a + shadow function that was overridden when the current keymap + was created. Return -2 to note that. */ + _rl_unget_char (key); + return -2; + } + else if (got_subseq) + { + /* Return -1 to note that we're in a subsequence, but we don't + have a matching key, nor was one overridden. This means + we need to back up the recursion chain and find the last + subsequence that is bound to a function. */ + _rl_unget_char (key); + return -1; + } + else + { + _rl_abort_internal (); + return -1; + } + break; + + case ISKMAP: + if (map[key].function != 0) + { +#if defined (VI_MODE) + /* The only way this test will be true is if a subsequence has been + bound starting with ESC, generally the arrow keys. What we do is + check whether there's input in the queue, which there generally + will be if an arrow key has been pressed, and, if there's not, + just dispatch to (what we assume is) rl_vi_movement_mode right + away. This is essentially an input test with a zero timeout. */ + if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap + && _rl_input_queued (0) == 0) + return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); +#endif + + rl_key_sequence_length++; + + 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); + + 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; + } + } + else + { + _rl_abort_internal (); + return -1; + } + break; + + case ISMACR: + if (map[key].function != 0) + { + macro = savestring ((char *)map[key].function); + _rl_with_macro_input (macro); + return 0; + } + break; + } +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && + _rl_vi_textmod_command (key)) + _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); +#endif + return (r); +} + +/* **************************************************************** */ +/* */ +/* Initializations */ +/* */ +/* **************************************************************** */ + +/* Initialize readline (and terminal if not already). */ +int +rl_initialize () +{ + /* If we have never been called before, initialize the + terminal and data structures. */ + if (!rl_initialized) + { + RL_SETSTATE(RL_STATE_INITIALIZING); + readline_initialize_everything (); + RL_UNSETSTATE(RL_STATE_INITIALIZING); + rl_initialized++; + RL_SETSTATE(RL_STATE_INITIALIZED); + } + + /* Initalize the current line information. */ + _rl_init_line_state (); + + /* We aren't done yet. We haven't even gotten started yet! */ + rl_done = 0; + RL_UNSETSTATE(RL_STATE_DONE); + + /* Tell the history routines what is going on. */ + _rl_start_using_history (); + + /* Make the display buffer match the state of the line. */ + rl_reset_line_state (); + + /* No such function typed yet. */ + rl_last_func = (rl_command_func_t *)NULL; + + /* Parsing of key-bindings begins in an enabled state. */ + _rl_parsing_conditionalized_out = 0; + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + _rl_vi_initialize_line (); +#endif + + /* Each line starts in insert mode (the default). */ + _rl_set_insert_mode (RL_IM_DEFAULT, 1); + + return 0; +} + +#if 0 +#if defined (__EMX__) +static void +_emx_build_environ () +{ + TIB *tibp; + PIB *pibp; + char *t, **tp; + int c; + + DosGetInfoBlocks (&tibp, &pibp); + t = pibp->pib_pchenv; + for (c = 1; *t; c++) + t += strlen (t) + 1; + tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *)); + t = pibp->pib_pchenv; + while (*t) + { + *tp++ = t; + t += strlen (t) + 1; + } + *tp = 0; +} +#endif /* __EMX__ */ +#endif + +/* Initialize the entire state of the world. */ +static void +readline_initialize_everything () +{ +#if 0 +#if defined (__EMX__) + if (environ == 0) + _emx_build_environ (); +#endif +#endif + +#if 0 + /* Find out if we are running in Emacs -- UNUSED. */ + running_in_emacs = sh_get_env_value ("EMACS") != (char *)0; +#endif + + /* Set up input and output if they are not already set up. */ + if (!rl_instream) + rl_instream = stdin; + + if (!rl_outstream) + rl_outstream = stdout; + + /* Bind _rl_in_stream and _rl_out_stream immediately. These values + may change, but they may also be used before readline_internal () + is called. */ + _rl_in_stream = rl_instream; + _rl_out_stream = rl_outstream; + + /* Allocate data structures. */ + if (rl_line_buffer == 0) + rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE); + + /* Initialize the terminal interface. */ + if (rl_terminal_name == 0) + rl_terminal_name = sh_get_env_value ("TERM"); + _rl_init_terminal_io (rl_terminal_name); + + /* Bind tty characters to readline functions. */ + readline_default_bindings (); + + /* Initialize the function names. */ + rl_initialize_funmap (); + + /* Decide whether we should automatically go into eight-bit mode. */ + _rl_init_eightbit (); + + /* Read in the init file. */ + rl_read_init_file ((char *)NULL); + + /* XXX */ + if (_rl_horizontal_scroll_mode && _rl_term_autowrap) + { + _rl_screenwidth--; + _rl_screenchars -= _rl_screenheight; + } + + /* Override the effect of any `set keymap' assignments in the + inputrc file. */ + rl_set_keymap_from_edit_mode (); + + /* Try to bind a common arrow key prefix, if not already bound. */ + bind_arrow_keys (); + + /* Enable the meta key, if this terminal has one. */ + if (_rl_enable_meta) + _rl_enable_meta_key (); + + /* 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; +} + +/* If this system allows us to look at the values of the regular + input editing characters, then bind them to their readline + equivalents, iff the characters are not bound to keymaps. */ +static void +readline_default_bindings () +{ + rl_tty_set_default_bindings (_rl_keymap); +} + +/* Bind some common arrow key sequences in MAP. */ +static void +bind_arrow_keys_internal (map) + Keymap map; +{ + Keymap xkeymap; + + xkeymap = _rl_keymap; + _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); +#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; +} + +/* Try and bind the common arrow key prefixes after giving termcap and + the inputrc file a chance to bind them and create `real' keymaps + for the arrow key prefix. */ +static void +bind_arrow_keys () +{ + bind_arrow_keys_internal (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_arrow_keys_internal (vi_movement_keymap); + bind_arrow_keys_internal (vi_insertion_keymap); +#endif +} + +/* **************************************************************** */ +/* */ +/* Saving and Restoring Readline's state */ +/* */ +/* **************************************************************** */ + +int +rl_save_state (sp) + struct readline_state *sp; +{ + if (sp == 0) + return -1; + + sp->point = rl_point; + sp->end = rl_end; + sp->mark = rl_mark; + sp->buffer = rl_line_buffer; + sp->buflen = rl_line_buffer_len; + sp->ul = rl_undo_list; + sp->prompt = rl_prompt; + + sp->rlstate = rl_readline_state; + sp->done = rl_done; + sp->kmap = _rl_keymap; + + sp->lastfunc = rl_last_func; + sp->insmode = rl_insert_mode; + sp->edmode = rl_editing_mode; + sp->kseqlen = rl_key_sequence_length; + sp->inf = rl_instream; + sp->outf = rl_outstream; + sp->pendingin = rl_pending_input; + sp->macro = rl_executing_macro; + + sp->catchsigs = rl_catch_signals; + sp->catchsigwinch = rl_catch_sigwinch; + + return (0); +} + +int +rl_restore_state (sp) + struct readline_state *sp; +{ + if (sp == 0) + return -1; + + rl_point = sp->point; + rl_end = sp->end; + rl_mark = sp->mark; + the_line = rl_line_buffer = sp->buffer; + rl_line_buffer_len = sp->buflen; + rl_undo_list = sp->ul; + rl_prompt = sp->prompt; + + rl_readline_state = sp->rlstate; + rl_done = sp->done; + _rl_keymap = sp->kmap; + + rl_last_func = sp->lastfunc; + rl_insert_mode = sp->insmode; + rl_editing_mode = sp->edmode; + rl_key_sequence_length = sp->kseqlen; + rl_instream = sp->inf; + rl_outstream = sp->outf; + rl_pending_input = sp->pendingin; + rl_executing_macro = sp->macro; + + rl_catch_signals = sp->catchsigs; + rl_catch_sigwinch = sp->catchsigwinch; + + return (0); +} diff --git a/readline-4.3/readline.h b/readline-4.3/readline.h new file mode 100644 index 0000000..f11b3d0 --- /dev/null +++ b/readline-4.3/readline.h @@ -0,0 +1,799 @@ +/* Readline.h -- the names of functions callable from within readline. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_READLINE_H_) +#define _READLINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +# include "rltypedefs.h" +# include "keymaps.h" +# include "tilde.h" +#else +# include +# include +# include +# include +#endif + +/* Hex-encoded Readline version number. */ +#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */ +#define RL_VERSION_MAJOR 4 +#define RL_VERSION_MINOR 3 + +/* Readline data structures. */ + +/* Maintaining the state of undo. We remember individual deletes and inserts + on a chain of things to do. */ + +/* The actions that undo knows how to undo. Notice that UNDO_DELETE means + to insert some text, and UNDO_INSERT means to delete some text. I.e., + the code tells undo what to undo, not how to undo it. */ +enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + +/* What an element of THE_UNDO_LIST looks like. */ +typedef struct undo_list { + struct undo_list *next; + int start, end; /* Where the change took place. */ + char *text; /* The text to insert, if undoing a delete. */ + enum undo_code what; /* Delete, Insert, Begin, End. */ +} UNDO_LIST; + +/* The current undo list for RL_LINE_BUFFER. */ +extern UNDO_LIST *rl_undo_list; + +/* The data structure for mapping textual names to code addresses. */ +typedef struct _funmap { + const char *name; + rl_command_func_t *function; +} FUNMAP; + +extern FUNMAP **funmap; + +/* **************************************************************** */ +/* */ +/* Functions available to bind to key sequences */ +/* */ +/* **************************************************************** */ + +/* Bindable commands for numeric arguments. */ +extern int rl_digit_argument PARAMS((int, int)); +extern int rl_universal_argument PARAMS((int, int)); + +/* Bindable commands for moving the cursor. */ +extern int rl_forward_byte PARAMS((int, int)); +extern int rl_forward_char PARAMS((int, int)); +extern int rl_forward PARAMS((int, int)); +extern int rl_backward_byte PARAMS((int, int)); +extern int rl_backward_char PARAMS((int, int)); +extern int rl_backward PARAMS((int, int)); +extern int rl_beg_of_line PARAMS((int, int)); +extern int rl_end_of_line PARAMS((int, int)); +extern int rl_forward_word PARAMS((int, int)); +extern int rl_backward_word PARAMS((int, int)); +extern int rl_refresh_line PARAMS((int, int)); +extern int rl_clear_screen PARAMS((int, int)); +extern int rl_arrow_keys PARAMS((int, int)); + +/* Bindable commands for inserting and deleting text. */ +extern int rl_insert PARAMS((int, int)); +extern int rl_quoted_insert PARAMS((int, int)); +extern int rl_tab_insert PARAMS((int, int)); +extern int rl_newline PARAMS((int, int)); +extern int rl_do_lowercase_version PARAMS((int, int)); +extern int rl_rubout PARAMS((int, int)); +extern int rl_delete PARAMS((int, int)); +extern int rl_rubout_or_delete PARAMS((int, int)); +extern int rl_delete_horizontal_space PARAMS((int, int)); +extern int rl_delete_or_show_completions PARAMS((int, int)); +extern int rl_insert_comment PARAMS((int, int)); + +/* Bindable commands for changing case. */ +extern int rl_upcase_word PARAMS((int, int)); +extern int rl_downcase_word PARAMS((int, int)); +extern int rl_capitalize_word PARAMS((int, int)); + +/* Bindable commands for transposing characters and words. */ +extern int rl_transpose_words PARAMS((int, int)); +extern int rl_transpose_chars PARAMS((int, int)); + +/* Bindable commands for searching within a line. */ +extern int rl_char_search PARAMS((int, int)); +extern int rl_backward_char_search PARAMS((int, int)); + +/* Bindable commands for readline's interface to the command history. */ +extern int rl_beginning_of_history PARAMS((int, int)); +extern int rl_end_of_history PARAMS((int, int)); +extern int rl_get_next_history PARAMS((int, int)); +extern int rl_get_previous_history PARAMS((int, int)); + +/* Bindable commands for managing the mark and region. */ +extern int rl_set_mark PARAMS((int, int)); +extern int rl_exchange_point_and_mark PARAMS((int, int)); + +/* Bindable commands to set the editing mode (emacs or vi). */ +extern int rl_vi_editing_mode PARAMS((int, int)); +extern int rl_emacs_editing_mode PARAMS((int, int)); + +/* Bindable commands to change the insert mode (insert or overwrite) */ +extern int rl_overwrite_mode PARAMS((int, int)); + +/* Bindable commands for managing key bindings. */ +extern int rl_re_read_init_file PARAMS((int, int)); +extern int rl_dump_functions PARAMS((int, int)); +extern int rl_dump_macros PARAMS((int, int)); +extern int rl_dump_variables PARAMS((int, int)); + +/* Bindable commands for word completion. */ +extern int rl_complete PARAMS((int, int)); +extern int rl_possible_completions PARAMS((int, int)); +extern int rl_insert_completions PARAMS((int, int)); +extern int rl_menu_complete PARAMS((int, int)); + +/* Bindable commands for killing and yanking text, and managing the kill ring. */ +extern int rl_kill_word PARAMS((int, int)); +extern int rl_backward_kill_word PARAMS((int, int)); +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_line_discard PARAMS((int, int)); +extern int rl_copy_region_to_kill PARAMS((int, int)); +extern int rl_kill_region PARAMS((int, int)); +extern int rl_copy_forward_word PARAMS((int, int)); +extern int rl_copy_backward_word PARAMS((int, int)); +extern int rl_yank PARAMS((int, int)); +extern int rl_yank_pop PARAMS((int, int)); +extern int rl_yank_nth_arg PARAMS((int, int)); +extern int rl_yank_last_arg PARAMS((int, int)); +/* Not available unless __CYGWIN__ is defined. */ +#ifdef __CYGWIN__ +extern int rl_paste_from_clipboard PARAMS((int, int)); +#endif + +/* Bindable commands for incremental searching. */ +extern int rl_reverse_search_history PARAMS((int, int)); +extern int rl_forward_search_history PARAMS((int, int)); + +/* Bindable keyboard macro commands. */ +extern int rl_start_kbd_macro PARAMS((int, int)); +extern int rl_end_kbd_macro PARAMS((int, int)); +extern int rl_call_last_kbd_macro PARAMS((int, int)); + +/* Bindable undo commands. */ +extern int rl_revert_line PARAMS((int, int)); +extern int rl_undo_command PARAMS((int, int)); + +/* Bindable tilde expansion commands. */ +extern int rl_tilde_expand PARAMS((int, int)); + +/* Bindable terminal control commands. */ +extern int rl_restart_output PARAMS((int, int)); +extern int rl_stop_output PARAMS((int, int)); + +/* Miscellaneous bindable commands. */ +extern int rl_abort PARAMS((int, int)); +extern int rl_tty_status PARAMS((int, int)); + +/* Bindable commands for incremental and non-incremental history searching. */ +extern int rl_history_search_forward PARAMS((int, int)); +extern int rl_history_search_backward PARAMS((int, int)); +extern int rl_noninc_forward_search PARAMS((int, int)); +extern int rl_noninc_reverse_search PARAMS((int, int)); +extern int rl_noninc_forward_search_again PARAMS((int, int)); +extern int rl_noninc_reverse_search_again PARAMS((int, int)); + +/* Bindable command used when inserting a matching close character. */ +extern int rl_insert_close PARAMS((int, int)); + +/* Not available unless READLINE_CALLBACKS is defined. */ +extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *)); +extern void rl_callback_read_char PARAMS((void)); +extern void rl_callback_handler_remove PARAMS((void)); + +/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ +/* VI-mode bindable commands. */ +extern int rl_vi_redo PARAMS((int, int)); +extern int rl_vi_undo PARAMS((int, int)); +extern int rl_vi_yank_arg PARAMS((int, int)); +extern int rl_vi_fetch_history PARAMS((int, int)); +extern int rl_vi_search_again PARAMS((int, int)); +extern int rl_vi_search PARAMS((int, int)); +extern int rl_vi_complete PARAMS((int, int)); +extern int rl_vi_tilde_expand PARAMS((int, int)); +extern int rl_vi_prev_word PARAMS((int, int)); +extern int rl_vi_next_word PARAMS((int, int)); +extern int rl_vi_end_word PARAMS((int, int)); +extern int rl_vi_insert_beg PARAMS((int, int)); +extern int rl_vi_append_mode PARAMS((int, int)); +extern int rl_vi_append_eol PARAMS((int, int)); +extern int rl_vi_eof_maybe PARAMS((int, int)); +extern int rl_vi_insertion_mode PARAMS((int, int)); +extern int rl_vi_movement_mode PARAMS((int, int)); +extern int rl_vi_arg_digit PARAMS((int, int)); +extern int rl_vi_change_case PARAMS((int, int)); +extern int rl_vi_put PARAMS((int, int)); +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_delete PARAMS((int, int)); +extern int rl_vi_back_to_indent PARAMS((int, int)); +extern int rl_vi_first_print PARAMS((int, int)); +extern int rl_vi_char_search PARAMS((int, int)); +extern int rl_vi_match PARAMS((int, int)); +extern int rl_vi_change_char PARAMS((int, int)); +extern int rl_vi_subst PARAMS((int, int)); +extern int rl_vi_overstrike PARAMS((int, int)); +extern int rl_vi_overstrike_delete PARAMS((int, int)); +extern int rl_vi_replace PARAMS((int, int)); +extern int rl_vi_set_mark PARAMS((int, int)); +extern int rl_vi_goto_mark PARAMS((int, int)); + +/* VI-mode utility functions. */ +extern int rl_vi_check PARAMS((void)); +extern int rl_vi_domove PARAMS((int, int *)); +extern int rl_vi_bracktype PARAMS((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)); +extern int rl_vi_eWord PARAMS((int, int)); +extern int rl_vi_fword PARAMS((int, int)); +extern int rl_vi_bword PARAMS((int, int)); +extern int rl_vi_eword PARAMS((int, int)); + +/* **************************************************************** */ +/* */ +/* Well Published Functions */ +/* */ +/* **************************************************************** */ + +/* Readline functions. */ +/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ +extern char *readline PARAMS((const char *)); + +extern int rl_set_prompt PARAMS((const char *)); +extern int rl_expand_prompt PARAMS((char *)); + +extern int rl_initialize PARAMS((void)); + +/* Undocumented; unused by readline */ +extern int rl_discard_argument PARAMS((void)); + +/* Utility functions to bind keys to readline commands. */ +extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int)); +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_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_generic_bind PARAMS((int, const char *, char *, Keymap)); +extern int rl_variable_bind PARAMS((const char *, const char *)); + +/* Backwards compatibility, use rl_generic_bind instead. */ +extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); + +/* Undocumented in the texinfo manual; not really useful to programs. */ +extern int rl_translate_keyseq PARAMS((const char *, char *, int *)); +extern char *rl_untranslate_keyseq PARAMS((int)); + +extern rl_command_func_t *rl_named_function PARAMS((const char *)); +extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *)); + +extern void rl_list_funmap_names PARAMS((void)); +extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap)); +extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *)); + +extern void rl_function_dumper PARAMS((int)); +extern void rl_macro_dumper PARAMS((int)); +extern void rl_variable_dumper PARAMS((int)); + +extern int rl_read_init_file PARAMS((const char *)); +extern int rl_parse_and_bind PARAMS((char *)); + +/* Functions for manipulating keymaps. */ +extern Keymap rl_make_bare_keymap PARAMS((void)); +extern Keymap rl_copy_keymap PARAMS((Keymap)); +extern Keymap rl_make_keymap PARAMS((void)); +extern void rl_discard_keymap PARAMS((Keymap)); + +extern Keymap rl_get_keymap_by_name PARAMS((const char *)); +extern char *rl_get_keymap_name PARAMS((Keymap)); +extern void rl_set_keymap PARAMS((Keymap)); +extern Keymap rl_get_keymap PARAMS((void)); +/* Undocumented; used internally only. */ +extern void rl_set_keymap_from_edit_mode PARAMS((void)); +extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); + +/* Functions for manipulating the funmap, which maps command names to functions. */ +extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); +extern const char **rl_funmap_names PARAMS((void)); +/* Undocumented, only used internally -- there is only one funmap, and this + function may be called only once. */ +extern void rl_initialize_funmap PARAMS((void)); + +/* Utility functions for managing keyboard macros. */ +extern void rl_push_macro_input PARAMS((char *)); + +/* Functions for undoing, from undo.c */ +extern void rl_add_undo PARAMS((enum undo_code, int, int, char *)); +extern void rl_free_undo_list PARAMS((void)); +extern int rl_do_undo PARAMS((void)); +extern int rl_begin_undo_group PARAMS((void)); +extern int rl_end_undo_group PARAMS((void)); +extern int rl_modifying PARAMS((int, int)); + +/* Functions for redisplay. */ +extern void rl_redisplay PARAMS((void)); +extern int rl_on_new_line PARAMS((void)); +extern int rl_on_new_line_with_prompt PARAMS((void)); +extern int rl_forced_update_display PARAMS((void)); +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) +extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); +#else +extern int rl_message (); +#endif + +extern int rl_show_char PARAMS((int)); + +/* Undocumented in texinfo manual. */ +extern int rl_character_len PARAMS((int, int)); + +/* Save and restore internal prompt redisplay information. */ +extern void rl_save_prompt PARAMS((void)); +extern void rl_restore_prompt PARAMS((void)); + +/* Modifying text. */ +extern void rl_replace_line PARAMS((const char *, int)); +extern int rl_insert_text PARAMS((const char *)); +extern int rl_delete_text PARAMS((int, int)); +extern int rl_kill_text PARAMS((int, int)); +extern char *rl_copy_text PARAMS((int, int)); + +/* Terminal and tty mode management. */ +extern void rl_prep_terminal PARAMS((int)); +extern void rl_deprep_terminal PARAMS((void)); +extern void rl_tty_set_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 char *rl_get_termcap PARAMS((const char *)); + +/* Functions for character input. */ +extern int rl_stuff_char PARAMS((int)); +extern int rl_execute_next PARAMS((int)); +extern int rl_clear_pending_input PARAMS((void)); +extern int rl_read_key PARAMS((void)); +extern int rl_getc PARAMS((FILE *)); +extern int rl_set_keyboard_input_timeout PARAMS((int)); + +/* `Public' utility functions . */ +extern void rl_extend_line_buffer PARAMS((int)); +extern int rl_ding PARAMS((void)); +extern int rl_alphabetic PARAMS((int)); + +/* Readline signal handling, from signals.c */ +extern int rl_set_signals PARAMS((void)); +extern int rl_clear_signals PARAMS((void)); +extern void rl_cleanup_after_signal PARAMS((void)); +extern void rl_reset_after_signal PARAMS((void)); +extern void rl_free_line_state PARAMS((void)); + +extern int rl_set_paren_blink_timeout PARAMS((int)); + +/* Undocumented. */ +extern int rl_maybe_save_line PARAMS((void)); +extern int rl_maybe_unsave_line PARAMS((void)); +extern int rl_maybe_replace_line PARAMS((void)); + +/* Completion functions. */ +extern int rl_complete_internal PARAMS((int)); +extern void rl_display_match_list PARAMS((char **, int, int)); + +extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *)); +extern char *rl_username_completion_function PARAMS((const char *, int)); +extern char *rl_filename_completion_function PARAMS((const char *, int)); + +extern int rl_completion_mode PARAMS((rl_command_func_t *)); + +#if 0 +/* Backwards compatibility (compat.c). These will go away sometime. */ +extern void free_undo_list PARAMS((void)); +extern int maybe_save_line PARAMS((void)); +extern int maybe_unsave_line PARAMS((void)); +extern int maybe_replace_line PARAMS((void)); + +extern int ding PARAMS((void)); +extern int alphabetic PARAMS((int)); +extern int crlf PARAMS((void)); + +extern char **completion_matches PARAMS((char *, rl_compentry_func_t *)); +extern char *username_completion_function PARAMS((const char *, int)); +extern char *filename_completion_function PARAMS((const char *, int)); +#endif + +/* **************************************************************** */ +/* */ +/* Well Published Variables */ +/* */ +/* **************************************************************** */ + +/* The version of this incarnation of the readline library. */ +extern const char *rl_library_version; /* e.g., "4.2" */ +extern int rl_readline_version; /* e.g., 0x0402 */ + +/* True if this is real GNU readline. */ +extern int rl_gnu_readline_p; + +/* Flags word encapsulating the current readline state. */ +extern int rl_readline_state; + +/* Says which editing mode readline is currently using. 1 means emacs mode; + 0 means vi mode. */ +extern int rl_editing_mode; + +/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means + overwrite mode. Reset to insert mode on each input line. */ +extern int rl_insert_mode; + +/* The name of the calling program. You should initialize this to + whatever was in argv[0]. It is used when parsing conditionals. */ +extern const char *rl_readline_name; + +/* The prompt readline uses. This is set from the argument to + readline (), and should not be assigned to directly. */ +extern char *rl_prompt; + +/* The line buffer that is in use. */ +extern char *rl_line_buffer; + +/* The location of point, and end. */ +extern int rl_point; +extern int rl_end; + +/* The mark, or saved cursor position. */ +extern int rl_mark; + +/* Flag to indicate that readline has finished with the current input + line and should return it. */ +extern int rl_done; + +/* If set to a character value, that will be the next keystroke read. */ +extern int rl_pending_input; + +/* Non-zero if we called this function from _rl_dispatch(). It's present + so functions can find out whether they were called from a key binding + or directly from an application. */ +extern int rl_dispatching; + +/* Non-zero if the user typed a numeric argument before executing the + current function. */ +extern int rl_explicit_arg; + +/* The current value of the numeric argument specified by the user. */ +extern int rl_numeric_arg; + +/* The address of the last command function Readline executed. */ +extern rl_command_func_t *rl_last_func; + +/* The name of the terminal to use. */ +extern const char *rl_terminal_name; + +/* The input and output streams. */ +extern FILE *rl_instream; +extern FILE *rl_outstream; + +/* 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; + +/* If non-zero, this is the address of a function to call just before + readline_internal_setup () returns and readline_internal starts + reading input characters. */ +extern rl_hook_func_t *rl_pre_input_hook; + +/* The address of a function to call periodically while Readline is + awaiting character input, or NULL, for no event handling. */ +extern rl_hook_func_t *rl_event_hook; + +/* The address of the function to call to fetch a character from the current + Readline input stream */ +extern rl_getc_func_t *rl_getc_function; + +extern rl_voidfunc_t *rl_redisplay_function; + +extern rl_vintfunc_t *rl_prep_term_function; +extern rl_voidfunc_t *rl_deprep_term_function; + +/* Dispatch variables. */ +extern Keymap rl_executing_keymap; +extern Keymap rl_binding_keymap; + +/* Display variables. */ +/* If non-zero, readline will erase the entire line, including any prompt, + if the only thing typed on an otherwise-blank line is something bound to + rl_newline. */ +extern int rl_erase_empty_line; + +/* If non-zero, the application has already printed the prompt (rl_prompt) + before calling readline, so readline should not output it the first time + redisplay is done. */ +extern int rl_already_prompted; + +/* A non-zero value means to read only this many characters rather than + up to a character bound to accept-line. */ +extern int rl_num_chars_to_read; + +/* The text of a currently-executing keyboard macro. */ +extern char *rl_executing_macro; + +/* Variables to control readline signal handling. */ +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +extern int rl_catch_signals; + +/* If non-zero, readline will install a signal handler for SIGWINCH + that also attempts to call any calling application's SIGWINCH signal + handler. Note that the terminal is not cleaned up before the + application's signal handler is called; use rl_cleanup_after_signal() + to do that. */ +extern int rl_catch_sigwinch; + +/* Completion variables. */ +/* Pointer to the generator function for completion_matches (). + NULL means to use rl_filename_completion_function (), the default + filename completer. */ +extern rl_compentry_func_t *rl_completion_entry_function; + +/* If rl_ignore_some_completions_function is non-NULL it is the address + of a function to call after all of the possible matches have been + generated, but before the actual completion is done to the input line. + The function is called with one argument; a NULL terminated array + of (char *). If your function removes any of the elements, they + must be free()'ed. */ +extern rl_compignore_func_t *rl_ignore_some_completions_function; + +/* Pointer to alternative function to create matches. + Function is called with TEXT, START, and END. + START and END are indices in RL_LINE_BUFFER saying what the boundaries + of TEXT are. + If this function exists and returns NULL then call the value of + rl_completion_entry_function to try to match, otherwise use the + array of strings returned. */ +extern rl_completion_func_t *rl_attempted_completion_function; + +/* The basic list of characters that signal a break between words for the + completer routine. The initial contents of this variable is what + breaks words in the shell, i.e. "n\"\\'`@$>". */ +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; + +/* List of characters which can be used to quote a substring of the line. + Completion occurs on the entire substring, and within the substring + rl_completer_word_break_characters are treated as any other character, + unless they also appear within this list. */ +extern const char *rl_completer_quote_characters; + +/* List of quote characters which cause a word break. */ +extern const char *rl_basic_quote_characters; + +/* List of characters that need to be quoted in filenames by the completer. */ +extern const char *rl_filename_quote_characters; + +/* List of characters that are word break characters, but should be left + in TEXT when it is passed to the completion function. The shell uses + this to help determine what kind of completing to do. */ +extern const char *rl_special_prefixes; + +/* If non-zero, then this is the address of a function to call when + completing on a directory name. The function is called with + the address of a string (the current directory name) as an arg. It + changes what is displayed when the possible completions are printed + or inserted. */ +extern rl_icppfunc_t *rl_directory_completion_hook; + +/* If non-zero, this is the address of a function to call when completing + a directory name. This function takes the address of the directory name + to be modified as an argument. Unlike rl_directory_completion_hook, it + only modifies the directory name used in opendir(2), not what is displayed + when the possible completions are printed or inserted. It is called + before rl_directory_completion_hook. I'm not happy with how this works + yet, so it's undocumented. */ +extern rl_icppfunc_t *rl_directory_rewrite_hook; + +/* Backwards compatibility with previous versions of readline. */ +#define rl_symbolic_link_hook rl_directory_completion_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 instead of actually doing the display. + It takes three arguments: (char **matches, int num_matches, int max_length) + where MATCHES is the array of strings that matched, NUM_MATCHES is the + number of strings in that array, and MAX_LENGTH is the length of the + longest string in that array. */ +extern rl_compdisp_func_t *rl_completion_display_matches_hook; + +/* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ +extern int rl_filename_completion_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 + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ +extern int rl_filename_quoting_desired; + +/* Set to a function to quote a filename in an application-specific fashion. + Called with the text to quote, the type of match found (single or multiple) + and a pointer to the quoting character to be used, which the function can + reset if desired. */ +extern rl_quote_func_t *rl_filename_quoting_function; + +/* Function to call to remove quoting characters from a filename. Called + before completion is attempted, so the embedded quotes do not interfere + with matching names in the file system. */ +extern rl_dequote_func_t *rl_filename_dequoting_function; + +/* Function to call to decide whether or not a word break character is + quoted. If a character is quoted, it does not break words for the + completer. */ +extern rl_linebuf_func_t *rl_char_is_quoted_p; + +/* Non-zero means to suppress normal filename completion after the + user-specified completion function has been called. */ +extern int rl_attempted_completion_over; + +/* Set to a character describing the type of completion being attempted by + rl_complete_internal; available for use by application completion + functions. */ +extern int rl_completion_type; + +/* 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; + +/* If set to non-zero by an application completion function, + 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; + +/* 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 + that application completion functions can override the user's preference + (set via the mark-symlinked-directories variable) if appropriate. + It's set to the value of _rl_complete_mark_symlink_dirs in + rl_complete_internal before any application-specific completion + function is called, so without that function doing anything, the user's + preferences are honored. */ +extern int rl_completion_mark_symlink_dirs; + +/* If non-zero, then disallow duplicates in the matches. */ +extern int rl_ignore_completion_duplicates; + +/* If this is non-zero, completion is (temporarily) inhibited, and the + completion character will be inserted as any other. */ +extern int rl_inhibit_completion; + +/* Definitions available for use by readline clients. */ +#define RL_PROMPT_START_IGNORE '\001' +#define RL_PROMPT_END_IGNORE '\002' + +/* Possible values for do_replace argument to rl_filename_quoting_function, + called by rl_complete_internal. */ +#define NO_MATCH 0 +#define SINGLE_MATCH 1 +#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_SETSTATE(x) (rl_readline_state |= (x)) +#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) +#define RL_ISSTATE(x) (rl_readline_state & (x)) + +struct readline_state { + /* line state */ + int point; + int end; + int mark; + char *buffer; + int buflen; + UNDO_LIST *ul; + char *prompt; + + /* global state */ + int rlstate; + int done; + Keymap kmap; + + /* input state */ + rl_command_func_t *lastfunc; + int insmode; + int edmode; + int kseqlen; + FILE *inf; + FILE *outf; + int pendingin; + char *macro; + + /* signal state */ + int catchsigs; + int catchsigwinch; + + /* reserved for future expansion, so the struct size doesn't change */ + char reserved[64]; +}; + +extern int rl_save_state PARAMS((struct readline_state *)); +extern int rl_restore_state PARAMS((struct readline_state *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _READLINE_H_ */ diff --git a/readline-4.3/rlconf.h b/readline-4.3/rlconf.h new file mode 100644 index 0000000..c651fd8 --- /dev/null +++ b/readline-4.3/rlconf.h @@ -0,0 +1,60 @@ +/* rlconf.h -- readline configuration definitions */ + +/* Copyright (C) 1994 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLCONF_H_) +#define _RLCONF_H_ + +/* Define this if you want the vi-mode editing available. */ +#define VI_MODE + +/* Define this to get an indication of file type when listing completions. */ +#define VISIBLE_STATS + +/* This definition is needed by readline.c, rltty.c, and signals.c. */ +/* If on, then readline handles signals in a way that doesn't screw. */ +#define HANDLE_SIGNALS + +/* Ugly but working hack for binding prefix meta. */ +#define PREFIX_META_HACK + +/* The final, last-ditch effort file name for an init file. */ +#define DEFAULT_INPUTRC "~/.inputrc" + +/* If defined, expand tabs to spaces. */ +#define DISPLAY_TABS + +/* If defined, use the terminal escape sequence to move the cursor forward + over a character when updating the line rather than rewriting it. */ +/* #define HACK_TERMCAP_MOTION */ + +/* The string inserted by the `insert comment' command. */ +#define RL_COMMENT_BEGIN_DEFAULT "#" + +/* Define this if you want code that allows readline to be used in an + X `callback' style. */ +#define READLINE_CALLBACKS + +/* Define this if you want the cursor to indicate insert or overwrite mode. */ +/* #define CURSOR_MODE */ + +#endif /* _RLCONF_H_ */ diff --git a/readline-4.3/rldefs.h b/readline-4.3/rldefs.h new file mode 100644 index 0000000..4a28bd1 --- /dev/null +++ b/readline-4.3/rldefs.h @@ -0,0 +1,156 @@ +/* rldefs.h -- an attempt to isolate some of the system-specific defines + 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. + + This file contains the Readline Library (the Library), a set of + routines for providing Emacs style line input to programs that ask + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLDEFS_H_) +#define _RLDEFS_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include "rlstdc.h" + +#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 +# endif +#endif + +/* Posix macro to check file in statbuf for directory-ness. + This requires that be included before this test. */ +#if defined (S_IFDIR) && !defined (S_ISDIR) +# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif + +/* Decide which flavor of the header file describing the C library + string functions to include and include it. */ + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if !defined (strchr) && !defined (__STDC__) +extern char *strchr (), *strrchr (); +#endif /* !strchr && !__STDC__ */ + +#if defined (PREFER_STDARG) +# include +#else +# if defined (PREFER_VARARGS) +# include +# endif +#endif + +#if defined (HAVE_STRCASECMP) +#define _rl_stricmp strcasecmp +#define _rl_strnicmp strncasecmp +#else +extern int _rl_stricmp PARAMS((char *, char *)); +extern int _rl_strnicmp PARAMS((char *, char *, int)); +#endif + +#if defined (HAVE_STRPBRK) +# define _rl_strpbrk(a,b) strpbrk((a),(b)) +#else +extern char *_rl_strpbrk PARAMS((const char *, const char *)); +#endif + +#if !defined (emacs_mode) +# define no_mode -1 +# define vi_mode 0 +# define emacs_mode 1 +#endif + +#if !defined (RL_IM_INSERT) +# define RL_IM_INSERT 1 +# define RL_IM_OVERWRITE 0 +# +# define RL_IM_DEFAULT RL_IM_INSERT +#endif + +/* If you cast map[key].function to type (Keymap) on a Cray, + the compiler takes the value of map[key].function and + divides it by 4 to convert between pointer types (pointers + to functions and pointers to structs are different sizes). + This is not what is wanted. */ +#if defined (CRAY) +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data)) +#else +# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function) +# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data) +#endif + +#ifndef savestring +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif + +/* Possible values for _rl_bell_preference. */ +#define NO_BELL 0 +#define AUDIBLE_BELL 1 +#define VISIBLE_BELL 2 + +/* Definitions used when searching the line for characters. */ +/* NOTE: it is necessary that opposite directions are inverses */ +#define FTO 1 /* forward to */ +#define BTO -1 /* backward to */ +#define FFIND 2 /* forward find */ +#define BFIND -2 /* backward find */ + +/* Possible values for the found_quote flags word used by the completion + functions. It says what kind of (shell-like) quoting we found anywhere + in the line. */ +#define RL_QF_SINGLE_QUOTE 0x01 +#define RL_QF_DOUBLE_QUOTE 0x02 +#define RL_QF_BACKSLASH 0x04 +#define RL_QF_OTHER_QUOTE 0x08 + +/* Default readline line buffer length. */ +#define DEFAULT_BUFFER_SIZE 256 + +#if !defined (STREQ) +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((n) == 0) ? (1) \ + : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) +#endif + +#if !defined (FREE) +# define FREE(x) if (x) free (x) +#endif + +#if !defined (SWAP) +# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) +#endif + +/* CONFIGURATION SECTION */ +#include "rlconf.h" + +#endif /* !_RLDEFS_H_ */ diff --git a/readline-4.3/rlmbutil.h b/readline-4.3/rlmbutil.h new file mode 100644 index 0000000..27ca32b --- /dev/null +++ b/readline-4.3/rlmbutil.h @@ -0,0 +1,108 @@ +/* rlmbutil.h -- utility functions for multibyte characters. */ + +/* Copyright (C) 2001 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_MBUTIL_H_) +#define _RL_MBUTIL_H_ + +#include "rlstdc.h" + +/************************************************/ +/* check multibyte capability for I18N code */ +/************************************************/ + +/* For platforms which support the ISO C amendement 1 functionality we + support user defined character classes. */ + /* Solaris 2.5 has a bug: must be included before . */ +#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) +# include +# include +# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */ +# define HANDLE_MULTIBYTE 1 +# endif +#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 +# include +# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) +# undef MB_LEN_MAX +# endif +# if !defined (MB_LEN_MAX) +# define MB_LEN_MAX 16 +# endif +#endif + +/************************************************/ +/* end of multibyte capability checks for I18N */ +/************************************************/ + +/* + * Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar: + * + * MB_FIND_ANY find any multibyte character + * MB_FIND_NONZERO find a non-zero-width multibyte character + */ + +#define MB_FIND_ANY 0x00 +#define MB_FIND_NONZERO 0x01 + +extern int _rl_find_prev_mbchar PARAMS((char *, int, int)); +extern int _rl_find_next_mbchar PARAMS((char *, int, int, int)); + +#ifdef HANDLE_MULTIBYTE + +extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *)); +extern int _rl_get_char_len PARAMS((char *, mbstate_t *)); +extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *)); + +extern int _rl_read_mbchar PARAMS((char *, int)); +extern int _rl_read_mbstring PARAMS((int, char *, int)); + +extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); + +#else /* !HANDLE_MULTIBYTE */ + +#undef MB_LEN_MAX +#undef MB_CUR_MAX + +#define MB_LEN_MAX 1 +#define MB_CUR_MAX 1 + +#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1)) +#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2)) + +#endif /* !HANDLE_MULTIBYTE */ + +extern int rl_byte_oriented; + +#endif /* _RL_MBUTIL_H_ */ diff --git a/readline-4.3/rlprivate.h b/readline-4.3/rlprivate.h new file mode 100644 index 0000000..ccb9144 --- /dev/null +++ b/readline-4.3/rlprivate.h @@ -0,0 +1,284 @@ +/* rlprivate.h -- functions and variables global to the readline library, + but not intended for use by applications. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_PRIVATE_H_) +#define _RL_PRIVATE_H_ + +#include "rlconf.h" /* for VISIBLE_STATS */ +#include "rlstdc.h" +#include "posixjmp.h" /* defines procenv_t */ + +/************************************************************************* + * * + * Global functions undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/************************************************************************* + * * + * Global variables undocumented in texinfo manual and not in readline.h * + * * + *************************************************************************/ + +/* complete.c */ +extern int rl_complete_with_tilde_expansion; +#if defined (VISIBLE_STATS) +extern int rl_visible_stats; +#endif /* VISIBLE_STATS */ + +/* readline.c */ +extern int rl_line_buffer_len; +extern int rl_arg_sign; +extern int rl_visible_prompt_length; +extern int readline_echoing_p; +extern int rl_key_sequence_length; +extern int rl_byte_oriented; + +/* display.c */ +extern int rl_display_fixed; + +/* parens.c */ +extern int rl_blink_matching_paren; + +/************************************************************************* + * * + * Global functions and variables unsed and undocumented * + * * + *************************************************************************/ + +/* kill.c */ +extern int rl_set_retained_kills PARAMS((int)); + +/* terminal.c */ +extern void _rl_set_screen_size PARAMS((int, int)); + +/* undo.c */ +extern int _rl_fix_last_undo_of_type PARAMS((int, int, int)); + +/* util.c */ +extern char *_rl_savestring PARAMS((const char *)); + +/************************************************************************* + * * + * Functions and variables private to the readline library * + * * + *************************************************************************/ + +/* NOTE: Functions and variables prefixed with `_rl_' are + pseudo-global: they are global so they can be shared + between files in the readline library, but are not intended + to be visible to readline callers. */ + +/************************************************************************* + * Undocumented private functions * + *************************************************************************/ + +#if defined(READLINE_CALLBACKS) + +/* readline.c */ +extern void readline_internal_setup PARAMS((void)); +extern char *readline_internal_teardown PARAMS((int)); +extern int readline_internal_char PARAMS((void)); + +#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 *)); +extern void _rl_free_match_list PARAMS((char **)); + +/* display.c */ +extern char *_rl_strip_prompt PARAMS((char *)); +extern void _rl_move_cursor_relative PARAMS((int, const char *)); +extern void _rl_move_vert PARAMS((int)); +extern void _rl_save_prompt PARAMS((void)); +extern void _rl_restore_prompt PARAMS((void)); +extern char *_rl_make_prompt_for_search PARAMS((int)); +extern void _rl_erase_at_end_of_line PARAMS((int)); +extern void _rl_clear_to_eol PARAMS((int)); +extern void _rl_clear_screen PARAMS((void)); +extern void _rl_update_final PARAMS((void)); +extern void _rl_redisplay_after_sigwinch PARAMS((void)); +extern void _rl_clean_up_for_exit PARAMS((void)); +extern void _rl_erase_entire_line PARAMS((void)); +extern int _rl_current_display_line PARAMS((void)); + +/* input.c */ +extern int _rl_any_typein PARAMS((void)); +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)); + +/* macro.c */ +extern void _rl_with_macro_input PARAMS((char *)); +extern int _rl_next_macro_key PARAMS((void)); +extern void _rl_push_executing_macro PARAMS((void)); +extern void _rl_pop_executing_macro PARAMS((void)); +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 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)); + +/* nls.c */ +extern int _rl_init_eightbit PARAMS((void)); + +/* parens.c */ +extern void _rl_enable_paren_matching PARAMS((int)); + +/* readline.c */ +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)); + +/* rltty.c */ +extern int _rl_disable_tty_signals PARAMS((void)); +extern int _rl_restore_tty_signals PARAMS((void)); + +/* terminal.c */ +extern void _rl_get_screen_size PARAMS((int, int)); +extern int _rl_init_terminal_io PARAMS((const char *)); +#ifdef _MINIX +extern void _rl_output_character_function PARAMS((int)); +#else +extern int _rl_output_character_function PARAMS((int)); +#endif +extern void _rl_output_some_chars PARAMS((const char *, int)); +extern int _rl_backspace PARAMS((int)); +extern void _rl_enable_meta_key PARAMS((void)); +extern void _rl_control_keypad PARAMS((int)); +extern void _rl_set_cursor PARAMS((int, int)); + +/* text.c */ +extern void _rl_fix_point PARAMS((int)); +extern int _rl_replace_text PARAMS((const char *, int, int)); +extern int _rl_insert_char PARAMS((int, int)); +extern int _rl_overwrite_char PARAMS((int, int)); +extern int _rl_overwrite_rubout PARAMS((int, int)); +extern int _rl_rubout_char PARAMS((int, int)); +#if defined (HANDLE_MULTIBYTE) +extern int _rl_char_search_internal PARAMS((int, int, char *, int)); +#else +extern int _rl_char_search_internal PARAMS((int, int, int)); +#endif +extern int _rl_set_mark_at_pos PARAMS((int)); + +/* util.c */ +extern int _rl_abort_internal PARAMS((void)); +extern char *_rl_strindex PARAMS((const char *, const char *)); +extern int _rl_qsort_string_compare PARAMS((char **, char **)); +extern int (_rl_uppercase_p) PARAMS((int)); +extern int (_rl_lowercase_p) PARAMS((int)); +extern int (_rl_pure_alphabetic) PARAMS((int)); +extern int (_rl_digit_p) PARAMS((int)); +extern int (_rl_to_lower) PARAMS((int)); +extern int (_rl_to_upper) PARAMS((int)); +extern int (_rl_digit_value) PARAMS((int)); + +/* vi_mode.c */ +extern void _rl_vi_initialize_line PARAMS((void)); +extern void _rl_vi_reset_last PARAMS((void)); +extern void _rl_vi_set_last PARAMS((int, int, int)); +extern int _rl_vi_textmod_command PARAMS((int)); +extern void _rl_vi_done_inserting PARAMS((void)); + +/************************************************************************* + * Undocumented private variables * + *************************************************************************/ + +/* bind.c */ +extern const char *_rl_possible_control_prefixes[]; +extern const char *_rl_possible_meta_prefixes[]; + +/* complete.c */ +extern int _rl_complete_show_all; +extern int _rl_complete_mark_directories; +extern int _rl_complete_mark_symlink_dirs; +extern int _rl_print_completions_horizontally; +extern int _rl_completion_case_fold; +extern int _rl_match_hidden_files; +extern int _rl_page_completions; + +/* display.c */ +extern int _rl_vis_botlin; +extern int _rl_last_c_pos; +extern int _rl_suppress_redisplay; +extern char *rl_display_prompt; + +/* isearch.c */ +extern char *_rl_isearch_terminators; + +/* macro.c */ +extern char *_rl_executing_macro; + +/* misc.c */ +extern int _rl_history_preserve_point; +extern int _rl_history_saved_point; + +/* readline.c */ +extern int _rl_horizontal_scroll_mode; +extern int _rl_mark_modified_lines; +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 char *_rl_comment_begin; +extern unsigned char _rl_parsing_conditionalized_out; +extern Keymap _rl_keymap; +extern FILE *_rl_in_stream; +extern FILE *_rl_out_stream; +extern int _rl_last_command_was_kill; +extern int _rl_eof_char; +extern procenv_t readline_top_level; + +/* terminal.c */ +extern int _rl_enable_keypad; +extern int _rl_enable_meta; +extern char *_rl_term_clreol; +extern char *_rl_term_clrpag; +extern char *_rl_term_im; +extern char *_rl_term_ic; +extern char *_rl_term_ei; +extern char *_rl_term_DC; +extern char *_rl_term_up; +extern char *_rl_term_dc; +extern char *_rl_term_cr; +extern char *_rl_term_IC; +extern int _rl_screenheight; +extern int _rl_screenwidth; +extern int _rl_screenchars; +extern int _rl_terminal_can_insert; +extern int _rl_term_autowrap; + +/* undo.c */ +extern int _rl_doing_an_undo; +extern int _rl_undo_group_level; + +#endif /* _RL_PRIVATE_H_ */ diff --git a/readline-4.3/rlshell.h b/readline-4.3/rlshell.h new file mode 100644 index 0000000..3c03fba --- /dev/null +++ b/readline-4.3/rlshell.h @@ -0,0 +1,34 @@ +/* rlshell.h -- utility functions normally provided by bash. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RL_SHELL_H_) +#define _RL_SHELL_H_ + +#include "rlstdc.h" + +extern char *sh_single_quote PARAMS((char *)); +extern void sh_set_lines_and_columns PARAMS((int, int)); +extern char *sh_get_env_value PARAMS((const char *)); +extern char *sh_get_home_dir PARAMS((void)); +extern int sh_unset_nodelay_mode PARAMS((int)); + +#endif /* _RL_SHELL_H_ */ diff --git a/readline-4.3/rlstdc.h b/readline-4.3/rlstdc.h new file mode 100644 index 0000000..d6a22b3 --- /dev/null +++ b/readline-4.3/rlstdc.h @@ -0,0 +1,45 @@ +/* stdc.h -- macros to make source compile on both ANSI C and K&R C + compilers. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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. + + Bash 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 Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_RL_STDC_H_) +#define _RL_STDC_H_ + +/* Adapted from BSD /usr/include/sys/cdefs.h. */ + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ +# define __attribute__(x) +# endif +#endif + +#endif /* !_RL_STDC_H_ */ diff --git a/readline-4.3/rltty.c b/readline-4.3/rltty.c new file mode 100644 index 0000000..755efeb --- /dev/null +++ b/readline-4.3/rltty.c @@ -0,0 +1,911 @@ +/* rltty.c -- functions to prepare and restore the terminal for readline's + use. */ + +/* Copyright (C) 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include +#endif /* GWINSZ_IN_SYS_IOCTL */ + +#include "rltty.h" +#include "readline.h" +#include "rlprivate.h" + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal; +rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal; + +static void block_sigint PARAMS((void)); +static void release_sigint PARAMS((void)); + +static void set_winsize PARAMS((int)); + +/* **************************************************************** */ +/* */ +/* Signal Management */ +/* */ +/* **************************************************************** */ + +#if defined (HAVE_POSIX_SIGNALS) +static sigset_t sigint_set, sigint_oset; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) +static int sigint_oldmask; +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +static int sigint_blocked; + +/* Cause SIGINT to not be delivered until the corresponding call to + release_sigint(). */ +static void +block_sigint () +{ + if (sigint_blocked) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&sigint_set); + sigemptyset (&sigint_oset); + sigaddset (&sigint_set, SIGINT); + sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigint_oldmask = sigblock (sigmask (SIGINT)); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sighold (SIGINT); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigint_blocked = 1; +} + +/* Allow SIGINT to be delivered. */ +static void +release_sigint () +{ + if (sigint_blocked == 0) + return; + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL); +#else +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (sigint_oldmask); +# else /* !HAVE_BSD_SIGNALS */ +# if defined (HAVE_USG_SIGHOLD) + sigrelse (SIGINT); +# endif /* HAVE_USG_SIGHOLD */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + sigint_blocked = 0; +} + +/* **************************************************************** */ +/* */ +/* Saving and Restoring the TTY */ +/* */ +/* **************************************************************** */ + +/* Non-zero means that the terminal is in a prepped state. */ +static int terminal_prepped; + +static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars; + +/* If non-zero, means that this process has called tcflow(fd, TCOOFF) + and output is suspended. */ +#if defined (__ksr1__) +static int ksrflow; +#endif + +/* Dummy call to force a backgrounded readline to stop before it tries + to get the tty settings. */ +static void +set_winsize (tty) + int tty; +{ +#if defined (TIOCGWINSZ) + struct winsize w; + + if (ioctl (tty, TIOCGWINSZ, &w) == 0) + (void) ioctl (tty, TIOCSWINSZ, &w); +#endif /* TIOCGWINSZ */ +} + +#if defined (NEW_TTY_DRIVER) + +/* Values for the `flags' field of a struct bsdtty. This tells which + elements of the struct bsdtty have been fetched from the system and + are valid. */ +#define SGTTY_SET 0x01 +#define LFLAG_SET 0x02 +#define TCHARS_SET 0x04 +#define LTCHARS_SET 0x08 + +struct bsdtty { + struct sgttyb sgttyb; /* Basic BSD tty driver information. */ + int lflag; /* Local mode flags, like LPASS8. */ +#if defined (TIOCGETC) + struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */ +#endif +#if defined (TIOCGLTC) + struct ltchars ltchars; /* 4.2 BSD editing characters */ +#endif + int flags; /* Bitmap saying which parts of the struct are valid. */ +}; + +#define TIOTYPE struct bsdtty + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +static void +save_tty_chars (tiop) + TIOTYPE *tiop; +{ + _rl_last_tty_chars = _rl_tty_chars; + + if (tiop->flags & SGTTY_SET) + { + _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase; + _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill; + } + + if (tiop->flags & TCHARS_SET) + { + _rl_tty_chars.t_intr = tiop->tchars.t_intrc; + _rl_tty_chars.t_quit = tiop->tchars.t_quitc; + _rl_tty_chars.t_start = tiop->tchars.t_startc; + _rl_tty_chars.t_stop = tiop->tchars.t_stopc; + _rl_tty_chars.t_eof = tiop->tchars.t_eofc; + _rl_tty_chars.t_eol = '\n'; + _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc; + } + + if (tiop->flags & LTCHARS_SET) + { + _rl_tty_chars.t_susp = tiop->ltchars.t_suspc; + _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc; + _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc; + _rl_tty_chars.t_flush = tiop->ltchars.t_flushc; + _rl_tty_chars.t_werase = tiop->ltchars.t_werasc; + _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc; + } + + _rl_tty_chars.t_status = -1; +} + +static int +get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + set_winsize (tty); + + tiop->flags = tiop->lflag = 0; + + if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0) + return -1; + tiop->flags |= SGTTY_SET; + +#if defined (TIOCLGET) + if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0) + tiop->flags |= LFLAG_SET; +#endif + +#if defined (TIOCGETC) + if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0) + tiop->flags |= TCHARS_SET; +#endif + +#if defined (TIOCGLTC) + if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0) + tiop->flags |= LTCHARS_SET; +#endif + + return 0; +} + +static int +set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + if (tiop->flags & SGTTY_SET) + { + ioctl (tty, TIOCSETN, &(tiop->sgttyb)); + tiop->flags &= ~SGTTY_SET; + } + readline_echoing_p = 1; + +#if defined (TIOCLSET) + if (tiop->flags & LFLAG_SET) + { + ioctl (tty, TIOCLSET, &(tiop->lflag)); + tiop->flags &= ~LFLAG_SET; + } +#endif + +#if defined (TIOCSETC) + if (tiop->flags & TCHARS_SET) + { + ioctl (tty, TIOCSETC, &(tiop->tchars)); + tiop->flags &= ~TCHARS_SET; + } +#endif + +#if defined (TIOCSLTC) + if (tiop->flags & LTCHARS_SET) + { + ioctl (tty, TIOCSLTC, &(tiop->ltchars)); + tiop->flags &= ~LTCHARS_SET; + } +#endif + + return 0; +} + +static void +prepare_terminal_settings (meta_flag, oldtio, tiop) + int meta_flag; + TIOTYPE oldtio, *tiop; +{ + readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); + + /* Copy the original settings to the structure we're going to use for + our settings. */ + tiop->sgttyb = oldtio.sgttyb; + tiop->lflag = oldtio.lflag; +#if defined (TIOCGETC) + tiop->tchars = oldtio.tchars; +#endif +#if defined (TIOCGLTC) + tiop->ltchars = oldtio.ltchars; +#endif + tiop->flags = oldtio.flags; + + /* First, the basic settings to put us into character-at-a-time, no-echo + input mode. */ + tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD); + tiop->sgttyb.sg_flags |= CBREAK; + + /* If this terminal doesn't care how the 8th bit is used, then we can + use it for the meta-key. If only one of even or odd parity is + specified, then the terminal is using parity, and we cannot. */ +#if !defined (ANYP) +# define ANYP (EVENP | ODDP) +#endif + if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) || + ((oldtio.sgttyb.sg_flags & ANYP) == 0)) + { + tiop->sgttyb.sg_flags |= ANYP; + + /* Hack on local mode flags if we can. */ +#if defined (TIOCLGET) +# if defined (LPASS8) + tiop->lflag |= LPASS8; +# endif /* LPASS8 */ +#endif /* TIOCLGET */ + } + +#if defined (TIOCGETC) +# if defined (USE_XON_XOFF) + /* Get rid of terminal output start and stop characters. */ + tiop->tchars.t_stopc = -1; /* C-s */ + tiop->tchars.t_startc = -1; /* C-q */ + + /* If there is an XON character, bind it to restart the output. */ + if (oldtio.tchars.t_startc != -1) + rl_bind_key (oldtio.tchars.t_startc, rl_restart_output); +# endif /* USE_XON_XOFF */ + + /* If there is an EOF char, bind _rl_eof_char to it. */ + if (oldtio.tchars.t_eofc != -1) + _rl_eof_char = oldtio.tchars.t_eofc; + +# if defined (NO_KILL_INTR) + /* Get rid of terminal-generated SIGQUIT and SIGINT. */ + tiop->tchars.t_quitc = -1; /* C-\ */ + tiop->tchars.t_intrc = -1; /* C-c */ +# endif /* NO_KILL_INTR */ +#endif /* TIOCGETC */ + +#if defined (TIOCGLTC) + /* Make the interrupt keys go away. Just enough to make people happy. */ + tiop->ltchars.t_dsuspc = -1; /* C-y */ + tiop->ltchars.t_lnextc = -1; /* C-v */ +#endif /* TIOCGLTC */ +} + +#else /* !defined (NEW_TTY_DRIVER) */ + +#if !defined (VMIN) +# define VMIN VEOF +#endif + +#if !defined (VTIME) +# define VTIME VEOL +#endif + +#if defined (TERMIOS_TTY_DRIVER) +# define TIOTYPE struct termios +# define DRAIN_OUTPUT(fd) tcdrain (fd) +# define GETATTR(tty, tiop) (tcgetattr (tty, tiop)) +# ifdef M_UNIX +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop)) +# else +# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop)) +# endif /* !M_UNIX */ +#else +# define TIOTYPE struct termio +# define DRAIN_OUTPUT(fd) +# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) +# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop)) +#endif /* !TERMIOS_TTY_DRIVER */ + +static TIOTYPE otio; + +static void save_tty_chars PARAMS((TIOTYPE *)); +static int _get_tty_settings PARAMS((int, TIOTYPE *)); +static int get_tty_settings PARAMS((int, TIOTYPE *)); +static int _set_tty_settings PARAMS((int, TIOTYPE *)); +static int set_tty_settings PARAMS((int, TIOTYPE *)); + +static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); + +#if defined (FLUSHO) +# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) +#else +# define OUTPUT_BEING_FLUSHED(tp) 0 +#endif + +static void +save_tty_chars (tiop) + TIOTYPE *tiop; +{ + _rl_last_tty_chars = _rl_tty_chars; + + _rl_tty_chars.t_eof = tiop->c_cc[VEOF]; + _rl_tty_chars.t_eol = tiop->c_cc[VEOL]; +#ifdef VEOL2 + _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2]; +#endif + _rl_tty_chars.t_erase = tiop->c_cc[VERASE]; +#ifdef VWERASE + _rl_tty_chars.t_werase = tiop->c_cc[VWERASE]; +#endif + _rl_tty_chars.t_kill = tiop->c_cc[VKILL]; +#ifdef VREPRINT + _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT]; +#endif + _rl_tty_chars.t_intr = tiop->c_cc[VINTR]; + _rl_tty_chars.t_quit = tiop->c_cc[VQUIT]; +#ifdef VSUSP + _rl_tty_chars.t_susp = tiop->c_cc[VSUSP]; +#endif +#ifdef VDSUSP + _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP]; +#endif +#ifdef VSTART + _rl_tty_chars.t_start = tiop->c_cc[VSTART]; +#endif +#ifdef VSTOP + _rl_tty_chars.t_stop = tiop->c_cc[VSTOP]; +#endif +#ifdef VLNEXT + _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT]; +#endif +#ifdef VDISCARD + _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD]; +#endif +#ifdef VSTATUS + _rl_tty_chars.t_status = tiop->c_cc[VSTATUS]; +#endif +} + +#if defined (_AIX) || defined (_AIX41) +/* Currently this is only used on AIX */ +static void +rltty_warning (msg) + char *msg; +{ + fprintf (stderr, "readline: warning: %s\n", msg); +} +#endif + +#if defined (_AIX) +void +setopost(tp) +TIOTYPE *tp; +{ + if ((tp->c_oflag & OPOST) == 0) + { + rltty_warning ("turning on OPOST for terminal\r"); + tp->c_oflag |= OPOST|ONLCR; + } +} +#endif + +static int +_get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + int ioctl_ret; + + while (1) + { + ioctl_ret = GETATTR (tty, tiop); + if (ioctl_ret < 0) + { + if (errno != EINTR) + return -1; + else + continue; + } + if (OUTPUT_BEING_FLUSHED (tiop)) + { +#if defined (FLUSHO) && defined (_AIX41) + rltty_warning ("turning off output flushing"); + tiop->c_lflag &= ~FLUSHO; + break; +#else + continue; +#endif + } + break; + } + + return 0; +} + +static int +get_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + set_winsize (tty); + + if (_get_tty_settings (tty, tiop) < 0) + return -1; + +#if defined (_AIX) + setopost(tiop); +#endif + + return 0; +} + +static int +_set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + while (SETATTR (tty, tiop) < 0) + { + if (errno != EINTR) + return -1; + errno = 0; + } + return 0; +} + +static int +set_tty_settings (tty, tiop) + int tty; + TIOTYPE *tiop; +{ + if (_set_tty_settings (tty, tiop) < 0) + return -1; + +#if 0 + +#if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (tty, TCOON); + } +# else /* !ksr1 */ + tcflow (tty, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +#else + ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ +#endif /* !TERMIOS_TTY_DRIVER */ + +#endif /* 0 */ + + return 0; +} + +static void +prepare_terminal_settings (meta_flag, oldtio, tiop) + int meta_flag; + TIOTYPE oldtio, *tiop; +{ + readline_echoing_p = (oldtio.c_lflag & ECHO); + + tiop->c_lflag &= ~(ICANON | ECHO); + + if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) + _rl_eof_char = oldtio.c_cc[VEOF]; + +#if defined (USE_XON_XOFF) +#if defined (IXANY) + tiop->c_iflag &= ~(IXON | IXOFF | IXANY); +#else + /* `strict' Posix systems do not define IXANY. */ + tiop->c_iflag &= ~(IXON | IXOFF); +#endif /* IXANY */ +#endif /* USE_XON_XOFF */ + + /* Only turn this off if we are using all 8 bits. */ + if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag) + tiop->c_iflag &= ~(ISTRIP | INPCK); + + /* Make sure we differentiate between CR and NL on input. */ + tiop->c_iflag &= ~(ICRNL | INLCR); + +#if !defined (HANDLE_SIGNALS) + tiop->c_lflag &= ~ISIG; +#else + tiop->c_lflag |= ISIG; +#endif + + tiop->c_cc[VMIN] = 1; + tiop->c_cc[VTIME] = 0; + +#if defined (FLUSHO) + if (OUTPUT_BEING_FLUSHED (tiop)) + { + tiop->c_lflag &= ~FLUSHO; + oldtio.c_lflag &= ~FLUSHO; + } +#endif + + /* Turn off characters that we need on Posix systems with job control, + just to be sure. This includes ^Y and ^V. This should not really + be necessary. */ +#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE) + +#if defined (VLNEXT) + tiop->c_cc[VLNEXT] = _POSIX_VDISABLE; +#endif + +#if defined (VDSUSP) + tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; +#endif + +#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ +} +#endif /* NEW_TTY_DRIVER */ + +/* Put the terminal in CBREAK mode so that we can detect key presses. */ +void +rl_prep_terminal (meta_flag) + int meta_flag; +{ + int tty; + TIOTYPE tio; + + if (terminal_prepped) + return; + + /* Try to keep this function from being INTerrupted. */ + block_sigint (); + + tty = fileno (rl_instream); + + if (get_tty_settings (tty, &tio) < 0) + { + release_sigint (); + return; + } + + otio = tio; + + save_tty_chars (&otio); + + prepare_terminal_settings (meta_flag, otio, &tio); + + if (set_tty_settings (tty, &tio) < 0) + { + release_sigint (); + return; + } + + if (_rl_enable_keypad) + _rl_control_keypad (1); + + fflush (rl_outstream); + terminal_prepped = 1; + RL_SETSTATE(RL_STATE_TERMPREPPED); + + release_sigint (); +} + +/* Restore the terminal's normal settings and modes. */ +void +rl_deprep_terminal () +{ + int tty; + + if (!terminal_prepped) + return; + + /* Try to keep this function from being interrupted. */ + block_sigint (); + + tty = fileno (rl_instream); + + if (_rl_enable_keypad) + _rl_control_keypad (0); + + fflush (rl_outstream); + + if (set_tty_settings (tty, &otio) < 0) + { + release_sigint (); + return; + } + + terminal_prepped = 0; + RL_UNSETSTATE(RL_STATE_TERMPREPPED); + + release_sigint (); +} + +/* **************************************************************** */ +/* */ +/* Bogus Flow Control */ +/* */ +/* **************************************************************** */ + +int +rl_restart_output (count, key) + int count, key; +{ + int fildes = fileno (rl_outstream); +#if defined (TIOCSTART) +#if defined (apollo) + ioctl (&fildes, TIOCSTART, 0); +#else + ioctl (fildes, TIOCSTART, 0); +#endif /* apollo */ + +#else /* !TIOCSTART */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + if (ksrflow) + { + ksrflow = 0; + tcflow (fildes, TCOON); + } +# else /* !ksr1 */ + tcflow (fildes, TCOON); /* Simulate a ^Q. */ +# endif /* !ksr1 */ +# else /* !TERMIOS_TTY_DRIVER */ +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTART */ + + return 0; +} + +int +rl_stop_output (count, key) + int count, key; +{ + int fildes = fileno (rl_instream); + +#if defined (TIOCSTOP) +# if defined (apollo) + ioctl (&fildes, TIOCSTOP, 0); +# else + ioctl (fildes, TIOCSTOP, 0); +# endif /* apollo */ +#else /* !TIOCSTOP */ +# if defined (TERMIOS_TTY_DRIVER) +# if defined (__ksr1__) + ksrflow = 1; +# endif /* ksr1 */ + tcflow (fildes, TCOOFF); +# else +# if defined (TCXONC) + ioctl (fildes, TCXONC, TCOON); +# endif /* TCXONC */ +# endif /* !TERMIOS_TTY_DRIVER */ +#endif /* !TIOCSTOP */ + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Default Key Bindings */ +/* */ +/* **************************************************************** */ + +/* 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; +{ + TIOTYPE ttybuff; + int tty = fileno (rl_instream); + +#if defined (NEW_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) + + if (get_tty_settings (tty, &ttybuff) == 0) + { + if (ttybuff.flags & SGTTY_SET) + { + 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 */ + } + +#else /* !NEW_TTY_DRIVER */ + +#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) + + if (get_tty_settings (tty, &ttybuff) == 0) + { + 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); +# endif /* VLNEXT && TERMIOS_TTY_DRIVER */ + +# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) + SET_SPECIAL (VWERASE, rl_unix_word_rubout); +# endif /* VWERASE && TERMIOS_TTY_DRIVER */ + } +#endif /* !NEW_TTY_DRIVER */ +} + +/* New public way to set the system default editing chars to their readline + equivalents. */ +void +rl_tty_set_default_bindings (kmap) + Keymap kmap; +{ + rltty_set_default_bindings (kmap); +} + +#if defined (HANDLE_SIGNALS) + +#if defined (NEW_TTY_DRIVER) +int +_rl_disable_tty_signals () +{ + return 0; +} + +int +_rl_restore_tty_signals () +{ + return 0; +} +#else + +static TIOTYPE sigstty, nosigstty; +static int tty_sigs_disabled = 0; + +int +_rl_disable_tty_signals () +{ + if (tty_sigs_disabled) + return 0; + + if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0) + return -1; + + nosigstty = sigstty; + + nosigstty.c_lflag &= ~ISIG; + nosigstty.c_iflag &= ~IXON; + + if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0) + return (_set_tty_settings (fileno (rl_instream), &sigstty)); + + tty_sigs_disabled = 1; + return 0; +} + +int +_rl_restore_tty_signals () +{ + int r; + + if (tty_sigs_disabled == 0) + return 0; + + r = _set_tty_settings (fileno (rl_instream), &sigstty); + + if (r == 0) + tty_sigs_disabled = 0; + + return r; +} +#endif /* !NEW_TTY_DRIVER */ + +#endif /* HANDLE_SIGNALS */ diff --git a/readline-4.3/rltty.h b/readline-4.3/rltty.h new file mode 100644 index 0000000..029a3fb --- /dev/null +++ b/readline-4.3/rltty.h @@ -0,0 +1,82 @@ +/* rltty.h - tty driver-related definitions used by some library files. */ + +/* Copyright (C) 1995 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLTTY_H_) +#define _RLTTY_H_ + +/* Posix systems use termios and the Posix signal functions. */ +#if defined (TERMIOS_TTY_DRIVER) +# include +#endif /* TERMIOS_TTY_DRIVER */ + +/* System V machines use termio. */ +#if defined (TERMIO_TTY_DRIVER) +# include +# if !defined (TCOON) +# define TCOON 1 +# endif +#endif /* TERMIO_TTY_DRIVER */ + +/* Other (BSD) machines use sgtty. */ +#if defined (NEW_TTY_DRIVER) +# include +#endif + +#include "rlwinsize.h" + +/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and + it is not already defined. It is used both to determine if a + special character is disabled and to disable certain special + characters. Posix systems should set to 0, USG systems to -1. */ +#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE) +# if defined (_SVR4_VDISABLE) +# define _POSIX_VDISABLE _SVR4_VDISABLE +# else +# if defined (_POSIX_VERSION) +# define _POSIX_VDISABLE 0 +# else /* !_POSIX_VERSION */ +# define _POSIX_VDISABLE -1 +# endif /* !_POSIX_VERSION */ +# endif /* !_SVR4_DISABLE */ +#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; +} _RL_TTY_CHARS; + +#endif /* _RLTTY_H_ */ diff --git a/readline-4.3/rltypedefs.h b/readline-4.3/rltypedefs.h new file mode 100644 index 0000000..f3280e9 --- /dev/null +++ b/readline-4.3/rltypedefs.h @@ -0,0 +1,88 @@ +/* rltypedefs.h -- Type declarations for readline functions. */ + +/* Copyright (C) 2000 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#ifndef _RL_TYPEDEFS_H_ +#define _RL_TYPEDEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Old-style */ + +#if !defined (_FUNCTION_DEF) +# define _FUNCTION_DEF + +typedef int Function (); +typedef void VFunction (); +typedef char *CPFunction (); +typedef char **CPPFunction (); + +#endif /* _FUNCTION_DEF */ + +/* New style. */ + +#if !defined (_RL_FUNCTION_TYPEDEF) +# define _RL_FUNCTION_TYPEDEF + +/* Bindable functions */ +typedef int rl_command_func_t PARAMS((int, int)); + +/* Typedefs for the completion system */ +typedef char *rl_compentry_func_t PARAMS((const char *, int)); +typedef char **rl_completion_func_t PARAMS((const char *, int, int)); + +typedef char *rl_quote_func_t PARAMS((char *, int, char *)); +typedef char *rl_dequote_func_t PARAMS((char *, int)); + +typedef int rl_compignore_func_t PARAMS((char **)); + +typedef void rl_compdisp_func_t PARAMS((char **, int, int)); + +/* Type for input and pre-read hook functions like rl_event_hook */ +typedef int rl_hook_func_t PARAMS((void)); + +/* Input function type */ +typedef int rl_getc_func_t PARAMS((FILE *)); + +/* Generic function that takes a character buffer (which could be the readline + line buffer) and an index into it (which could be rl_point) and returns + an int. */ +typedef int rl_linebuf_func_t PARAMS((char *, int)); + +/* `Generic' function pointer typedefs */ +typedef int rl_intfunc_t PARAMS((int)); +#define rl_ivoidfunc_t rl_hook_func_t +typedef int rl_icpfunc_t PARAMS((char *)); +typedef int rl_icppfunc_t PARAMS((char **)); + +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 **)); +#endif /* _RL_FUNCTION_TYPEDEF */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RL_TYPEDEFS_H_ */ diff --git a/readline-4.3/rlwinsize.h b/readline-4.3/rlwinsize.h new file mode 100644 index 0000000..7838154 --- /dev/null +++ b/readline-4.3/rlwinsize.h @@ -0,0 +1,57 @@ +/* rlwinsize.h -- an attempt to isolate some of the system-specific defines + for `struct winsize' and TIOCGWINSZ. */ + +/* Copyright (C) 1997 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLWINSIZE_H_) +#define _RLWINSIZE_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */ + +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ + +#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# include +#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +/* Not in either of the standard places, look around. */ +#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +# if defined (HAVE_SYS_STREAM_H) +# include +# endif /* HAVE_SYS_STREAM_H */ +# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */ +# include +# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ +# endif /* HAVE_SYS_PTEM_H */ +# if defined (HAVE_SYS_PTE_H) /* ??? */ +# include +# endif /* HAVE_SYS_PTE_H */ +#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +#endif /* _RL_WINSIZE_H */ + diff --git a/readline-4.3/savestring.c b/readline-4.3/savestring.c new file mode 100644 index 0000000..c7ebeb1 --- /dev/null +++ b/readline-4.3/savestring.c @@ -0,0 +1,36 @@ +/* savestring.c */ + +/* Copyright (C) 1998 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#include +#ifdef HAVE_STRING_H +# include +#endif +#include "xmalloc.h" + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +char * +savestring (s) + const char *s; +{ + return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s))); +} diff --git a/readline-4.3/search.c b/readline-4.3/search.c new file mode 100644 index 0000000..7e0d60b --- /dev/null +++ b/readline-4.3/search.c @@ -0,0 +1,465 @@ +/* search.c - code for non-incremental searching in emacs and vi modes. */ + +/* Copyright (C) 1992 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif + +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifdef abs +# undef abs +#endif +#define abs(x) (((x) >= 0) ? (x) : -(x)) + +extern HIST_ENTRY *_rl_saved_line_for_history; + +/* Functions imported from the rest of the library. */ +extern int _rl_free_history_entry PARAMS((HIST_ENTRY *)); + +static char *noninc_search_string = (char *) NULL; +static int noninc_history_pos; + +static char *prev_line_found = (char *) NULL; + +static int rl_history_search_len; +static int rl_history_search_pos; +static char *history_search_string; +static int history_string_size; + +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 rl_history_search_internal PARAMS((int, int)); +static void rl_history_search_reinit PARAMS((void)); + +/* 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. */ +static void +make_history_line_current (entry) + HIST_ENTRY *entry; +{ + rl_replace_line (entry->line, 0); + rl_undo_list = (UNDO_LIST *)entry->data; + + if (_rl_saved_line_for_history) + _rl_free_history_entry (_rl_saved_line_for_history); + _rl_saved_line_for_history = (HIST_ENTRY *)NULL; +} + +/* Search the history list for STRING starting at absolute history position + POS. If STRING begins with `^', the search must match STRING at the + beginning of a history line, otherwise a full substring match is performed + for STRING. DIR < 0 means to search backwards through the history list, + DIR >= 0 means to search forward. */ +static int +noninc_search_from_pos (string, pos, dir) + char *string; + int pos, dir; +{ + int ret, old; + + if (pos < 0) + return -1; + + old = where_history (); + if (history_set_pos (pos) == 0) + return -1; + + RL_SETSTATE(RL_STATE_SEARCH); + if (*string == '^') + ret = history_search_prefix (string + 1, dir); + else + ret = history_search (string, dir); + RL_UNSETSTATE(RL_STATE_SEARCH); + + if (ret != -1) + ret = where_history (); + + history_set_pos (old); + return (ret); +} + +/* 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 +noninc_dosearch (string, dir) + char *string; + int dir; +{ + int oldpos, pos; + HIST_ENTRY *entry; + + if (string == 0 || *string == '\0' || noninc_history_pos < 0) + { + rl_ding (); + return; + } + + pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); + if (pos == -1) + { + /* Search failed, current history position unchanged. */ + rl_maybe_unsave_line (); + rl_clear_message (); + rl_point = 0; + rl_ding (); + return; + } + + noninc_history_pos = pos; + + oldpos = where_history (); + history_set_pos (noninc_history_pos); + entry = current_history (); +#if defined (VI_MODE) + if (rl_editing_mode != vi_mode) +#endif + history_set_pos (oldpos); + + make_history_line_current (entry); + + rl_point = 0; + rl_mark = rl_end; + + rl_clear_message (); +} + +/* 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; +{ + int saved_point, saved_mark, c; + char *p; +#if defined (HANDLE_MULTIBYTE) + char mb[MB_LEN_MAX]; +#endif + + rl_maybe_save_line (); + saved_point = rl_point; + saved_mark = rl_mark; + + /* Use the line buffer to read the search string. */ + rl_line_buffer[0] = 0; + rl_end = rl_point = 0; + + p = _rl_make_prompt_for_search (pchar ? 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_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, MB_LEN_MAX); +#endif + + if (c == 0) + break; + + switch (c) + { + 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; + + default: +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_insert_text (mb); + else +#endif + _rl_insert_char (1, c); + break; + } + (*rl_redisplay_function) (); + } + + dosearch: + rl_mark = saved_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) + { + rl_ding (); + SEARCH_RETURN; + } + } + else + { + /* We want to start the search from the current history position. */ + noninc_history_pos = where_history (); + FREE (noninc_search_string); + noninc_search_string = savestring (rl_line_buffer); + } + + rl_restore_prompt (); + noninc_dosearch (noninc_search_string, dir); + RL_UNSETSTATE(RL_STATE_NSEARCH); +} + +/* Search forward through the history list for a string. If the vi-mode + code calls this, KEY will be `?'. */ +int +rl_noninc_forward_search (count, key) + int count, key; +{ + noninc_search (1, (key == '?') ? '?' : 0); + return 0; +} + +/* Reverse search the history list for a string. If the vi-mode code + calls this, KEY will be `/'. */ +int +rl_noninc_reverse_search (count, key) + int count, key; +{ + noninc_search (-1, (key == '/') ? '/' : 0); + return 0; +} + +/* Search forward through the history list for the last string searched + for. If there is no saved search string, abort. */ +int +rl_noninc_forward_search_again (count, key) + int count, key; +{ + if (!noninc_search_string) + { + rl_ding (); + return (-1); + } + noninc_dosearch (noninc_search_string, 1); + return 0; +} + +/* Reverse search in the history list for the last string searched + for. If there is no saved search string, abort. */ +int +rl_noninc_reverse_search_again (count, key) + int count, key; +{ + if (!noninc_search_string) + { + rl_ding (); + return (-1); + } + noninc_dosearch (noninc_search_string, -1); + return 0; +} + +static int +rl_history_search_internal (count, dir) + int count, dir; +{ + HIST_ENTRY *temp; + int ret, oldpos; + + rl_maybe_save_line (); + temp = (HIST_ENTRY *)NULL; + + /* Search COUNT times through the history for a line whose prefix + matches history_search_string. When this loop finishes, TEMP, + if non-null, is the history line to copy into the line buffer. */ + while (count) + { + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); + if (ret == -1) + break; + + /* Get the history entry we found. */ + rl_history_search_pos = ret; + oldpos = where_history (); + history_set_pos (rl_history_search_pos); + temp = current_history (); + history_set_pos (oldpos); + + /* Don't find multiple instances of the same line. */ + if (prev_line_found && STREQ (prev_line_found, temp->line)) + continue; + prev_line_found = temp->line; + count--; + } + + /* If we didn't find anything at all, return. */ + if (temp == 0) + { + rl_maybe_unsave_line (); + rl_ding (); + /* If you don't want the saved history line (last match) to show up + in the line buffer after the search fails, change the #if 0 to + #if 1 */ +#if 0 + if (rl_point > rl_history_search_len) + { + rl_point = rl_end = rl_history_search_len; + rl_line_buffer[rl_end] = '\0'; + rl_mark = 0; + } +#else + rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */ + rl_mark = rl_end; +#endif + return 1; + } + + /* Copy the line we found into the current line buffer. */ + make_history_line_current (temp); + + rl_point = rl_history_search_len; + rl_mark = rl_end; + + return 0; +} + +static void +rl_history_search_reinit () +{ + rl_history_search_pos = where_history (); + rl_history_search_len = rl_point; + prev_line_found = (char *)NULL; + if (rl_point) + { + if (rl_history_search_len >= history_string_size - 2) + { + history_string_size = rl_history_search_len + 2; + history_search_string = (char *)xrealloc (history_search_string, history_string_size); + } + history_search_string[0] = '^'; + strncpy (history_search_string + 1, rl_line_buffer, rl_point); + history_search_string[rl_point + 1] = '\0'; + } + _rl_free_saved_history_line (); +} + +/* Search forward in the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_search_forward (count, ignore) + int count, ignore; +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_next_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); +} + +/* Search backward through the history for the string of characters + from the start of the line to rl_point. This is a non-incremental + search. */ +int +rl_history_search_backward (count, ignore) + int count, ignore; +{ + if (count == 0) + return (0); + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_previous_history (count, ignore)); + return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); +} diff --git a/readline-4.3/shell.c b/readline-4.3/shell.c new file mode 100644 index 0000000..ad27cc1 --- /dev/null +++ b/readline-4.3/shell.c @@ -0,0 +1,196 @@ +/* shell.c -- readline utility functions that are normally provided by + bash when readline is linked as part of the shell. */ + +/* Copyright (C) 1997 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_LIMITS_H) +# include +#endif + +#include +#include + +#include + +#include "rlstdc.h" +#include "rlshell.h" +#include "xmalloc.h" + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid PARAMS((uid_t)); +#endif /* !HAVE_GETPW_DECLS */ + +#ifndef NULL +# define NULL 0 +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Bound on length of the string representing an integer value of type T. + Subtract one for the sign bit if T is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \ + + 1 + TYPE_SIGNED (t)) + +/* All of these functions are resolved from bash if we are linking readline + as part of bash. */ + +/* Does shell-like quoting using single quotes. */ +char * +sh_single_quote (string) + char *string; +{ + register int c; + char *result, *r, *s; + + result = (char *)xmalloc (3 + (4 * strlen (string))); + r = result; + *r++ = '\''; + + for (s = string; s && (c = *s); s++) + { + *r++ = c; + + if (c == '\'') + { + *r++ = '\\'; /* insert escaped single quote */ + *r++ = '\''; + *r++ = '\''; /* start new quoted string */ + } + } + + *r++ = '\''; + *r = '\0'; + + return (result); +} + +/* Set the environment variables LINES and COLUMNS to lines and cols, + respectively. */ +void +sh_set_lines_and_columns (lines, cols) + int 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) + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); + sprintf (b, "%d", lines); + setenv ("LINES", b, 1); + b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); + sprintf (b, "%d", cols); + setenv ("COLUMNS", b, 1); +# endif /* HAVE_SETENV */ +#endif /* !HAVE_PUTENV */ +} + +char * +sh_get_env_value (varname) + const char *varname; +{ + return ((char *)getenv (varname)); +} + +char * +sh_get_home_dir () +{ + char *home_dir; + struct passwd *entry; + + home_dir = (char *)NULL; + entry = getpwuid (getuid ()); + if (entry) + home_dir = entry->pw_dir; + return (home_dir); +} + +#if !defined (O_NDELAY) +# if defined (FNDELAY) +# define O_NDELAY FNDELAY +# endif +#endif + +int +sh_unset_nodelay_mode (fd) + int fd; +{ + int flags, bflags; + + if ((flags = fcntl (fd, F_GETFL, 0)) < 0) + return -1; + + bflags = 0; + +#ifdef O_NONBLOCK + bflags |= O_NONBLOCK; +#endif + +#ifdef O_NDELAY + bflags |= O_NDELAY; +#endif + + if (flags & bflags) + { + flags &= ~bflags; + return (fcntl (fd, F_SETFL, flags)); + } + + return 0; +} diff --git a/readline-4.3/shlib/Makefile.in b/readline-4.3/shlib/Makefile.in new file mode 100644 index 0000000..0cba57e --- /dev/null +++ b/readline-4.3/shlib/Makefile.in @@ -0,0 +1,437 @@ +## -*- text -*- ## +# Makefile for the GNU readline library shared library support. +# +# Copyright (C) 1998 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 USA. + +RL_LIBRARY_VERSION = @LIBVERSION@ +RL_LIBRARY_NAME = readline + +srcdir = @srcdir@ +VPATH = .:@top_srcdir@ +topdir = @top_srcdir@ +BUILD_DIR = @BUILD_DIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +RANLIB = @RANLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +RM = rm -f +CP = cp +MV = mv +LN = ln + +SHELL = @MAKE_SHELL@ + +host_os = @host_os@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +libdir = @libdir@ + +# Support an alternate destination root directory for package building +DESTDIR = + +CFLAGS = @CFLAGS@ +LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ @CFLAGS@ + +DEFS = @DEFS@ +LOCAL_DEFS = @LOCAL_DEFS@ + +# +# These values are generated for configure by ${topdir}/support/shobj-conf. +# If your system is not supported by that script, but includes facilities for +# dynamic loading of shared objects, please update the script and send the +# changes to bash-maintainers@gnu.org. +# +SHOBJ_CC = @SHOBJ_CC@ +SHOBJ_CFLAGS = @SHOBJ_CFLAGS@ +SHOBJ_LD = @SHOBJ_LD@ + +SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@ +SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@ +SHOBJ_LIBS = @SHOBJ_LIBS@ + +SHLIB_XLDFLAGS = @SHLIB_XLDFLAGS@ +SHLIB_LIBS = @SHLIB_LIBS@ +SHLIB_LIBSUFF = @SHLIB_LIBSUFF@ + +SHLIB_LIBVERSION = @SHLIB_LIBVERSION@ + +SHLIB_STATUS = @SHLIB_STATUS@ + +# shared library versioning +SHLIB_MAJOR= @SHLIB_MAJOR@ +# shared library systems like SVR4's do not use minor versions +SHLIB_MINOR= .@SHLIB_MINOR@ + +# For libraries which include headers from other libraries. +INCLUDES = -I. -I.. -I$(topdir) + +CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) $(INCLUDES) $(LOCAL_CFLAGS) $(CFLAGS) + +.SUFFIXES: .so + +.c.so: + ${RM} $@ + $(SHOBJ_CC) -c $(CCFLAGS) $(SHOBJ_CFLAGS) -o $*.o $< + $(MV) $*.o $@ + +# The name of the main library target. + +SHARED_READLINE = libreadline.$(SHLIB_LIBVERSION) +SHARED_HISTORY = libhistory.$(SHLIB_LIBVERSION) +SHARED_LIBS = $(SHARED_READLINE) $(SHARED_HISTORY) + +# The C code source files for this library. +CSOURCES = $(topdir)/readline.c $(topdir)/funmap.c $(topdir)/keymaps.c \ + $(topdir)/vi_mode.c $(topdir)/parens.c $(topdir)/rltty.c \ + $(topdir)/complete.c $(topdir)/bind.c $(topdir)/isearch.c \ + $(topdir)/display.c $(topdir)/signals.c $(topdir)/emacs_keymap.c \ + $(topdir)/vi_keymap.c $(topdir)/util.c $(topdir)/kill.c \ + $(topdir)/undo.c $(topdir)/macro.c $(topdir)/input.c \ + $(topdir)/callback.c $(topdir)/terminal.c $(topdir)/xmalloc.c \ + $(topdir)/history.c $(topdir)/histsearch.c $(topdir)/histexpand.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 + +# The header files for this library. +HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \ + posixstat.h posixdir.h posixjmp.h tilde.h rlconf.h rltty.h \ + ansi_stdlib.h tcap.h xmalloc.h rlprivate.h rlshell.h rlmbutil.h + +SHARED_HISTOBJ = history.so histexpand.so histfile.so histsearch.so shell.so \ + mbutil.so +SHARED_TILDEOBJ = tilde.so +SHARED_OBJ = readline.so vi_mode.so funmap.so keymaps.so parens.so search.so \ + rltty.so complete.so bind.so isearch.so display.so signals.so \ + util.so kill.so undo.so macro.so input.so callback.so terminal.so \ + text.so nls.so misc.so xmalloc.so $(SHARED_HISTOBJ) $(SHARED_TILDEOBJ) \ + compat.so + +########################################################################## + +all: $(SHLIB_STATUS) + +supported: $(SHARED_LIBS) + +unsupported: + @echo "Your system and compiler (${host_os}-${CC}) are not supported by the" + @echo "${topdir}/support/shobj-conf script." + @echo "If your operating system provides facilities for creating" + @echo "shared libraries, please update the script and re-run configure." + @echo "Please send the changes you made to bash-maintainers@gnu.org" + @echo "for inclusion in future bash and readline releases." + +$(SHARED_READLINE): $(SHARED_OBJ) + $(RM) $@ + $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_OBJ) $(SHLIB_LIBS) + +$(SHARED_HISTORY): $(SHARED_HISTOBJ) xmalloc.so + $(RM) $@ + $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_HISTOBJ) xmalloc.so $(SHLIB_LIBS) + +# Since tilde.c is shared between readline and bash, make sure we compile +# it with the right flags when it's built as part of readline +tilde.so: tilde.c + ${RM} $@ + $(SHOBJ_CC) -c $(CCFLAGS) $(SHOBJ_CFLAGS) -DREADLINE_LIBRARY -c -o tilde.o $(topdir)/tilde.c + $(MV) tilde.o $@ + +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) + @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) + @echo uninstall: you may need to run ldconfig + +clean mostlyclean: force + $(RM) $(SHARED_OBJ) $(SHARED_LIBS) + +distclean maintainer-clean: clean + $(RM) Makefile + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Dependencies +bind.so: $(topdir)/ansi_stdlib.h $(topdir)/posixstat.h +bind.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +bind.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +bind.so: $(topdir)/rltypedefs.h +bind.so: $(topdir)/tilde.h $(topdir)/history.h +compat.so: $(topdir)/rlstdc.h +callback.so: $(topdir)/rlconf.h +callback.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h +callback.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +callback.so: $(topdir)/rltypedefs.h +callback.so: $(topdir)/tilde.h +complete.so: $(topdir)/ansi_stdlib.h posixdir.h $(topdir)/posixstat.h +complete.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +complete.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +complete.so: $(topdir)/rltypedefs.h +complete.so: $(topdir)/tilde.h +display.so: $(topdir)/ansi_stdlib.h $(topdir)/posixstat.h +display.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +display.so: $(topdir)/tcap.h +display.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +display.so: $(topdir)/rltypedefs.h +display.so: $(topdir)/tilde.h $(topdir)/history.h +funmap.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +funmap.so: $(topdir)/rltypedefs.h +funmap.so: $(topdir)/rlconf.h $(topdir)/ansi_stdlib.h +funmap.so: ${BUILD_DIR}/config.h $(topdir)/tilde.h +histexpand.so: $(topdir)/ansi_stdlib.h +histexpand.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histexpand.so: ${BUILD_DIR}/config.h +histfile.so: $(topdir)/ansi_stdlib.h +histfile.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histfile.so: ${BUILD_DIR}/config.h +history.so: $(topdir)/ansi_stdlib.h +history.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +history.so: ${BUILD_DIR}/config.h +histsearch.so: $(topdir)/ansi_stdlib.h +histsearch.so: $(topdir)/history.h $(topdir)/histlib.h $(topdir)/rltypedefs.h +histsearch.so: ${BUILD_DIR}/config.h +input.so: $(topdir)/ansi_stdlib.h +input.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +input.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +input.so: $(topdir)/rltypedefs.h +input.so: $(topdir)/tilde.h +isearch.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +isearch.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +isearch.so: $(topdir)/rltypedefs.h +isearch.so: $(topdir)/ansi_stdlib.h $(topdir)/history.h $(topdir)/tilde.h +keymaps.so: emacs_keymap.c vi_keymap.c +keymaps.so: $(topdir)/keymaps.h $(topdir)/chardefs.h $(topdir)/rlconf.h +keymaps.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +keymaps.so: $(topdir)/rltypedefs.h +keymaps.so: ${BUILD_DIR}/config.h $(topdir)/ansi_stdlib.h $(topdir)/tilde.h +kill.so: $(topdir)/ansi_stdlib.h +kill.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +kill.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +kill.so: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rltypedefs.h +macro.so: $(topdir)/ansi_stdlib.h +macro.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +macro.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +macro.so: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rltypedefs.h +mbutil.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +mbutil.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/rltypedefs.h +mbutil.so: $(topdir)/chardefs.h $(topdir)/rlstdc.h +misc.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +misc.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +misc.so: $(topdir)/rltypedefs.h +misc.so: $(topdir)/history.h $(topdir)/tilde.h $(topdir)/ansi_stdlib.h +nls.so: $(topdir)/ansi_stdlib.h +nls.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +nls.o: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +nls.o: $(topdir)/rltypedefs.h +nls.o: $(topdir)/tilde.h $(topdir)/history.h $(topdir)/rlstdc.h +parens.so: $(topdir)/rlconf.h ${BUILD_DIR}/config.h +parens.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +parens.so: $(topdir)/rltypedefs.h +parens.so: $(topdir)/tilde.h +rltty.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +rltty.so: $(topdir)/rltty.h $(topdir)/tilde.h +rltty.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +rltty.so: $(topdir)/rltypedefs.h +search.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +search.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +search.so: $(topdir)/ansi_stdlib.h $(topdir)/history.h $(topdir)/tilde.h +search.so: $(topdir)/rltypedefs.h +signals.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +signals.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +signals.so: $(topdir)/history.h $(topdir)/tilde.h +signals.so: $(topdir)/rltypedefs.h +terminal.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +terminal.so: $(topdir)/tcap.h +terminal.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +terminal.so: $(topdir)/tilde.h $(topdir)/history.h +terminal.so: $(topdir)/rltypedefs.h +text.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +text.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +text.so: $(topdir)/rltypedefs.h +text.so: $(topdir)/history.h $(topdir)/tilde.h $(topdir)/ansi_stdlib.h +tilde.so: $(topdir)/ansi_stdlib.h ${BUILD_DIR}/config.h $(topdir)/tilde.h +undo.so: $(topdir)/ansi_stdlib.h +undo.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +undo.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +undo.so: $(topdir)/rltypedefs.h +undo.so: $(topdir)/tilde.h $(topdir)/history.h +util.so: $(topdir)/posixjmp.h $(topdir)/ansi_stdlib.h +util.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +util.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +util.so: $(topdir)/rltypedefs.h $(topdir)/tilde.h +vi_mode.so: $(topdir)/rldefs.h ${BUILD_DIR}/config.h $(topdir)/rlconf.h +vi_mode.so: $(topdir)/readline.h $(topdir)/keymaps.h $(topdir)/chardefs.h +vi_mode.so: $(topdir)/history.h $(topdir)/ansi_stdlib.h $(topdir)/tilde.h +vi_mode.so: $(topdir)/rltypedefs.h +xmalloc.so: ${BUILD_DIR}/config.h +xmalloc.so: $(topdir)/ansi_stdlib.h + +bind.so: $(topdir)/rlshell.h +histfile.so: $(topdir)/rlshell.h +nls.so: $(topdir)/rlshell.h +readline.so: $(topdir)/rlshell.h +shell.so: $(topdir)/rlshell.h +terminal.so: $(topdir)/rlshell.h +histexpand.so: $(topdir)/rlshell.h + +bind.so: $(topdir)/rlprivate.h +callback.so: $(topdir)/rlprivate.h +complete.so: $(topdir)/rlprivate.h +display.so: $(topdir)/rlprivate.h +input.so: $(topdir)/rlprivate.h +isearch.so: $(topdir)/rlprivate.h +kill.so: $(topdir)/rlprivate.h +macro.so: $(topdir)/rlprivate.h +mbutil.so: $(topdir)/rlprivate.h +misc.so: $(topdir)/rlprivate.h +nls.so: $(topdir)/rlprivate.h +parens.so: $(topdir)/rlprivate.h +readline.so: $(topdir)/rlprivate.h +rltty.so: $(topdir)/rlprivate.h +search.so: $(topdir)/rlprivate.h +signals.so: $(topdir)/rlprivate.h +terminal.so: $(topdir)/rlprivate.h +text.so: $(topdir)/rlprivate.h +undo.so: $(topdir)/rlprivate.h +util.so: $(topdir)/rlprivate.h +vi_mode.so: $(topdir)/rlprivate.h + +bind.so: $(topdir)/xmalloc.h +complete.so: $(topdir)/xmalloc.h +display.so: $(topdir)/xmalloc.h +funmap.so: $(topdir)/xmalloc.h +histexpand.so: $(topdir)/xmalloc.h +histfile.so: $(topdir)/xmalloc.h +history.so: $(topdir)/xmalloc.h +input.so: $(topdir)/xmalloc.h +isearch.so: $(topdir)/xmalloc.h +keymaps.so: $(topdir)/xmalloc.h +kill.so: $(topdir)/xmalloc.h +macro.so: $(topdir)/xmalloc.h +mbutil.so: $(topdir)/xmalloc.h +misc.so: $(topdir)/xmalloc.h +readline.so: $(topdir)/xmalloc.h +savestring.so: $(topdir)/xmalloc.h +search.so: $(topdir)/xmalloc.h +shell.so: $(topdir)/xmalloc.h +terminal.so: $(topdir)/xmalloc.h +text.so: $(topdir)/xmalloc.h +tilde.so: $(topdir)/xmalloc.h +undo.so: $(topdir)/xmalloc.h +util.so: $(topdir)/xmalloc.h +vi_mode.so: $(topdir)/xmalloc.h +xmalloc.so: $(topdir)/xmalloc.h + +complete.o: $(topdir)/rlmbutil.h +display.o: $(topdir)/rlmbutil.h +histexpand.o: $(topdir)/rlmbutil.h +input.o: $(topdir)/rlmbutil.h +isearch.o: $(topdir)/rlmbutil.h +mbutil.o: $(topdir)/rlmbutil.h +misc.o: $(topdir)/rlmbutil.h +readline.o: $(topdir)/rlmbutil.h +search.o: $(topdir)/rlmbutil.h +text.o: $(topdir)/rlmbutil.h +vi_mode.o: $(topdir)/rlmbutil.h + +bind.so: $(topdir)/bind.c +callback.so: $(topdir)/callback.c +compat.so: $(topdir)/compat.c +complete.so: $(topdir)/complete.c +display.so: $(topdir)/display.c +funmap.so: $(topdir)/funmap.c +input.so: $(topdir)/input.c +isearch.so: $(topdir)/isearch.c +keymaps.so: $(topdir)/keymaps.c $(topdir)/emacs_keymap.c $(topdir)/vi_keymap.c +kill.so: $(topdir)/kill.c +macro.so: $(topdir)/macro.c +mbutil.so: $(topdir)/mbutil.c +misc.so: $(topdir)/mbutil.c +nls.so: $(topdir)/nls.c +parens.so: $(topdir)/parens.c +readline.so: $(topdir)/readline.c +rltty.so: $(topdir)/rltty.c +savestring.so: $(topdir)/savestring.c +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 +tilde.so: $(topdir)/tilde.c +undo.so: $(topdir)/undo.c +util.so: $(topdir)/util.c +vi_mode.so: $(topdir)/vi_mode.c +xmalloc.so: $(topdir)/xmalloc.c + +histexpand.so: $(topdir)/histexpand.c +histfile.so: $(topdir)/histfile.c +history.so: $(topdir)/history.c +histsearch.so: $(topdir)/histsearch.c + +bind.so: bind.c +callback.so: callback.c +comapt.so: compat.c +complete.so: complete.c +display.so: display.c +funmap.so: funmap.c +input.so: input.c +isearch.so: isearch.c +keymaps.so: keymaps.c emacs_keymap.c vi_keymap.c +kill.so: kill.c +macro.so: macro.c +mbutil.so: mbutil.c +misc.so: misc.c +nls.so: nls.c +parens.so: parens.c +readline.so: readline.c +rltty.so: rltty.c +savestring.so: savestring.c +search.so: search.c +signals.so: signals.c +shell.so: shell.c +terminal.so: terminal.c +text.so: terminal.c +tilde.so: tilde.c +undo.so: undo.c +util.so: util.c +vi_mode.so: vi_mode.c +xmalloc.so: xmalloc.c + +histexpand.so: histexpand.c +histfile.so: histfile.c +history.so: history.c +histsearch.so: histsearch.c diff --git a/readline-4.3/signals.c b/readline-4.3/signals.c new file mode 100644 index 0000000..a73c36d --- /dev/null +++ b/readline-4.3/signals.c @@ -0,0 +1,400 @@ +/* signals.c -- signal handling support for readline. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include /* Just for NULL. Yuck. */ +#include +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) +# include +#endif /* GWINSZ_IN_SYS_IOCTL */ + +#if defined (HANDLE_SIGNALS) +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" + +#if !defined (RETSIGTYPE) +# if defined (VOID_SIGHANDLER) +# define RETSIGTYPE void +# else +# define RETSIGTYPE int +# endif /* !VOID_SIGHANDLER */ +#endif /* !RETSIGTYPE */ + +#if defined (VOID_SIGHANDLER) +# define SIGHANDLER_RETURN return +#else +# define SIGHANDLER_RETURN return (0) +#endif + +/* This typedef is equivalent to the one for Function; it allows us + to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */ +typedef RETSIGTYPE SigHandler (); + +#if defined (HAVE_POSIX_SIGNALS) +typedef struct sigaction sighandler_cxt; +# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh) +#else +typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt; +# define sigemptyset(m) +#endif /* !HAVE_POSIX_SIGNALS */ + +static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); +static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); + +/* Exported variables for use by applications. */ + +/* If non-zero, readline will install its own signal handlers for + SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ +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; +#endif + +static int signals_set_flag; +static int sigwinch_set_flag; + +/* **************************************************************** */ +/* */ +/* Signal Handling */ +/* */ +/* **************************************************************** */ + +static sighandler_cxt old_int, old_term, old_alrm, old_quit; +#if defined (SIGTSTP) +static sighandler_cxt old_tstp, old_ttou, old_ttin; +#endif +#if defined (SIGWINCH) +static sighandler_cxt old_winch; +#endif + +/* Readline signal handler functions. */ + +static RETSIGTYPE +rl_signal_handler (sig) + int sig; +{ +#if defined (HAVE_POSIX_SIGNALS) + sigset_t set; +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + long omask; +# else /* !HAVE_BSD_SIGNALS */ + sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */ +# endif /* !HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + RL_SETSTATE(RL_STATE_SIGHANDLER); + +#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 || sig == SIGALRM) + rl_set_sighandler (sig, SIG_IGN, &dummy_cxt); +#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */ + + switch (sig) + { + case SIGINT: + rl_free_line_state (); + /* FALLTHROUGH */ + +#if defined (SIGTSTP) + case SIGTSTP: + case SIGTTOU: + case SIGTTIN: +#endif /* SIGTSTP */ + case SIGALRM: + case SIGTERM: + case SIGQUIT: + rl_cleanup_after_signal (); + +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); + sigdelset (&set, sig); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + omask = sigblock (0); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + +#if defined (__EMX__) + signal (sig, SIG_ACK); +#endif + + kill (getpid (), sig); + + /* Let the signal that we just sent through. */ +#if defined (HAVE_POSIX_SIGNALS) + sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); +#else /* !HAVE_POSIX_SIGNALS */ +# if defined (HAVE_BSD_SIGNALS) + sigsetmask (omask & ~(sigmask (sig))); +# endif /* HAVE_BSD_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ + + rl_reset_after_signal (); + } + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} + +#if defined (SIGWINCH) +static RETSIGTYPE +rl_sigwinch_handler (sig) + int sig; +{ + SigHandler *oh; + +#if defined (MUST_REINSTALL_SIGHANDLERS) + sighandler_cxt dummy_winch; + + /* We don't want to change old_winch -- it holds the state of SIGWINCH + disposition set by the calling application. We need this state + because we call the application's SIGWINCH handler after updating + our own idea of the screen size. */ + rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch); +#endif + + RL_SETSTATE(RL_STATE_SIGHANDLER); + rl_resize_terminal (); + + /* If another sigwinch handler has been installed, call it. */ + oh = (SigHandler *)old_winch.sa_handler; + if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL) + (*oh) (sig); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); + SIGHANDLER_RETURN; +} +#endif /* SIGWINCH */ + +/* Functions to manage signal handling. */ + +#if !defined (HAVE_POSIX_SIGNALS) +static int +rl_sigaction (sig, nh, oh) + int sig; + sighandler_cxt *nh, *oh; +{ + oh->sa_handler = signal (sig, nh->sa_handler); + return 0; +} +#endif /* !HAVE_POSIX_SIGNALS */ + +/* Set up a readline-specific signal handler, saving the old signal + information in OHANDLER. Return the old signal handler, like + signal(). */ +static SigHandler * +rl_set_sighandler (sig, handler, ohandler) + int sig; + SigHandler *handler; + sighandler_cxt *ohandler; +{ + sighandler_cxt old_handler; +#if defined (HAVE_POSIX_SIGNALS) + struct sigaction act; + + act.sa_handler = handler; + act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */ + sigemptyset (&act.sa_mask); + sigemptyset (&ohandler->sa_mask); + sigaction (sig, &act, &old_handler); +#else + old_handler.sa_handler = (SigHandler *)signal (sig, handler); +#endif /* !HAVE_POSIX_SIGNALS */ + + /* XXX -- assume we have memcpy */ + /* If rl_set_signals is called twice in a row, don't set the old handler to + rl_signal_handler, because that would cause infinite recursion. */ + if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler) + memcpy (ohandler, &old_handler, sizeof (sighandler_cxt)); + + return (ohandler->sa_handler); +} + +static void +rl_maybe_set_sighandler (sig, handler, ohandler) + int sig; + SigHandler *handler; + sighandler_cxt *ohandler; +{ + sighandler_cxt dummy; + SigHandler *oh; + + sigemptyset (&dummy.sa_mask); + oh = rl_set_sighandler (sig, handler, ohandler); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (sig, ohandler, &dummy); +} + +int +rl_set_signals () +{ + sighandler_cxt dummy; + SigHandler *oh; + + if (rl_catch_signals && signals_set_flag == 0) + { + rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); + rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term); + rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit); + + oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm); + if (oh == (SigHandler *)SIG_IGN) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART) + /* If the application using readline has already installed a signal + handler with SA_RESTART, SIGALRM will cause reads to be restarted + automatically, so readline should just get out of the way. Since + we tested for SIG_IGN above, we can just test for SIG_DFL here. */ + if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART)) + rl_sigaction (SIGALRM, &old_alrm, &dummy); +#endif /* HAVE_POSIX_SIGNALS */ + +#if defined (SIGTSTP) + rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin); +#endif /* SIGTTIN */ + + signals_set_flag = 1; + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 0) + { + rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch); + sigwinch_set_flag = 1; + } +#endif /* SIGWINCH */ + + return 0; +} + +int +rl_clear_signals () +{ + sighandler_cxt dummy; + + if (rl_catch_signals && signals_set_flag == 1) + { + sigemptyset (&dummy.sa_mask); + + rl_sigaction (SIGINT, &old_int, &dummy); + rl_sigaction (SIGTERM, &old_term, &dummy); + rl_sigaction (SIGQUIT, &old_quit, &dummy); + rl_sigaction (SIGALRM, &old_alrm, &dummy); + +#if defined (SIGTSTP) + rl_sigaction (SIGTSTP, &old_tstp, &dummy); +#endif /* SIGTSTP */ + +#if defined (SIGTTOU) + rl_sigaction (SIGTTOU, &old_ttou, &dummy); +#endif /* SIGTTOU */ + +#if defined (SIGTTIN) + rl_sigaction (SIGTTIN, &old_ttin, &dummy); +#endif /* SIGTTIN */ + + signals_set_flag = 0; + } + +#if defined (SIGWINCH) + if (rl_catch_sigwinch && sigwinch_set_flag == 1) + { + sigemptyset (&dummy.sa_mask); + rl_sigaction (SIGWINCH, &old_winch, &dummy); + sigwinch_set_flag = 0; + } +#endif + + return 0; +} + +/* Clean up the terminal and readline state after catching a signal, before + resending it to the calling application. */ +void +rl_cleanup_after_signal () +{ + _rl_clean_up_for_exit (); + (*rl_deprep_term_function) (); + rl_clear_signals (); + rl_clear_pending_input (); +} + +/* Reset the terminal and readline state after a signal handler returns. */ +void +rl_reset_after_signal () +{ + (*rl_prep_term_function) (_rl_meta_flag); + rl_set_signals (); +} + +/* Free up the readline variable line state for the current line (undo list, + any partial history entry, any keyboard macros in progress, and any + numeric arguments in process) after catching a signal, before calling + rl_cleanup_after_signal(). */ +void +rl_free_line_state () +{ + register HIST_ENTRY *entry; + + rl_free_undo_list (); + + entry = current_history (); + if (entry) + entry->data = (char *)NULL; + + _rl_kill_kbd_macro (); + rl_clear_message (); + _rl_init_argument (); +} + +#endif /* HANDLE_SIGNALS */ diff --git a/readline-4.3/support/config.guess b/readline-4.3/support/config.guess new file mode 100755 index 0000000..5668108 --- /dev/null +++ b/readline-4.3/support/config.guess @@ -0,0 +1,1393 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# 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 +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +elif (test -f /usr/5bin/uname) >/dev/null 2>&1 ; then # bash + PATH=$PATH:/usr/5bin +fi + +UNAME=`(uname) 2>/dev/null` || UNAME=unknown # bash +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + # NOTE -- begin cases added for bash (mostly legacy) -- NOTE + mac68k:machten:*:*) + echo mac68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + concurrent*:*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo concurrent-concurrent-sysv3 + else + echo concurrent-concurrent-bsd + fi + exit 0 ;; + ppc*:SunOS:5.*:*) + echo ppc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sparc:UNIX_SV:4.*:*) + echo sparc-unknown-sysv${UNAME_RELEASE} + exit 0 ;; + mips:UNIX_SV:4.*:*) + echo mips-mips-sysv${UNAME_RELEASE} + exit 0 ;; + mips:OSF*1:*:*) + echo mips-mips-osf1 + exit 0 ;; + mips:4.4BSD:*:*) + echo mips-mips-bsd4.4 + exit 0 ;; + MIS*:SMP_DC.OSx:*:dcosx) # not the same as below + echo pyramid-pyramid-sysv4 + exit 0 ;; + news*:NEWS*:*:*) + echo mips-sony-newsos${UNAME_RELEASE} + exit 0 ;; + *370:AIX:*:*) + echo ibm370-ibm-aix${UNAME_RELEASE} + exit 0 ;; + ksr1:OSF*1:*:*) + echo ksr1-ksr-osf1 + exit 0 ;; + esa:OSF*1:*:* | ESA:OSF*:*:*) + echo esa-ibm-osf1 + exit 0 ;; + DNP*:DNIX:*:*) + echo m68k-dnix-sysv + exit 0 ;; + *3b2*:*:*:*) + echo we32k-att-sysv3 + exit 0 ;; + Alpha*:Windows_NT:*:SP*) + echo alpha-pc-opennt + exit 0 ;; + *:Windows_NT:*:SP*) + echo i386-pc-opennt + exit 0 ;; + + # NOTE -- end legacy cases added for bash -- NOTE + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + vax:OpenBSD:*:*) # bash + echo vax-dec-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +# NOTE -- Begin fallback cases added for bash -- NOTE +case "$UNAME" in +uts) echo uts-amdahl-sysv${UNAME_RELEASE}; exit 0 ;; +esac + +if [ -f /bin/fxc.info ]; then + echo fxc-alliant-concentrix + exit 0 +fi +# NOTE -- End fallback cases added for bash -- NOTE + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/readline-4.3/support/config.sub b/readline-4.3/support/config.sub new file mode 100644 index 0000000..538dc09 --- /dev/null +++ b/readline-4.3/support/config.sub @@ -0,0 +1,1497 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# 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 +# 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + + # NOTE -- BEGIN cases added for Bash -- NOTE + butterfly-bbn* | cadmus-* | ews*-nec | masscomp-masscomp \ + | tandem-* | symmetric-* | drs6000-icl | *-*ardent | concurrent-* \ + | ksr1-* | esa-ibm | fxc-alliant | *370-amdahl | sx[45]*-nec ) + ;; + # NOTE -- END cases added for Bash -- NOTE + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax | multimax) # bash + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hbullx20-bull) + basic_machine=m68k-bull # bash + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + ibm032-*) + basic_machine=ibmrt-ibm # bash + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386-go32) + basic_machine=i386-pc # bash + os=-go32 + ;; + i386-mingw32) + basic_machine=i386-pc # bash + os=-mingw32 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + luna88k-omron* | m88k-omron*) # bash + basic_machine=m88k-omron + ;; + magicstation*) + basic_machine=magicstation-unknown # bash + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + odt | odt3 | odt4) # SCO Open Desktop + basic_machine=i386-pc # bash + os=-sco3.2v4 + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + osr5 | sco5) # SCO Open Server + basic_machine=i386-pc # bash + os=-sco3.2v5 + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + uw2 | unixware | unixware2) # bash + basic_machine=i386-pc + os=-sysv4.2uw2.1 + ;; + uw7 | unixware7) # bash + basic_machine=i386-pc + os=-sysv5uw7 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware7*) # bash + os=-sysv5uw7 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + # NOTE -- BEGIN CASES ADDED FOR Bash -- NOTE + -powerux* | -superux*) + ;; + # NOTE -- END CASES ADDED FOR Bash -- NOTE + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + -sysvr5) # bash + os=-sysv5 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) # bash + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/readline-4.3/support/install.sh b/readline-4.3/support/install.sh new file mode 100755 index 0000000..0cac004 --- /dev/null +++ b/readline-4.3/support/install.sh @@ -0,0 +1,247 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/readline-4.3/support/mkdirs b/readline-4.3/support/mkdirs new file mode 100755 index 0000000..ce4fb23 --- /dev/null +++ b/readline-4.3/support/mkdirs @@ -0,0 +1,48 @@ +#! /bin/sh +# +# mkdirs - a work-alike for `mkdir -p' +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +for dir +do + + test -d "$dir" && continue + + tomake=$dir + while test -n "$dir" ; do + # dir=${dir%/*} + # dir=`expr "$dir" ':' '\(/.*\)/[^/]*'` + if dir=`expr "$dir" ':' '\(.*\)/[^/]*'`; then + tomake="$dir $tomake" + else + dir= + fi + done + + for d in $tomake + do + test -d "$d" && continue + echo mkdir "$d" + mkdir "$d" + done +done + +exit 0 diff --git a/readline-4.3/support/mkdist b/readline-4.3/support/mkdist new file mode 100755 index 0000000..06e6155 --- /dev/null +++ b/readline-4.3/support/mkdist @@ -0,0 +1,120 @@ +#! /bin/bash - +# +# mkdist - make a distribution directory from a master manifest file +# +# usage: mkdist [-m manifest] [-s srcdir] [-r rootname] [-v] version +# +# SRCDIR defaults to src +# MANIFEST defaults to $SRCDIR/MANIFEST +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +SRCDIR=src +ROOTNAME=bash + +usage() +{ + echo usage: mkdist [-m manifest] [-s srcdir] [-r rootname] [-v] version 1>&2 + exit 2 +} + +vmsg() +{ + if [ -n "$verbose" ]; then + echo mkdist: "$@" + fi +} + +while getopts m:s:r:v name +do + case $name in + m) MANIFEST=$OPTARG ;; + s) SRCDIR=$OPTARG ;; + r) ROOTNAME=$OPTARG ;; + v) verbose=yes ;; + ?) usage ;; + esac +done + +: ${MANIFEST:=$SRCDIR/MANIFEST} + +vmsg using $MANIFEST + +shift $(( $OPTIND - 1 )) + +if [ $# -lt 1 ]; then + usage +fi + +version=$1 +newdir=${ROOTNAME}-$version + +vmsg creating distribution for $ROOTNAME version $version in $newdir + +if [ ! -d $newdir ]; then + mkdir $newdir || { echo $0: cannot make directory $newdir 1>&2 ; exit 1; } +fi + +dirmode=755 +filmode=644 + +while read fname type mode +do + [ -z "$fname" ] && continue + + case "$fname" in + \#*) continue ;; + esac + + case "$type" in + d) mkdir $newdir/$fname ;; + f) cp -p $SRCDIR/$fname $newdir/$fname ;; + s) ln -s $mode $newdir/$fname ; mode= ;; # symlink + l) ln $mode $newdir/$fname ; mode= ;; # hard link + *) echo "unknown file type $type" 1>&2 ;; + esac + + if [ -n "$mode" ]; then + chmod $mode $newdir/$fname + fi + +done < $MANIFEST + +# cut off the `-alpha' in something like `2.0-alpha', leaving just the +# numeric version +#version=${version%%-*} + +#case "$version" in +#*.*.*) vers=${version%.*} ;; +#*.*) vers=${version} ;; +#esac + +#echo $vers > $newdir/.distribution + +#case "$version" in +#*.*.*) plevel=${version##*.} ;; +#*) plevel=0 ;; +#esac +#[ -z "$plevel" ] && plevel=0 +#echo ${plevel} > $newdir/.patchlevel + +vmsg $newdir created + +exit 0 diff --git a/readline-4.3/support/shlib-install b/readline-4.3/support/shlib-install new file mode 100755 index 0000000..654cfa9 --- /dev/null +++ b/readline-4.3/support/shlib-install @@ -0,0 +1,156 @@ +#! /bin/sh +# +# 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 +# +# Chet Ramey +# chet@po.cwru.edu + +# +# defaults +# +INSTALLDIR=/usr/local/lib +LDCONFIG=ldconfig + +PROGNAME=`basename $0` +USAGE="$PROGNAME [-D] -O host_os -d installation-dir -i install-prog [-U] library" + +# process options + +while [ $# -gt 0 ]; do + case "$1" in + -O) shift; host_os="$1"; shift ;; + -d) shift; INSTALLDIR="$1"; shift ;; + -i) shift; INSTALLPROG="$1" ; shift ;; + -D) echo=echo ; shift ;; + -U) uninstall=true ; shift ;; + -*) echo "$USAGE" >&2 ; exit 2;; + *) break ;; + esac +done + +# set install target name +LIBNAME="$1" + +if [ -z "$LIBNAME" ]; then + echo "$USAGE" >&2 + exit 2 +fi + +OLDSUFF=old +MV=mv +RM="rm -f" +LN="ln -s" + +# pre-install + +if [ -z "$uninstall" ]; then + ${echo} $RM ${INSTALLDIR}/${LIBNAME}.${OLDSUFF} + if [ -f "$INSTALLDIR/$LIBNAME" ]; then + ${echo} $MV $INSTALLDIR/$LIBNAME ${INSTALLDIR}/${LIBNAME}.${OLDSUFF} + fi +fi + +# install/uninstall + +if [ -z "$uninstall" ] ; then + ${echo} eval ${INSTALLPROG} $LIBNAME ${INSTALLDIR}/${LIBNAME} +else + ${echo} ${RM} ${INSTALLDIR}/${LIBNAME} +fi + +# post-install/uninstall + +# HP-UX and Darwin/MacOS X require that a shared library have execute permission +case "$host_os" in +hpux*|darwin*|macosx*) + if [ -z "$uninstall" ]; then + chmod 555 ${INSTALLDIR}/${LIBNAME} + fi ;; +*) ;; +esac + +case "$LIBNAME" in +*.*.[0-9].[0-9]) # libname.so.M.N + LINK2=`echo $LIBNAME | sed 's:\(.*\..*\.[0-9]\)\.[0-9]:\1:'` # libname.so.M + LINK1=`echo $LIBNAME | sed 's:\(.*\..*\)\.[0-9]\.[0-9]:\1:'` # libname.so + ;; +*.*.[0-9]) # libname.so.M + LINK1=`echo $LIBNAME | sed 's:\(.*\..*\)\.[0-9]:\1:'` # libname.so + ;; +*.[0-9]) # libname.M + LINK1=`echo $LIBNAME | sed 's:\(.*\)\.[0-9]:\1:'` # libname + ;; +*.[0-9].[0-9].dylib) # libname.M.N.dylib + LINK2=`echo $LIBNAME | sed 's:\(.*\.[0-9]\)\.[0-9]:\1:'` # libname.M.dylib + 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' + +# +# Create symlinks to the installed library. This section is incomplete. +# +case "$host_os" in +*linux*|bsdi4*|*gnu*|darwin*|macosx*) + # libname.so.M -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK2 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + fi + + # libname.so -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + ;; + +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 + fi + ;; + + +# FreeBSD 3.x and above can have either a.out or ELF shared libraries +freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) + if [ -x /usr/bin/objformat ] && [ "`/usr/bin/objformat`" = "elf" ]; then + # libname.so -> libname.so.M + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + else + # libname.so.M -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK2 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2 + fi + + # libname.so -> libname.so.M.N + ${echo} ${RM} ${INSTALLDIR}/$LINK1 + if [ -z "$uninstall" ]; then + ${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1 + fi + fi + ;; + +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} + fi + ;; + +*) ;; +esac + +exit 0 diff --git a/readline-4.3/support/shobj-conf b/readline-4.3/support/shobj-conf new file mode 100755 index 0000000..6bd7fb1 --- /dev/null +++ b/readline-4.3/support/shobj-conf @@ -0,0 +1,458 @@ +#! /bin/sh +# +# shobj-conf -- output a series of variable assignments to be substituted +# into a Makefile by configure which specify system-dependent +# information for creating shared objects that may be loaded +# into bash with `enable -f' +# +# usage: shobj-conf [-C compiler] -c host_cpu -o host_os -v host_vendor +# +# Chet Ramey +# chet@po.cwru.edu + +# Copyright (C) 1996-2002 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 USA. + +# +# defaults +# +SHOBJ_STATUS=supported +SHLIB_STATUS=supported + +SHOBJ_CC=cc +SHOBJ_CFLAGS= +SHOBJ_LD= +SHOBJ_LDFLAGS= +SHOBJ_XLDFLAGS= +SHOBJ_LIBS= + +SHLIB_XLDFLAGS= +SHLIB_LIBS= +SHLIB_LIBSUFF='so' + +SHLIB_LIBVERSION='$(SHLIB_LIBSUFF)' + +PROGNAME=`basename $0` +USAGE="$PROGNAME [-C compiler] -c host_cpu -o host_os -v host_vendor" + +while [ $# -gt 0 ]; do + case "$1" in + -C) shift; SHOBJ_CC="$1"; shift ;; + -c) shift; host_cpu="$1"; shift ;; + -o) shift; host_os="$1"; shift ;; + -v) shift; host_vendor="$1"; shift ;; + *) echo "$USAGE" >&2 ; exit 2;; + esac +done + +case "${host_os}-${SHOBJ_CC}" in +sunos4*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD=/usr/bin/ld + SHOBJ_LDFLAGS='-assert pure-text' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +sunos4*) + SHOBJ_CFLAGS=-pic + SHOBJ_LD=/usr/bin/ld + SHOBJ_LDFLAGS='-assert pure-text' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +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,$@' + +# SHLIB_XLDFLAGS='-R $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sunos5*|solaris2*) + SHOBJ_CFLAGS='-K pic' + SHOBJ_LD=/usr/ccs/bin/ld + SHOBJ_LDFLAGS='-G -dy -z text -i -h $@' + +# SHLIB_XLDFLAGS='-R $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +# All versions of Linux or the semi-mythical GNU Hurd. +linux*|gnu*) + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir) -Wl,-soname,`basename $@ $(SHLIB_MINOR)`' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +freebsd2* | netbsd*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-x -Bshareable' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +# FreeBSD-3.x ELF +freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + + if [ -x /usr/bin/objformat ] && [ "`/usr/bin/objformat`" = "elf" ]; then + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + else + SHOBJ_LDFLAGS='-shared' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + fi + ;; + +# Darwin/MacOS X +darwin*|macosx*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=supported + + SHOBJ_CFLAGS='-dynamic -fno-common' + + SHOBJ_LD=/usr/bin/libtool + + 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' + + SHLIB_LIBS='-lSystem' + ;; + +openbsd*) + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_XLDFLAGS='-R$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +bsdi2*) + SHOBJ_CC=shlicc2 + SHOBJ_CFLAGS= + SHOBJ_LD=ld + SHOBJ_LDFLAGS=-r + SHOBJ_LIBS=-lc_s.2.1.0 + + # BSD/OS 2.x and 3.x `shared libraries' are too much of a pain in + # the ass -- they require changing {/usr/lib,etc}/shlib.map on + # each system, and the library creation process is byzantine + SHLIB_STATUS=unsupported + ;; + +bsdi3*) + SHOBJ_CC=shlicc2 + SHOBJ_CFLAGS= + SHOBJ_LD=ld + SHOBJ_LDFLAGS=-r + SHOBJ_LIBS=-lc_s.3.0.0 + + # BSD/OS 2.x and 3.x `shared libraries' are too much of a pain in + # the ass -- they require changing {/usr/lib,etc}/shlib.map on + # each system, and the library creation process is byzantine + SHLIB_STATUS=unsupported + ;; + +bsdi4*) + # BSD/OS 4.x now supports ELF and SunOS-style dynamically-linked + # shared libraries. gcc 2.x is the standard compiler, and the + # `normal' gcc options should work as they do in Linux. + + SHOBJ_CFLAGS=-fPIC + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-soname,`basename $@ $(SHLIB_MINOR)`' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' + ;; + +osf*-*gcc*) + # Fix to use gcc linker driver from bfischer@TechFak.Uni-Bielefeld.DE + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +osf*) + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-shared -soname $@ -expect_unresolved "*"' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +aix4.[2-9]*-*gcc*) # lightly tested by jik@cisco.com + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='ld' + SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall' + SHOBJ_XLDFLAGS='-G' + + SHLIB_XLDFLAGS='-bM:SRE' + SHLIB_LIBS='-lcurses -lc' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +aix4.[2-9]*) + SHOBJ_CFLAGS=-K + SHOBJ_LD='ld' + SHOBJ_LDFLAGS='-bdynamic -bnoentry -bexpall' + SHOBJ_XLDFLAGS='-G' + + SHLIB_XLDFLAGS='-bM:SRE' + SHLIB_LIBS='-lcurses -lc' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +# +# THE FOLLOWING ARE UNTESTED -- and some may not support the dlopen interface +# +irix[56]*-*gcc*) + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-soname,$@' + + SHLIB_XLDFLAGS='-Wl,-rpath,$(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +irix[56]*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld +# SHOBJ_LDFLAGS='-call_shared -hidden_symbol -no_unresolved -soname $@' +# Change from David Kaelbling . If you have problems, +# remove the `-no_unresolved' + SHOBJ_LDFLAGS='-shared -no_unresolved -soname $@' + + SHLIB_XLDFLAGS='-rpath $(libdir)' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux9*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s' + + SHLIB_XLDFLAGS='-Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux9*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +hpux10*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s' + + SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux10*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s +h $@' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +hpux11*-*gcc*) + # must use gcc; the bundled cc cannot compile PIC code + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' +# SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,-B,symbolic -Wl,+s -Wl,+std -Wl,+h,$@' + SHOBJ_LDFLAGS='-shared -fpic -Wl,-b -Wl,+s -Wl,+h,$@' + + SHLIB_XLDFLAGS='-Wl,+b,$(libdir)' + SHLIB_LIBSUFF='sl' + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +hpux11*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + + # If you are using the HP ANSI C compiler, you can uncomment and use + # this code (I have not tested it) +# SHOBJ_STATUS=supported +# SHLIB_STATUS=supported +# +# SHOBJ_CFLAGS='+z' +# SHOBJ_LD='ld' +# SHOBJ_LDFLAGS='-b +s +h $@' +# +# SHLIB_XLDFLAGS='+b $(libdir)' +# SHLIB_LIBSUFF='sl' +# SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + + ;; + +sysv4*-*gcc*) + SHOBJ_CFLAGS=-shared + SHOBJ_LDFLAGS='-shared -h $@' + SHOBJ_LD='${CC}' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv4*) + SHOBJ_CFLAGS='-K PIC' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-dy -z text -G -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sco3.2v5*-*gcc*) + SHOBJ_CFLAGS='-fpic' # DEFAULTS TO ELF + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sco3.2v5*) + SHOBJ_CFLAGS='-K pic -b elf' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -b elf -dy -z text -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5uw7*-*gcc*) + SHOBJ_CFLAGS='-fpic' + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +sysv5uw7*) + 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}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +dgux*) + SHOBJ_CFLAGS='-K pic' + SHOBJ_LD=ld + SHOBJ_LDFLAGS='-G -dy -h $@' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +msdos*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + ;; + +# +# Rely on correct gcc configuration for everything else +# +*-*gcc*) + SHOBJ_CFLAGS=-fpic + SHOBJ_LD='${CC}' + SHOBJ_LDFLAGS='-shared' + + SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' + ;; + +*) + SHOBJ_STATUS=unsupported + SHLIB_STATUS=unsupported + ;; + +esac + +echo SHOBJ_CC=\'"$SHOBJ_CC"\' +echo SHOBJ_CFLAGS=\'"$SHOBJ_CFLAGS"\' +echo SHOBJ_LD=\'"$SHOBJ_LD"\' +echo SHOBJ_LDFLAGS=\'"$SHOBJ_LDFLAGS"\' +echo SHOBJ_XLDFLAGS=\'"$SHOBJ_XLDFLAGS"\' +echo SHOBJ_LIBS=\'"$SHOBJ_LIBS"\' + +echo SHLIB_XLDFLAGS=\'"$SHLIB_XLDFLAGS"\' +echo SHLIB_LIBS=\'"$SHLIB_LIBS"\' +echo SHLIB_LIBSUFF=\'"$SHLIB_LIBSUFF"\' +echo SHLIB_LIBVERSION=\'"$SHLIB_LIBVERSION"\' + +echo SHOBJ_STATUS=\'"$SHOBJ_STATUS"\' +echo SHLIB_STATUS=\'"$SHLIB_STATUS"\' + +exit 0 diff --git a/readline-4.3/support/wcwidth.c b/readline-4.3/support/wcwidth.c new file mode 100644 index 0000000..ace9a3a --- /dev/null +++ b/readline-4.3/support/wcwidth.c @@ -0,0 +1,236 @@ +/* + * This is an implementation of wcwidth() and wcswidth() as defined in + * "The Single UNIX Specification, Version 2, The Open Group, 1997" + * + * + * Markus Kuhn -- 2001-09-08 -- public domain + */ + +#include + +struct interval { + unsigned short first; + unsigned short last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * FullWidth (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +int wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + static const struct interval combining[] = { + { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 }, + { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, + { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, + { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, + { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, + { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, + { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, + { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, + { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, + { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, + { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, + { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F }, + { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A }, + { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2ffff))); +} + + +int wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + + +/* + * The following function is the same as wcwidth(), except that + * spacing characters in the East Asian Ambiguous (A) category as + * defined in Unicode Technical Report #11 have a column width of 2. + * This experimental variant might be useful for users of CJK legacy + * encodings who want to migrate to UCS. It is not otherwise + * recommended for general use. + */ +static int wcwidth_cjk(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters */ + static const struct interval ambiguous[] = { + { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, + { 0x00AA, 0x00AA }, { 0x00AD, 0x00AE }, { 0x00B0, 0x00B4 }, + { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 }, + { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 }, + { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED }, + { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA }, + { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 }, + { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B }, + { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 }, + { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 }, + { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 }, + { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE }, + { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 }, + { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA }, + { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 }, + { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, + { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, + { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0300, 0x034E }, + { 0x0360, 0x0362 }, { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, + { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, + { 0x0410, 0x044F }, { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, + { 0x2013, 0x2016 }, { 0x2018, 0x2019 }, { 0x201C, 0x201D }, + { 0x2020, 0x2022 }, { 0x2024, 0x2027 }, { 0x2030, 0x2030 }, + { 0x2032, 0x2033 }, { 0x2035, 0x2035 }, { 0x203B, 0x203B }, + { 0x203E, 0x203E }, { 0x2074, 0x2074 }, { 0x207F, 0x207F }, + { 0x2081, 0x2084 }, { 0x20AC, 0x20AC }, { 0x2103, 0x2103 }, + { 0x2105, 0x2105 }, { 0x2109, 0x2109 }, { 0x2113, 0x2113 }, + { 0x2116, 0x2116 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 }, + { 0x212B, 0x212B }, { 0x2153, 0x2155 }, { 0x215B, 0x215E }, + { 0x2160, 0x216B }, { 0x2170, 0x2179 }, { 0x2190, 0x2199 }, + { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 }, + { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, + { 0x2207, 0x2208 }, { 0x220B, 0x220B }, { 0x220F, 0x220F }, + { 0x2211, 0x2211 }, { 0x2215, 0x2215 }, { 0x221A, 0x221A }, + { 0x221D, 0x2220 }, { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, + { 0x2227, 0x222C }, { 0x222E, 0x222E }, { 0x2234, 0x2237 }, + { 0x223C, 0x223D }, { 0x2248, 0x2248 }, { 0x224C, 0x224C }, + { 0x2252, 0x2252 }, { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, + { 0x226A, 0x226B }, { 0x226E, 0x226F }, { 0x2282, 0x2283 }, + { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, + { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, + { 0x2329, 0x232A }, { 0x2460, 0x24BF }, { 0x24D0, 0x24E9 }, + { 0x2500, 0x254B }, { 0x2550, 0x2574 }, { 0x2580, 0x258F }, + { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, + { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, + { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, + { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, + { 0x2605, 0x2606 }, { 0x2609, 0x2609 }, { 0x260E, 0x260F }, + { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 }, + { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 }, + { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F }, + { 0x273D, 0x273D }, { 0x3008, 0x300B }, { 0x3014, 0x3015 }, + { 0x3018, 0x301B }, { 0xFFFD, 0xFFFD } + }; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, + sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return wcwidth(ucs); +} + + +int wcswidth_cjk(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} diff --git a/readline-4.3/tcap.h b/readline-4.3/tcap.h new file mode 100644 index 0000000..58ab894 --- /dev/null +++ b/readline-4.3/tcap.h @@ -0,0 +1,60 @@ +/* tcap.h -- termcap library functions and variables. */ + +/* Copyright (C) 1996 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_RLTCAP_H_) +#define _RLTCAP_H_ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#if defined (HAVE_TERMCAP_H) +# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES) +# include "rltty.h" +# endif +# include +#else + +/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. + Unfortunately, PC is a global variable used by the termcap library. */ +#ifdef PC +# undef PC +#endif + +extern char PC; +extern char *UP, *BC; + +extern short ospeed; + +extern int tgetent (); +extern int tgetflag (); +extern int tgetnum (); +extern char *tgetstr (); + +extern int tputs (); + +extern char *tgoto (); + +#endif /* HAVE_TERMCAP_H */ + +#endif /* !_RLTCAP_H_ */ diff --git a/readline-4.3/terminal.c b/readline-4.3/terminal.c new file mode 100644 index 0000000..f3f5b6c --- /dev/null +++ b/readline-4.3/terminal.c @@ -0,0 +1,662 @@ +/* terminal.c -- controlling the terminal with termcap. */ + +/* Copyright (C) 1996 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include "posixstat.h" +#include +#if defined (HAVE_SYS_FILE_H) +# include +#endif /* HAVE_SYS_FILE_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) +# include +#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ + +#include "rltty.h" +#include "tcap.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay) +#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc) + +/* **************************************************************** */ +/* */ +/* Terminal and Termcap */ +/* */ +/* **************************************************************** */ + +static char *term_buffer = (char *)NULL; +static char *term_string_buffer = (char *)NULL; + +static int tcap_initialized; + +#if !defined (__linux__) +# if defined (__EMX__) || defined (NEED_EXTERN_PC) +extern +# endif /* __EMX__ || NEED_EXTERN_PC */ +char PC, *BC, *UP; +#endif /* __linux__ */ + +/* Some strings to control terminal actions. These are output by tputs (). */ +char *_rl_term_clreol; +char *_rl_term_clrpag; +char *_rl_term_cr; +char *_rl_term_backspace; +char *_rl_term_goto; +char *_rl_term_pc; + +/* Non-zero if we determine that the terminal can do character insertion. */ +int _rl_terminal_can_insert = 0; + +/* How to insert characters. */ +char *_rl_term_im; +char *_rl_term_ei; +char *_rl_term_ic; +char *_rl_term_ip; +char *_rl_term_IC; + +/* How to delete characters. */ +char *_rl_term_dc; +char *_rl_term_DC; + +#if defined (HACK_TERMCAP_MOTION) +char *_rl_term_forward_char; +#endif /* HACK_TERMCAP_MOTION */ + +/* How to go up a line. */ +char *_rl_term_up; + +/* A visible bell; char if the terminal can be made to flash the screen. */ +static char *_rl_visible_bell; + +/* Non-zero means the terminal can auto-wrap lines. */ +int _rl_term_autowrap; + +/* Non-zero means that this terminal has a meta key. */ +static int term_has_meta; + +/* The sequences to write to turn on and off the meta key, if this + terminal has one. */ +static char *_rl_term_mm; +static char *_rl_term_mo; + +/* The key sequences output by the arrow keys, if this terminal has any. */ +static char *_rl_term_ku; +static char *_rl_term_kd; +static char *_rl_term_kr; +static char *_rl_term_kl; + +/* How to initialize and reset the arrow keys, if this terminal has any. */ +static char *_rl_term_ks; +static char *_rl_term_ke; + +/* The key sequences sent by the Home and End keys, if any. */ +static char *_rl_term_kh; +static char *_rl_term_kH; +static char *_rl_term_at7; /* @7 */ + +/* Insert key */ +static char *_rl_term_kI; + +/* Cursor control */ +static char *_rl_term_vs; /* very visible */ +static char *_rl_term_ve; /* normal */ + +static void bind_termcap_arrow_keys PARAMS((Keymap)); + +/* Variables that hold the screen dimensions, used by the display code. */ +int _rl_screenwidth, _rl_screenheight, _rl_screenchars; + +/* Non-zero means the user wants to enable the keypad. */ +int _rl_enable_keypad; + +/* Non-zero means the user wants to enable a meta key. */ +int _rl_enable_meta = 1; + +#if defined (__EMX__) +static void +_emx_get_screensize (swp, shp) + int *swp, *shp; +{ + int sz[2]; + + _scrsize (sz); + + if (swp) + *swp = sz[0]; + if (shp) + *shp = sz[1]; +} +#endif + +/* Get readline's idea of the screen size. TTY is a file descriptor open + to the terminal. If IGNORE_ENV is true, we do not pay attention to the + values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being + non-null serve to check whether or not we have initialized termcap. */ +void +_rl_get_screen_size (tty, ignore_env) + int tty, ignore_env; +{ + char *ss; +#if defined (TIOCGWINSZ) + struct winsize window_size; +#endif /* TIOCGWINSZ */ + +#if defined (TIOCGWINSZ) + if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) + { + _rl_screenwidth = (int) window_size.ws_col; + _rl_screenheight = (int) window_size.ws_row; + } +#endif /* TIOCGWINSZ */ + +#if defined (__EMX__) + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); +#endif + + /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV + is unset. */ + if (_rl_screenwidth <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS"))) + _rl_screenwidth = atoi (ss); + +#if !defined (__DJGPP__) + if (_rl_screenwidth <= 0 && term_string_buffer) + _rl_screenwidth = tgetnum ("co"); +#endif + } + + /* Environment variable LINES overrides setting of "li" if IGNORE_ENV + is unset. */ + if (_rl_screenheight <= 0) + { + if (ignore_env == 0 && (ss = sh_get_env_value ("LINES"))) + _rl_screenheight = atoi (ss); + +#if !defined (__DJGPP__) + if (_rl_screenheight <= 0 && term_string_buffer) + _rl_screenheight = tgetnum ("li"); +#endif + } + + /* If all else fails, default to 80x24 terminal. */ + if (_rl_screenwidth <= 1) + _rl_screenwidth = 80; + + if (_rl_screenheight <= 0) + _rl_screenheight = 24; + + /* If we're being compiled as part of bash, set the environment + variables $LINES and $COLUMNS to new values. Otherwise, just + do a pair of putenv () or setenv () calls. */ + sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth); + + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +_rl_set_screen_size (rows, cols) + int rows, cols; +{ + if (rows == 0 || cols == 0) + return; + + _rl_screenheight = rows; + _rl_screenwidth = cols; + + if (_rl_term_autowrap == 0) + _rl_screenwidth--; + + _rl_screenchars = _rl_screenwidth * _rl_screenheight; +} + +void +rl_set_screen_size (rows, cols) + int rows, cols; +{ + _rl_set_screen_size (rows, cols); +} + +void +rl_get_screen_size (rows, cols) + int *rows, *cols; +{ + if (rows) + *rows = _rl_screenheight; + if (cols) + *cols = _rl_screenwidth; +} + +void +rl_resize_terminal () +{ + if (readline_echoing_p) + { + _rl_get_screen_size (fileno (rl_instream), 1); + if (CUSTOM_REDISPLAY_FUNC ()) + rl_forced_update_display (); + else + _rl_redisplay_after_sigwinch (); + } +} + +struct _tc_string { + const char *tc_var; + char **tc_value; +}; + +/* This should be kept sorted, just in case we decide to change the + search algorithm to something smarter. */ +static struct _tc_string tc_strings[] = +{ + { "@7", &_rl_term_at7 }, + { "DC", &_rl_term_DC }, + { "IC", &_rl_term_IC }, + { "ce", &_rl_term_clreol }, + { "cl", &_rl_term_clrpag }, + { "cr", &_rl_term_cr }, + { "dc", &_rl_term_dc }, + { "ei", &_rl_term_ei }, + { "ic", &_rl_term_ic }, + { "im", &_rl_term_im }, + { "kH", &_rl_term_kH }, /* home down ?? */ + { "kI", &_rl_term_kI }, /* insert */ + { "kd", &_rl_term_kd }, + { "ke", &_rl_term_ke }, /* end keypad mode */ + { "kh", &_rl_term_kh }, /* home */ + { "kl", &_rl_term_kl }, + { "kr", &_rl_term_kr }, + { "ks", &_rl_term_ks }, /* start keypad mode */ + { "ku", &_rl_term_ku }, + { "le", &_rl_term_backspace }, + { "mm", &_rl_term_mm }, + { "mo", &_rl_term_mo }, +#if defined (HACK_TERMCAP_MOTION) + { "nd", &_rl_term_forward_char }, +#endif + { "pc", &_rl_term_pc }, + { "up", &_rl_term_up }, + { "vb", &_rl_visible_bell }, + { "vs", &_rl_term_vs }, + { "ve", &_rl_term_ve }, +}; + +#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) + +/* Read the desired terminal capability strings into BP. The capabilities + are described in the TC_STRINGS table. */ +static void +get_term_capabilities (bp) + char **bp; +{ +#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ + 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; +} + +int +_rl_init_terminal_io (terminal_name) + const char *terminal_name; +{ + const char *term; + char *buffer; + int tty, tgetent_ret; + + 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"; + + /* I've separated this out for later work on not calling tgetent at all + if the calling application has supplied a custom redisplay function, + (and possibly if the application has supplied a custom input function). */ + if (CUSTOM_REDISPLAY_FUNC()) + { + tgetent_ret = -1; + } + else + { + if (term_string_buffer == 0) + term_string_buffer = (char *)xmalloc(2032); + + if (term_buffer == 0) + term_buffer = (char *)xmalloc(4080); + + buffer = term_string_buffer; + + tgetent_ret = tgetent (term_buffer, term); + } + + if (tgetent_ret <= 0) + { + FREE (term_string_buffer); + FREE (term_buffer); + buffer = term_buffer = term_string_buffer = (char *)NULL; + + _rl_term_autowrap = 0; /* used by _rl_get_screen_size */ + +#if defined (__EMX__) + _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight); + _rl_screenwidth--; +#else /* !__EMX__ */ + _rl_get_screen_size (tty, 0); +#endif /* !__EMX__ */ + + /* Defaults. */ + if (_rl_screenwidth <= 0 || _rl_screenheight <= 0) + { + _rl_screenwidth = 79; + _rl_screenheight = 24; + } + + /* Everything below here is used by the redisplay code (tputs). */ + _rl_screenchars = _rl_screenwidth * _rl_screenheight; + _rl_term_cr = "\r"; + _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_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; +#if defined (HACK_TERMCAP_MOTION) + term_forward_char = (char *)NULL; +#endif + _rl_terminal_can_insert = term_has_meta = 0; + + /* Reasonable defaults for tgoto(). Readline currently only uses + tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we + change that later... */ + PC = '\0'; + BC = _rl_term_backspace = "\b"; + UP = _rl_term_up; + + return 0; + } + + get_term_capabilities (&buffer); + + /* Set up the variables that the termcap library expects the application + to provide. */ + PC = _rl_term_pc ? *_rl_term_pc : 0; + BC = _rl_term_backspace; + UP = _rl_term_up; + + if (!_rl_term_cr) + _rl_term_cr = "\r"; + + _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); + + _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', + `im', `ic' or `ip' is provided." But we can't do anything if + only `ip' is provided, so... */ + _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic); + + /* Check to see if this terminal has a meta key and clear the capability + variables if there is none. */ + term_has_meta = (tgetflag ("km") || tgetflag ("MT")); + if (!term_has_meta) + _rl_term_mm = _rl_term_mo = (char *)NULL; + + /* Attempt to find and bind the arrow keys. Do not override already + bound keys in an overzealous attempt, however. */ + + bind_termcap_arrow_keys (emacs_standard_keymap); + +#if defined (VI_MODE) + bind_termcap_arrow_keys (vi_movement_keymap); + bind_termcap_arrow_keys (vi_insertion_keymap); +#endif /* VI_MODE */ + + return 0; +} + +/* Bind the arrow key sequences from the termcap description in MAP. */ +static void +bind_termcap_arrow_keys (map) + Keymap map; +{ + Keymap xkeymap; + + 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_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */ + _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ + + _rl_keymap = xkeymap; +} + +char * +rl_get_termcap (cap) + const char *cap; +{ + register int i; + + if (tcap_initialized == 0) + return ((char *)NULL); + for (i = 0; i < NUM_TC_STRINGS; i++) + { + if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0) + return *(tc_strings[i].tc_value); + } + return ((char *)NULL); +} + +/* Re-initialize the terminal considering that the TERM/TERMCAP variable + has changed. */ +int +rl_reset_terminal (terminal_name) + const char *terminal_name; +{ + _rl_init_terminal_io (terminal_name); + return 0; +} + +/* A function for the use of tputs () */ +#ifdef _MINIX +void +_rl_output_character_function (c) + int c; +{ + putc (c, _rl_out_stream); +} +#else /* !_MINIX */ +int +_rl_output_character_function (c) + int c; +{ + return putc (c, _rl_out_stream); +} +#endif /* !_MINIX */ + +/* Write COUNT characters from STRING to the output stream. */ +void +_rl_output_some_chars (string, count) + const char *string; + int count; +{ + fwrite (string, 1, count, _rl_out_stream); +} + +/* Move the cursor back. */ +int +_rl_backspace (count) + int count; +{ + register int i; + + if (_rl_term_backspace) + for (i = 0; i < count; i++) + tputs (_rl_term_backspace, 1, _rl_output_character_function); + else + for (i = 0; i < count; i++) + putc ('\b', _rl_out_stream); + return 0; +} + +/* Move to the start of the next line. */ +int +rl_crlf () +{ +#if defined (NEW_TTY_DRIVER) + if (_rl_term_cr) + tputs (_rl_term_cr, 1, _rl_output_character_function); +#endif /* NEW_TTY_DRIVER */ + putc ('\n', _rl_out_stream); + return 0; +} + +/* Ring the terminal bell. */ +int +rl_ding () +{ + if (readline_echoing_p) + { + switch (_rl_bell_preference) + { + case NO_BELL: + default: + break; + case VISIBLE_BELL: + if (_rl_visible_bell) + { + tputs (_rl_visible_bell, 1, _rl_output_character_function); + break; + } + /* FALLTHROUGH */ + case AUDIBLE_BELL: + fprintf (stderr, "\007"); + fflush (stderr); + break; + } + return (0); + } + return (-1); +} + +/* **************************************************************** */ +/* */ +/* Controlling the Meta Key and Keypad */ +/* */ +/* **************************************************************** */ + +void +_rl_enable_meta_key () +{ +#if !defined (__DJGPP__) + if (term_has_meta && _rl_term_mm) + tputs (_rl_term_mm, 1, _rl_output_character_function); +#endif +} + +void +_rl_control_keypad (on) + int on; +{ +#if !defined (__DJGPP__) + if (on && _rl_term_ks) + tputs (_rl_term_ks, 1, _rl_output_character_function); + else if (!on && _rl_term_ke) + tputs (_rl_term_ke, 1, _rl_output_character_function); +#endif +} + +/* **************************************************************** */ +/* */ +/* Controlling the Cursor */ +/* */ +/* **************************************************************** */ + +/* Set the cursor appropriately depending on IM, which is one of the + insert modes (insert or overwrite). Insert mode gets the normal + cursor. Overwrite mode gets a very visible cursor. Only does + anything if we have both capabilities. */ +void +_rl_set_cursor (im, force) + int im, force; +{ + if (_rl_term_ve && _rl_term_vs) + { + if (force || im != rl_insert_mode) + { + if (im == RL_IM_OVERWRITE) + tputs (_rl_term_vs, 1, _rl_output_character_function); + else + tputs (_rl_term_ve, 1, _rl_output_character_function); + } + } +} diff --git a/readline-4.3/text.c b/readline-4.3/text.c new file mode 100644 index 0000000..2a7b724 --- /dev/null +++ b/readline-4.3/text.c @@ -0,0 +1,1540 @@ +/* text.c -- text handling commands for readline. */ + +/* Copyright (C) 1987-2002 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#if defined (__EMX__) +# define INCL_DOSPROCESS +# include +#endif /* __EMX__ */ + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "rlshell.h" +#include "xmalloc.h" + +/* Forward declarations. */ +static int rl_change_case PARAMS((int, int)); +static int _rl_char_search PARAMS((int, int, int)); + +/* **************************************************************** */ +/* */ +/* Insert and Delete */ +/* */ +/* **************************************************************** */ + +/* Insert a string of text into the line at point. This is the only + way that you should do insertion. _rl_insert_char () calls this + function. Returns the number of characters inserted. */ +int +rl_insert_text (string) + const char *string; +{ + register int i, l; + + l = (string && *string) ? strlen (string) : 0; + if (l == 0) + return 0; + + if (rl_end + l >= rl_line_buffer_len) + rl_extend_line_buffer (rl_end + l); + + for (i = rl_end; i >= rl_point; i--) + rl_line_buffer[i + l] = rl_line_buffer[i]; + strncpy (rl_line_buffer + rl_point, string, l); + + /* Remember how to undo this if we aren't undoing something. */ + if (_rl_doing_an_undo == 0) + { + /* If possible and desirable, concatenate the undos. */ + if ((l == 1) && + rl_undo_list && + (rl_undo_list->what == UNDO_INSERT) && + (rl_undo_list->end == rl_point) && + (rl_undo_list->end - rl_undo_list->start < 20)) + rl_undo_list->end++; + else + rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL); + } + rl_point += l; + rl_end += l; + rl_line_buffer[rl_end] = '\0'; + return l; +} + +/* Delete the string between FROM and TO. FROM is inclusive, TO is not. + Returns the number of characters deleted. */ +int +rl_delete_text (from, to) + int from, to; +{ + register char *text; + register int diff, i; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + /* fix boundaries */ + if (to > rl_end) + { + to = rl_end; + if (from > to) + from = to; + } + if (from < 0) + from = 0; + + text = rl_copy_text (from, to); + + /* Some versions of strncpy() can't handle overlapping arguments. */ + diff = to - from; + for (i = from; i < rl_end - diff; i++) + rl_line_buffer[i] = rl_line_buffer[i + diff]; + + /* Remember how to undo this delete. */ + if (_rl_doing_an_undo == 0) + rl_add_undo (UNDO_DELETE, from, to, text); + else + free (text); + + rl_end -= diff; + rl_line_buffer[rl_end] = '\0'; + return (diff); +} + +/* Fix up point so that it is within the line boundaries after killing + text. If FIX_MARK_TOO is non-zero, the mark is forced within line + boundaries also. */ + +#define _RL_FIX_POINT(x) \ + do { \ + if (x > rl_end) \ + x = rl_end; \ + else if (x < 0) \ + x = 0; \ + } while (0) + +void +_rl_fix_point (fix_mark_too) + int fix_mark_too; +{ + _RL_FIX_POINT (rl_point); + if (fix_mark_too) + _RL_FIX_POINT (rl_mark); +} +#undef _RL_FIX_POINT + +int +_rl_replace_text (text, start, end) + const char *text; + int start, end; +{ + int n; + + rl_begin_undo_group (); + rl_delete_text (start, end + 1); + rl_point = start; + n = rl_insert_text (text); + rl_end_undo_group (); + + return n; +} + +/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is + non-zero, we free the current undo list. */ +void +rl_replace_line (text, clear_undo) + const char *text; + int clear_undo; +{ + int len; + + len = strlen (text); + if (len >= rl_line_buffer_len) + rl_extend_line_buffer (len); + strcpy (rl_line_buffer, text); + rl_end = len; + + if (clear_undo) + rl_free_undo_list (); + + _rl_fix_point (1); +} + +/* **************************************************************** */ +/* */ +/* Readline character functions */ +/* */ +/* **************************************************************** */ + +/* This is not a gap editor, just a stupid line input routine. No hair + is involved in writing any of the functions, and none should be. */ + +/* Note that: + + rl_end is the place in the string that we would place '\0'; + i.e., it is always safe to place '\0' there. + + rl_point is the place in the string where the cursor is. Sometimes + this is the same as rl_end. + + Any command that is called interactively receives two arguments. + The first is a count: the numeric arg pased to this command. + The second is the key which invoked this command. +*/ + +/* **************************************************************** */ +/* */ +/* Movement Commands */ +/* */ +/* **************************************************************** */ + +/* Note that if you `optimize' the display for these functions, you cannot + use said functions in other functions which do not do optimizing display. + I.e., you will have to update the data base for rl_redisplay, and you + might as well let rl_redisplay do that job. */ + +/* Move forward COUNT bytes. */ +int +rl_forward_byte (count, key) + int count, key; +{ + if (count < 0) + return (rl_backward_byte (-count, key)); + + if (count > 0) + { + int end = rl_point + count; +#if defined (VI_MODE) + int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end; +#else + int lend = rl_end; +#endif + + if (end > lend) + { + rl_point = lend; + rl_ding (); + } + else + rl_point = end; + } + + if (rl_end < 0) + rl_end = 0; + + return 0; +} + +#if defined (HANDLE_MULTIBYTE) +/* Move forward COUNT characters. */ +int +rl_forward_char (count, key) + int count, key; +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_forward_byte (count, key)); + + if (count < 0) + return (rl_backward_char (-count, key)); + + if (count > 0) + { + point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + +#if defined (VI_MODE) + if (rl_end <= point && rl_editing_mode == vi_mode) + point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO); +#endif + + if (rl_point == point) + rl_ding (); + + rl_point = point; + + if (rl_end < 0) + rl_end = 0; + } + + return 0; +} +#else /* !HANDLE_MULTIBYTE */ +int +rl_forward_char (count, key) + int count, key; +{ + return (rl_forward_byte (count, key)); +} +#endif /* !HANDLE_MULTIBYTE */ + +/* Backwards compatibility. */ +int +rl_forward (count, key) + int count, key; +{ + return (rl_forward_char (count, key)); +} + +/* Move backward COUNT bytes. */ +int +rl_backward_byte (count, key) + int count, key; +{ + if (count < 0) + return (rl_forward_byte (-count, key)); + + if (count > 0) + { + if (rl_point < count) + { + rl_point = 0; + rl_ding (); + } + else + rl_point -= count; + } + + if (rl_point < 0) + rl_point = 0; + + return 0; +} + +#if defined (HANDLE_MULTIBYTE) +/* Move backward COUNT characters. */ +int +rl_backward_char (count, key) + int count, key; +{ + int point; + + if (MB_CUR_MAX == 1 || rl_byte_oriented) + return (rl_backward_byte (count, key)); + + if (count < 0) + return (rl_forward_char (-count, key)); + + if (count > 0) + { + point = rl_point; + + while (count > 0 && point > 0) + { + point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); + count--; + } + if (count > 0) + { + rl_point = 0; + rl_ding (); + } + else + rl_point = point; + } + + return 0; +} +#else +int +rl_backward_char (count, key) + int count, key; +{ + return (rl_backward_byte (count, key)); +} +#endif + +/* Backwards compatibility. */ +int +rl_backward (count, key) + int count, key; +{ + return (rl_backward_char (count, key)); +} + +/* Move to the beginning of the line. */ +int +rl_beg_of_line (count, key) + int count, key; +{ + rl_point = 0; + return 0; +} + +/* Move to the end of the line. */ +int +rl_end_of_line (count, key) + int count, key; +{ + rl_point = rl_end; + return 0; +} + +/* XXX - these might need changes for multibyte characters */ +/* Move forward a word. We do what Emacs does. */ +int +rl_forward_word (count, key) + int count, key; +{ + int c; + + if (count < 0) + return (rl_backward_word (-count, key)); + + while (count) + { + if (rl_point == rl_end) + return 0; + + /* 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) + { + while (++rl_point < rl_end) + { + c = rl_line_buffer[rl_point]; + if (rl_alphabetic (c)) + break; + } + } + + if (rl_point == rl_end) + return 0; + + while (++rl_point < rl_end) + { + c = rl_line_buffer[rl_point]; + if (rl_alphabetic (c) == 0) + break; + } + --count; + } + + return 0; +} + +/* Move backward a word. We do what Emacs does. */ +int +rl_backward_word (count, key) + int count, key; +{ + int c; + + if (count < 0) + return (rl_forward_word (-count, key)); + + while (count) + { + if (!rl_point) + 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) + { + while (--rl_point) + { + c = rl_line_buffer[rl_point - 1]; + if (rl_alphabetic (c)) + break; + } + } + + while (rl_point) + { + c = rl_line_buffer[rl_point - 1]; + if (rl_alphabetic (c) == 0) + break; + else + --rl_point; + } + + --count; + } + + return 0; +} + +/* Clear the current line. Numeric argument to C-l does this. */ +int +rl_refresh_line (ignore1, ignore2) + int ignore1, ignore2; +{ + int curr_line; + + curr_line = _rl_current_display_line (); + + _rl_move_vert (curr_line); + _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */ + + _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */ + + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +/* C-l typed to a line without quoting clears the screen, and then reprints + the prompt and the current input line. Given a numeric arg, redraw only + the current line. */ +int +rl_clear_screen (count, key) + int count, key; +{ + if (rl_explicit_arg) + { + rl_refresh_line (count, key); + return 0; + } + + _rl_clear_screen (); /* calls termcap function to clear screen */ + rl_forced_update_display (); + rl_display_fixed = 1; + + return 0; +} + +int +rl_arrow_keys (count, c) + int count, c; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + switch (_rl_to_upper (ch)) + { + case 'A': + rl_get_previous_history (count, ch); + break; + + case 'B': + rl_get_next_history (count, ch); + break; + + case 'C': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_forward_char (count, ch); + else + rl_forward_byte (count, ch); + break; + + case 'D': + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_backward_char (count, ch); + else + rl_backward_byte (count, ch); + break; + + default: + rl_ding (); + } + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Text commands */ +/* */ +/* **************************************************************** */ + +#ifdef HANDLE_MULTIBYTE +static char pending_bytes[MB_LEN_MAX]; +static int pending_bytes_length = 0; +static mbstate_t ps = {0}; +#endif + +/* Insert the character C at the current location, moving point forward. + If C introduces a multibyte sequence, we read the whole sequence and + then insert the multibyte char into the line buffer. */ +int +_rl_insert_char (count, c) + int count, c; +{ + register int i; + char *string; +#ifdef HANDLE_MULTIBYTE + int string_size; + char incoming[MB_LEN_MAX + 1]; + int incoming_length = 0; + mbstate_t ps_back; + static int stored_count = 0; +#endif + + if (count <= 0) + return 0; + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + incoming[0] = c; + incoming[1] = '\0'; + incoming_length = 1; + } + else + { + wchar_t wc; + size_t ret; + + if (stored_count <= 0) + stored_count = count; + else + count = stored_count; + + ps_back = ps; + pending_bytes[pending_bytes_length++] = c; + ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps); + + if (ret == (size_t)-2) + { + /* Bytes too short to compose character, try to wait for next byte. + Restore the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + ps = ps_back; + return 1; + } + else if (ret == (size_t)-1) + { + /* Invalid byte sequence for the current locale. Treat first byte + as a single character. */ + incoming[0] = pending_bytes[0]; + incoming[1] = '\0'; + incoming_length = 1; + pending_bytes_length--; + memmove (pending_bytes, pending_bytes + 1, pending_bytes_length); + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (ret == (size_t)0) + { + incoming[0] = '\0'; + incoming_length = 0; + pending_bytes_length--; + /* Clear the state of the byte sequence, because in this case the + effect of mbstate is undefined. */ + memset (&ps, 0, sizeof (mbstate_t)); + } + else + { + /* We successfully read a single multibyte character. */ + memcpy (incoming, pending_bytes, pending_bytes_length); + incoming[pending_bytes_length] = '\0'; + incoming_length = pending_bytes_length; + pending_bytes_length = 0; + } + } +#endif /* HANDLE_MULTIBYTE */ + + /* If we can optimize, then do it. But don't let people crash + readline because of extra large arguments. */ + if (count > 1 && count <= 1024) + { +#if defined (HANDLE_MULTIBYTE) + string_size = count * incoming_length; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + string = (char *)xmalloc (1 + count); + + for (i = 0; i < count; i++) + string[i] = c; +#endif /* !HANDLE_MULTIBYTE */ + + string[i] = '\0'; + rl_insert_text (string); + free (string); + + return 0; + } + + if (count > 1024) + { + int decreaser; +#if defined (HANDLE_MULTIBYTE) + string_size = incoming_length * 1024; + string = (char *)xmalloc (1 + string_size); + + i = 0; + while (i < string_size) + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } + + while (count) + { + decreaser = (count > 1024) ? 1024 : count; + string[decreaser*incoming_length] = '\0'; + rl_insert_text (string); + count -= decreaser; + } + + free (string); + incoming_length = 0; + stored_count = 0; +#else /* !HANDLE_MULTIBYTE */ + char str[1024+1]; + + for (i = 0; i < 1024; i++) + str[i] = c; + + while (count) + { + decreaser = (count > 1024 ? 1024 : count); + str[decreaser] = '\0'; + rl_insert_text (str); + count -= decreaser; + } +#endif /* !HANDLE_MULTIBYTE */ + + 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 + them all. */ + if (_rl_any_typein ()) + _rl_insert_typein (c); + else + { + /* Inserting a single character. */ + char str[2]; + + str[1] = '\0'; + str[0] = c; + rl_insert_text (str); + } +#if defined (HANDLE_MULTIBYTE) + } + else + { + rl_insert_text (incoming); + stored_count = 0; + } +#endif + + return 0; +} + +/* Overwrite the character at point (or next COUNT characters) with C. + If C introduces a multibyte character sequence, read the entire sequence + before starting the overwrite loop. */ +int +_rl_overwrite_char (count, c) + int count, c; +{ + int i; +#if defined (HANDLE_MULTIBYTE) + char mbkey[MB_LEN_MAX]; + int k; + + /* Read an entire multibyte character sequence to insert COUNT times. */ + if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0) + k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); +#endif + + 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); + else +#endif + _rl_insert_char (1, c); + + rl_end_undo_group (); + } + + return 0; +} + +int +rl_insert (count, c) + int count, c; +{ + return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c) + : _rl_overwrite_char (count, c)); +} + +/* Insert the next typed character verbatim. */ +int +rl_quoted_insert (count, key) + int count, key; +{ + 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 (); +#endif + + return (_rl_insert_char (count, c)); +} + +/* Insert a tab character. */ +int +rl_tab_insert (count, key) + int count, key; +{ + return (_rl_insert_char (count, '\t')); +} + +/* What to do when a NEWLINE is pressed. We accept the whole line. + KEY is the key that invoked this command. I guess it could have + meaning in the future. */ +int +rl_newline (count, key) + int count, key; +{ + rl_done = 1; + + if (_rl_history_preserve_point) + _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; + + RL_SETSTATE(RL_STATE_DONE); + +#if defined (VI_MODE) + if (rl_editing_mode == vi_mode) + { + _rl_vi_done_inserting (); + _rl_vi_reset_last (); + } +#endif /* VI_MODE */ + + /* If we've been asked to erase empty lines, suppress the final update, + since _rl_update_final calls rl_crlf(). */ + if (rl_erase_empty_line && rl_point == 0 && rl_end == 0) + return 0; + + if (readline_echoing_p) + _rl_update_final (); + return 0; +} + +/* What to do for some uppercase characters, like meta characters, + and some characters appearing in emacs_ctlx_keymap. This function + is just a stub, you bind keys to it and the code in _rl_dispatch () + is special cased. */ +int +rl_do_lowercase_version (ignore1, ignore2) + int ignore1, ignore2; +{ + return 0; +} + +/* This is different from what vi does, so the code's not shared. Emacs + rubout in overwrite mode has one oddity: it replaces a control + character that's displayed as two characters (^X) with two spaces. */ +int +_rl_overwrite_rubout (count, key) + int count, key; +{ + int opoint; + int i, l; + + if (rl_point == 0) + { + rl_ding (); + return 1; + } + + opoint = rl_point; + + /* L == number of spaces to insert */ + for (i = l = 0; i < count; i++) + { + rl_backward_char (1, key); + l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */ + } + + rl_begin_undo_group (); + + if (count > 1 || rl_explicit_arg) + rl_kill_text (opoint, rl_point); + else + 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; + + rl_end_undo_group (); + + return 0; +} + +/* Rubout the character behind point. */ +int +rl_rubout (count, key) + int count, key; +{ + if (count < 0) + return (rl_delete (-count, key)); + + if (!rl_point) + { + rl_ding (); + return -1; + } + + if (rl_insert_mode == RL_IM_OVERWRITE) + return (_rl_overwrite_rubout (count, key)); + + return (_rl_rubout_char (count, key)); +} + +int +_rl_rubout_char (count, key) + int count, key; +{ + int orig_point; + unsigned char c; + + /* Duplicated code because this is called from other parts of the library. */ + if (count < 0) + return (rl_delete (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return -1; + } + + 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_kill_text (orig_point, rl_point); + } + else + { +#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 + if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos) + { + int l; + l = rl_character_len (c, rl_point); + _rl_erase_at_end_of_line (l); + } + } + + return 0; +} + +/* Delete the character under the cursor. Given a numeric argument, + kill that many characters instead. */ +int +rl_delete (count, key) + int count, key; +{ + int r; + + if (count < 0) + return (_rl_rubout_char (-count, key)); + + if (rl_point == rl_end) + { + rl_ding (); + return -1; + } + + 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_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)); + } +} + +/* Delete the character under the cursor, unless the insertion + point is at the end of the line, in which case the character + behind the cursor is deleted. COUNT is obeyed and may be used + to delete forward or backward that many characters. */ +int +rl_rubout_or_delete (count, key) + int count, key; +{ + if (rl_end != 0 && rl_point == rl_end) + return (_rl_rubout_char (count, key)); + else + return (rl_delete (count, key)); +} + +/* Delete all spaces and tabs around point. */ +int +rl_delete_horizontal_space (count, ignore) + int count, ignore; +{ + int start = rl_point; + + while (rl_point && whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + start = rl_point; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + if (start != rl_point) + { + rl_delete_text (start, rl_point); + rl_point = start; + } + return 0; +} + +/* Like the tcsh editing function delete-char-or-list. The eof character + is caught before this is invoked, so this really does the same thing as + delete-char-or-list-or-eof, as long as it's bound to the eof character. */ +int +rl_delete_or_show_completions (count, key) + int count, key; +{ + if (rl_end != 0 && rl_point == rl_end) + return (rl_possible_completions (count, key)); + else + return (rl_delete (count, key)); +} + +#ifndef RL_COMMENT_BEGIN_DEFAULT +#define RL_COMMENT_BEGIN_DEFAULT "#" +#endif + +/* Turn the current line into a comment in shell history. + A K*rn shell style function. */ +int +rl_insert_comment (count, key) + int count, key; +{ + char *rl_comment_text; + int rl_comment_len; + + rl_beg_of_line (1, key); + rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT; + + if (rl_explicit_arg == 0) + rl_insert_text (rl_comment_text); + else + { + rl_comment_len = strlen (rl_comment_text); + if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len)) + rl_delete_text (rl_point, rl_point + rl_comment_len); + else + rl_insert_text (rl_comment_text); + } + + (*rl_redisplay_function) (); + rl_newline (1, '\n'); + + return (0); +} + +/* **************************************************************** */ +/* */ +/* Changing Case */ +/* */ +/* **************************************************************** */ + +/* The three kinds of things that we know how to do. */ +#define UpCase 1 +#define DownCase 2 +#define CapCase 3 + +/* Uppercase the word at point. */ +int +rl_upcase_word (count, key) + int count, key; +{ + return (rl_change_case (count, UpCase)); +} + +/* Lowercase the word at point. */ +int +rl_downcase_word (count, key) + int count, key; +{ + return (rl_change_case (count, DownCase)); +} + +/* Upcase the first letter, downcase the rest. */ +int +rl_capitalize_word (count, key) + int count, key; +{ + return (rl_change_case (count, CapCase)); +} + +/* The meaty function. + Change the case of COUNT words, performing OP on them. + OP is one of UpCase, DownCase, or CapCase. + If a negative argument is given, leave point where it started, + otherwise, leave it where it moves to. */ +static int +rl_change_case (count, op) + int count, op; +{ + register int start, end; + int inword, c; + + start = rl_point; + rl_forward_word (count, 0); + end = rl_point; + + if (count < 0) + SWAP (start, end); + + /* We are going to modify some text, so let's prepare to undo it. */ + rl_modifying (start, end); + + for (inword = 0; start < end; start++) + { + c = rl_line_buffer[start]; + switch (op) + { + case UpCase: + rl_line_buffer[start] = _rl_to_upper (c); + break; + + 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; + + default: + rl_ding (); + return -1; + } + } + rl_point = end; + return 0; +} + +/* **************************************************************** */ +/* */ +/* Transposition */ +/* */ +/* **************************************************************** */ + +/* Transpose the words at point. If point is at the end of the line, + transpose the two words before point. */ +int +rl_transpose_words (count, key) + int count, key; +{ + char *word1, *word2; + int w1_beg, w1_end, w2_beg, w2_end; + int orig_point = rl_point; + + if (!count) + return 0; + + /* Find the two words. */ + rl_forward_word (count, key); + w2_end = rl_point; + rl_backward_word (1, key); + w2_beg = rl_point; + rl_backward_word (count, key); + w1_beg = rl_point; + rl_forward_word (1, key); + w1_end = rl_point; + + /* Do some check to make sure that there really are two words. */ + if ((w1_beg == w2_beg) || (w2_beg < w1_end)) + { + rl_ding (); + rl_point = orig_point; + return -1; + } + + /* Get the text of the words. */ + word1 = rl_copy_text (w1_beg, w1_end); + word2 = rl_copy_text (w2_beg, w2_end); + + /* We are about to do many insertions and deletions. Remember them + as one operation. */ + rl_begin_undo_group (); + + /* Do the stuff at word2 first, so that we don't have to worry + about word1 moving. */ + rl_point = w2_beg; + rl_delete_text (w2_beg, w2_end); + rl_insert_text (word1); + + rl_point = w1_beg; + rl_delete_text (w1_beg, w1_end); + rl_insert_text (word2); + + /* This is exactly correct since the text before this point has not + changed in length. */ + rl_point = w2_end; + + /* I think that does it. */ + rl_end_undo_group (); + free (word1); + free (word2); + + return 0; +} + +/* Transpose the characters at point. If point is at the end of the line, + then transpose the characters before point. */ +int +rl_transpose_chars (count, key) + int count, key; +{ +#if defined (HANDLE_MULTIBYTE) + char *dummy; + int i, prev_point; +#else + char dummy[2]; +#endif + int char_length; + + if (count == 0) + return 0; + + if (!rl_point || rl_end < 2) + { + rl_ding (); + return -1; + } + + rl_begin_undo_group (); + + 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; + 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--; + +#if defined (HANDLE_MULTIBYTE) + char_length = prev_point - rl_point; + dummy = (char *)xmalloc (char_length + 1); + for (i = 0; i < char_length; i++) + dummy[i] = rl_line_buffer[rl_point + i]; + dummy[i] = '\0'; +#else + dummy[0] = rl_line_buffer[rl_point]; + dummy[char_length = 1] = '\0'; +#endif + + rl_delete_text (rl_point, rl_point + char_length); + + rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + + _rl_fix_point (0); + rl_insert_text (dummy); + rl_end_undo_group (); + +#if defined (HANDLE_MULTIBYTE) + free (dummy); +#endif + + return 0; +} + +/* **************************************************************** */ +/* */ +/* Character Searching */ +/* */ +/* **************************************************************** */ + +int +#if defined (HANDLE_MULTIBYTE) +_rl_char_search_internal (count, dir, smbchar, len) + int count, dir; + char *smbchar; + int len; +#else +_rl_char_search_internal (count, dir, schar) + int count, dir, schar; +#endif +{ + int pos, inc; +#if defined (HANDLE_MULTIBYTE) + int prepos; +#endif + + pos = rl_point; + inc = (dir < 0) ? -1 : 1; + while (count) + { + if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end)) + { + rl_ding (); + return -1; + } + +#if defined (HANDLE_MULTIBYTE) + pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); +#else + pos += inc; +#endif + do + { +#if defined (HANDLE_MULTIBYTE) + if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len)) +#else + if (rl_line_buffer[pos] == schar) +#endif + { + count--; + if (dir < 0) + rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY) + : pos; + else + rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY) + : pos; + break; + } +#if defined (HANDLE_MULTIBYTE) + prepos = pos; +#endif + } +#if defined (HANDLE_MULTIBYTE) + while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos + : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos); +#else + while ((dir < 0) ? pos-- : ++pos < rl_end); +#endif + } + return (0); +} + +/* Search COUNT times for a character read from the current input stream. + FDIR is the direction to search if COUNT is non-negative; otherwise + the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE + that there are two separate versions of this function. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_char_search (count, fdir, bdir) + int count, fdir, bdir; +{ + char mbchar[MB_LEN_MAX]; + int mb_len; + + mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX); + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, mbchar, mb_len)); + else + return (_rl_char_search_internal (count, fdir, mbchar, mb_len)); +} +#else /* !HANDLE_MULTIBYTE */ +static int +_rl_char_search (count, fdir, bdir) + int count, fdir, bdir; +{ + int c; + + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (count < 0) + return (_rl_char_search_internal (-count, bdir, c)); + else + return (_rl_char_search_internal (count, fdir, c)); +} +#endif /* !HANDLE_MULTIBYTE */ + +int +rl_char_search (count, key) + int count, key; +{ + return (_rl_char_search (count, FFIND, BFIND)); +} + +int +rl_backward_char_search (count, key) + int count, key; +{ + return (_rl_char_search (count, BFIND, FFIND)); +} + +/* **************************************************************** */ +/* */ +/* The Mark and the Region. */ +/* */ +/* **************************************************************** */ + +/* Set the mark at POSITION. */ +int +_rl_set_mark_at_pos (position) + int position; +{ + if (position > rl_end) + return -1; + + rl_mark = position; + return 0; +} + +/* A bindable command to set the mark. */ +int +rl_set_mark (count, key) + int count, key; +{ + return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); +} + +/* Exchange the position of mark and point. */ +int +rl_exchange_point_and_mark (count, key) + int count, key; +{ + if (rl_mark > rl_end) + rl_mark = -1; + + if (rl_mark == -1) + { + rl_ding (); + return -1; + } + else + SWAP (rl_point, rl_mark); + + return 0; +} diff --git a/readline-4.3/tilde.c b/readline-4.3/tilde.c new file mode 100644 index 0000000..154f7f8 --- /dev/null +++ b/readline-4.3/tilde.c @@ -0,0 +1,458 @@ +/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ + +/* Copyright (C) 1988,1989 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +#include "tilde.h" + +#if defined (TEST) || defined (STATIC_MALLOC) +static void *xmalloc (), *xrealloc (); +#else +# include "xmalloc.h" +#endif /* TEST || STATIC_MALLOC */ + +#if !defined (HAVE_GETPW_DECLS) +extern struct passwd *getpwuid PARAMS((uid_t)); +extern struct passwd *getpwnam PARAMS((const char *)); +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (savestring) +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif /* !savestring */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* If being compiled as part of bash, these will be satisfied from + variables.o. If being compiled as part of readline, they will + be satisfied from shell.o. */ +extern char *sh_get_home_dir PARAMS((void)); +extern char *sh_get_env_value PARAMS((const char *)); + +/* The default value of tilde_additional_prefixes. This is set to + whitespace preceding a tilde so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_prefixes[] = + { " ~", "\t~", (const char *)NULL }; + +/* The default value of tilde_additional_suffixes. This is set to + whitespace or newline so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_suffixes[] = + { " ", "\n", (const char *)NULL }; + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +char **tilde_additional_prefixes = (char **)default_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +char **tilde_additional_suffixes = (char **)default_suffixes; + +static int tilde_find_prefix PARAMS((const char *, int *)); +static int tilde_find_suffix PARAMS((const char *)); +static char *isolate_tilde_prefix PARAMS((const char *, int *)); +static char *glue_prefix_and_suffix PARAMS((char *, const char *, int)); + +/* Find the start of a tilde expansion in STRING, and return the index of + the tilde which starts the expansion. Place the length of the text + which identified this tilde starter in LEN, excluding the tilde itself. */ +static int +tilde_find_prefix (string, len) + const char *string; + int *len; +{ + register int i, j, string_len; + register char **prefixes; + + prefixes = tilde_additional_prefixes; + + string_len = strlen (string); + *len = 0; + + if (*string == '\0' || *string == '~') + return (0); + + if (prefixes) + { + for (i = 0; i < string_len; i++) + { + for (j = 0; prefixes[j]; j++) + { + if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) + { + *len = strlen (prefixes[j]) - 1; + return (i + *len); + } + } + } + } + return (string_len); +} + +/* Find the end of a tilde expansion in STRING, and return the index of + the character which ends the tilde definition. */ +static int +tilde_find_suffix (string) + const char *string; +{ + register int i, j, string_len; + register char **suffixes; + + suffixes = tilde_additional_suffixes; + string_len = strlen (string); + + for (i = 0; i < string_len; i++) + { +#if defined (__MSDOS__) + if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) +#else + if (string[i] == '/' /* || !string[i] */) +#endif + break; + + for (j = 0; suffixes && suffixes[j]; j++) + { + if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) + return (i); + } + } + return (i); +} + +/* Return a new string which is the result of tilde expanding STRING. */ +char * +tilde_expand (string) + const char *string; +{ + char *result; + int result_size, result_index; + + result_index = result_size = 0; + if (result = strchr (string, '~')) + result = (char *)xmalloc (result_size = (strlen (string) + 16)); + else + result = (char *)xmalloc (result_size = (strlen (string) + 1)); + + /* Scan through STRING expanding tildes as we come to them. */ + while (1) + { + register int start, end; + char *tilde_word, *expansion; + int len; + + /* Make START point to the tilde which starts the expansion. */ + start = tilde_find_prefix (string, &len); + + /* Copy the skipped text into the result. */ + if ((result_index + start + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + + strncpy (result + result_index, string, start); + result_index += start; + + /* Advance STRING to the starting tilde. */ + string += start; + + /* Make END be the index of one after the last character of the + username. */ + end = tilde_find_suffix (string); + + /* If both START and END are zero, we are all done. */ + if (!start && !end) + break; + + /* Expand the entire tilde word, and copy it into RESULT. */ + tilde_word = (char *)xmalloc (1 + end); + strncpy (tilde_word, string, end); + tilde_word[end] = '\0'; + string += end; + + expansion = tilde_expand_word (tilde_word); + free (tilde_word); + + len = strlen (expansion); +#ifdef __CYGWIN__ + /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when + $HOME for `user' is /. On cygwin, // denotes a network drive. */ + if (len > 1 || *expansion != '/' || *string != '/') +#endif + { + if ((result_index + len + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + + strcpy (result + result_index, expansion); + result_index += len; + } + free (expansion); + } + + result[result_index] = '\0'; + + return (result); +} + +/* Take FNAME and return the tilde prefix we want expanded. If LENP is + non-null, the index of the end of the prefix into FNAME is returned in + the location it points to. */ +static char * +isolate_tilde_prefix (fname, lenp) + const char *fname; + int *lenp; +{ + char *ret; + int i; + + ret = (char *)xmalloc (strlen (fname)); +#if defined (__MSDOS__) + for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) +#else + for (i = 1; fname[i] && fname[i] != '/'; i++) +#endif + ret[i - 1] = fname[i]; + ret[i - 1] = '\0'; + if (lenp) + *lenp = i; + return ret; +} + +/* Return a string that is PREFIX concatenated with SUFFIX starting at + SUFFIND. */ +static char * +glue_prefix_and_suffix (prefix, suffix, suffind) + char *prefix; + const char *suffix; + int suffind; +{ + char *ret; + int plen, slen; + + plen = (prefix && *prefix) ? strlen (prefix) : 0; + slen = strlen (suffix + suffind); + ret = (char *)xmalloc (plen + slen + 1); + if (plen) + strcpy (ret, prefix); + strcpy (ret + plen, suffix + suffind); + return ret; +} + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. + This always returns a newly-allocated string, never static storage. */ +char * +tilde_expand_word (filename) + const char *filename; +{ + char *dirname, *expansion, *username; + int user_len; + struct passwd *user_entry; + + if (filename == 0) + return ((char *)NULL); + + if (*filename != '~') + return (savestring (filename)); + + /* A leading `~/' or a bare `~' is *always* translated to the value of + $HOME or the home directory of the current user, regardless of any + preexpansion hook. */ + if (filename[1] == '\0' || filename[1] == '/') + { + /* Prefix $HOME to the rest of the string. */ + expansion = sh_get_env_value ("HOME"); + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (expansion == 0) + expansion = sh_get_home_dir (); + + return (glue_prefix_and_suffix (expansion, filename, 1)); + } + + username = isolate_tilde_prefix (filename, &user_len); + + if (tilde_expansion_preexpansion_hook) + { + expansion = (*tilde_expansion_preexpansion_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + free (username); + free (expansion); + return (dirname); + } + } + + /* No preexpansion hook, or the preexpansion hook failed. Look in the + password database. */ + dirname = (char *)NULL; + user_entry = getpwnam (username); + if (user_entry == 0) + { + /* If the calling program has a special syntax for expanding tildes, + and we couldn't find a standard expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + expansion = (*tilde_expansion_failure_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + free (expansion); + } + } + free (username); + /* If we don't have a failure hook, or if the failure hook did not + expand the tilde, return a copy of what we were passed. */ + if (dirname == 0) + dirname = savestring (filename); + } + else + { + free (username); + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); + } + + endpwent (); + return (dirname); +} + + +#if defined (TEST) +#undef NULL +#include + +main (argc, argv) + int argc; + char **argv; +{ + char *result, line[512]; + int done = 0; + + while (!done) + { + printf ("~expand: "); + fflush (stdout); + + if (!gets (line)) + strcpy (line, "done"); + + if ((strcmp (line, "done") == 0) || + (strcmp (line, "quit") == 0) || + (strcmp (line, "exit") == 0)) + { + done = 1; + break; + } + + result = tilde_expand (line); + printf (" --> %s\n", result); + free (result); + } + exit (0); +} + +static void memory_error_and_abort (); + +static void * +xmalloc (bytes) + size_t bytes; +{ + void *temp = (char *)malloc (bytes); + + if (!temp) + memory_error_and_abort (); + return (temp); +} + +static void * +xrealloc (pointer, bytes) + void *pointer; + int bytes; +{ + void *temp; + + if (!pointer) + temp = malloc (bytes); + else + temp = realloc (pointer, bytes); + + if (!temp) + memory_error_and_abort (); + + return (temp); +} + +static void +memory_error_and_abort () +{ + fprintf (stderr, "readline: out of virtual memory\n"); + abort (); +} + +/* + * Local variables: + * compile-command: "gcc -g -DTEST -o tilde tilde.c" + * end: + */ +#endif /* TEST */ diff --git a/readline-4.3/tilde.h b/readline-4.3/tilde.h new file mode 100644 index 0000000..f8182c9 --- /dev/null +++ b/readline-4.3/tilde.h @@ -0,0 +1,78 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992 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 + for it. + + The Library 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. + + The Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/readline-4.3/undo.c b/readline-4.3/undo.c new file mode 100644 index 0000000..25c287b --- /dev/null +++ b/readline-4.3/undo.c @@ -0,0 +1,263 @@ +/* readline.c -- a general facility for reading lines of input + with emacs style editing and completion. */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +/* Some standard library routines. */ +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* Non-zero tells rl_delete_text and rl_insert_text to not add to + the undo list. */ +int _rl_doing_an_undo = 0; + +/* How many unclosed undo groups we currently have. */ +int _rl_undo_group_level = 0; + +/* The current undo list for THE_LINE. */ +UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; + +/* **************************************************************** */ +/* */ +/* Undo, and Undoing */ +/* */ +/* **************************************************************** */ + +/* Remember how to undo something. Concatenate some undos if that + seems right. */ +void +rl_add_undo (what, start, end, text) + enum undo_code what; + int start, end; + char *text; +{ + UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST)); + temp->what = what; + temp->start = start; + temp->end = end; + temp->text = text; + temp->next = rl_undo_list; + rl_undo_list = temp; +} + +/* Free the existing undo list. */ +void +rl_free_undo_list () +{ + while (rl_undo_list) + { + UNDO_LIST *release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + + if (release->what == UNDO_DELETE) + free (release->text); + + free (release); + } + rl_undo_list = (UNDO_LIST *)NULL; +} + +/* Undo the next thing in the list. Return 0 if there + is nothing to undo, or non-zero if there was. */ +int +rl_do_undo () +{ + UNDO_LIST *release; + int waiting_for_begin, start, end; + +#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) + + start = end = waiting_for_begin = 0; + do + { + if (!rl_undo_list) + return (0); + + _rl_doing_an_undo = 1; + RL_SETSTATE(RL_STATE_UNDOING); + + /* To better support vi-mode, a start or end value of -1 means + rl_point, and a value of -2 means rl_end. */ + if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT) + { + start = TRANS (rl_undo_list->start); + end = TRANS (rl_undo_list->end); + } + + switch (rl_undo_list->what) + { + /* Undoing deletes means inserting some text. */ + case UNDO_DELETE: + rl_point = start; + rl_insert_text (rl_undo_list->text); + free (rl_undo_list->text); + break; + + /* Undoing inserts means deleting some text. */ + case UNDO_INSERT: + rl_delete_text (start, end); + rl_point = start; + break; + + /* Undoing an END means undoing everything 'til we get to a BEGIN. */ + case UNDO_END: + waiting_for_begin++; + break; + + /* Undoing a BEGIN means that we are done with this group. */ + case UNDO_BEGIN: + if (waiting_for_begin) + waiting_for_begin--; + else + rl_ding (); + break; + } + + _rl_doing_an_undo = 0; + RL_UNSETSTATE(RL_STATE_UNDOING); + + release = rl_undo_list; + rl_undo_list = rl_undo_list->next; + free (release); + } + while (waiting_for_begin); + + return (1); +} +#undef TRANS + +int +_rl_fix_last_undo_of_type (type, start, end) + int type, start, end; +{ + UNDO_LIST *rl; + + for (rl = rl_undo_list; rl; rl = rl->next) + { + if (rl->what == type) + { + rl->start = start; + rl->end = end; + return 0; + } + } + return 1; +} + +/* Begin a group. Subsequent undos are undone as an atomic operation. */ +int +rl_begin_undo_group () +{ + rl_add_undo (UNDO_BEGIN, 0, 0, 0); + _rl_undo_group_level++; + return 0; +} + +/* End an undo group started with rl_begin_undo_group (). */ +int +rl_end_undo_group () +{ + rl_add_undo (UNDO_END, 0, 0, 0); + _rl_undo_group_level--; + return 0; +} + +/* Save an undo entry for the text from START to END. */ +int +rl_modifying (start, end) + int start, end; +{ + if (start > end) + { + SWAP (start, end); + } + + if (start != end) + { + char *temp = rl_copy_text (start, end); + rl_begin_undo_group (); + rl_add_undo (UNDO_DELETE, start, end, temp); + rl_add_undo (UNDO_INSERT, start, end, (char *)NULL); + rl_end_undo_group (); + } + return 0; +} + +/* Revert the current line to its previous state. */ +int +rl_revert_line (count, key) + int count, key; +{ + if (!rl_undo_list) + rl_ding (); + else + { + while (rl_undo_list) + rl_do_undo (); + } + return 0; +} + +/* Do some undoing of things that were done. */ +int +rl_undo_command (count, key) + int count, key; +{ + if (count < 0) + return 0; /* Nothing to do. */ + + while (count) + { + if (rl_do_undo ()) + count--; + else + { + rl_ding (); + break; + } + } + return 0; +} diff --git a/readline-4.3/util.c b/readline-4.3/util.c new file mode 100644 index 0000000..c7bd360 --- /dev/null +++ b/readline-4.3/util.c @@ -0,0 +1,338 @@ +/* util.c -- readline utility functions */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixjmp.h" + +#if defined (HAVE_UNISTD_H) +# include /* for _POSIX_VERSION */ +#endif /* HAVE_UNISTD_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#include + +/* System-specific feature definitions and include files. */ +#include "rldefs.h" + +#if defined (TIOCSTAT_IN_SYS_IOCTL) +# include +#endif /* TIOCSTAT_IN_SYS_IOCTL */ + +/* Some standard library routines. */ +#include "readline.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return 0 if C is not a member of the class of characters that belong + in words, or 1 if it is. */ + +int _rl_allow_pathname_alphabetic_chars = 0; +static const char *pathname_alphabetic_chars = "/-_=~.#$"; + +int +rl_alphabetic (c) + int c; +{ + if (ALPHABETIC (c)) + return (1); + + return (_rl_allow_pathname_alphabetic_chars && + strchr (pathname_alphabetic_chars, c) != NULL); +} + +/* How to abort things. */ +int +_rl_abort_internal () +{ + rl_ding (); + rl_clear_message (); + _rl_init_argument (); + rl_clear_pending_input (); + + RL_UNSETSTATE (RL_STATE_MACRODEF); + while (rl_executing_macro) + _rl_pop_executing_macro (); + + rl_last_func = (rl_command_func_t *)NULL; + longjmp (readline_top_level, 1); + return (0); +} + +int +rl_abort (count, key) + int count, key; +{ + return (_rl_abort_internal ()); +} + +int +rl_tty_status (count, key) + int count, key; +{ +#if defined (TIOCSTAT) + ioctl (1, TIOCSTAT, (char *)0); + rl_refresh_line (count, key); +#else + rl_ding (); +#endif + return 0; +} + +/* Return a copy of the string between FROM and TO. + FROM is inclusive, TO is not. */ +char * +rl_copy_text (from, to) + int from, to; +{ + register int length; + char *copy; + + /* Fix it if the caller is confused. */ + if (from > to) + SWAP (from, to); + + length = to - from; + copy = (char *)xmalloc (1 + length); + strncpy (copy, rl_line_buffer + from, length); + copy[length] = '\0'; + return (copy); +} + +/* Increase the size of RL_LINE_BUFFER until it has enough space to hold + LEN characters. */ +void +rl_extend_line_buffer (len) + int len; +{ + while (len >= rl_line_buffer_len) + { + rl_line_buffer_len += DEFAULT_BUFFER_SIZE; + rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); + } + + _rl_set_the_line (); +} + + +/* A function for simple tilde expansion. */ +int +rl_tilde_expand (ignore, key) + int ignore, key; +{ + register int start, end; + char *homedir, *temp; + int len; + + end = rl_point; + start = end - 1; + + if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') + { + homedir = tilde_expand ("~"); + _rl_replace_text (homedir, start, end); + return (0); + } + else if (rl_line_buffer[start] != '~') + { + for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) + ; + start++; + } + + end = start; + do + end++; + while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); + + if (whitespace (rl_line_buffer[end]) || end >= rl_end) + end--; + + /* If the first character of the current word is a tilde, perform + tilde expansion and insert the result. If not a tilde, do + nothing. */ + if (rl_line_buffer[start] == '~') + { + len = end - start + 1; + temp = (char *)xmalloc (len + 1); + strncpy (temp, rl_line_buffer + start, len); + temp[len] = '\0'; + homedir = tilde_expand (temp); + free (temp); + + _rl_replace_text (homedir, start, end); + } + + return (0); +} + +/* **************************************************************** */ +/* */ +/* String Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Determine if s2 occurs in s1. If so, return a pointer to the + match in s1. The compare is case insensitive. */ +char * +_rl_strindex (s1, s2) + register const char *s1, *s2; +{ + register int i, l, len; + + for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) + if (_rl_strnicmp (s1 + i, s2, l) == 0) + return ((char *) (s1 + i)); + return ((char *)NULL); +} + +#ifndef HAVE_STRPBRK +/* Find the first occurrence in STRING1 of any character from STRING2. + Return a pointer to the character in STRING1. */ +char * +_rl_strpbrk (string1, string2) + const char *string1, *string2; +{ + register const char *scan; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps; + register int i, v; + + memset (&ps, 0, sizeof (mbstate_t)); +#endif + + for (; *string1; string1++) + { + for (scan = string2; *scan; scan++) + { + if (*string1 == *scan) + return ((char *)string1); + } +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + v = _rl_get_char_len (string1, &ps); + if (v > 1) + string += v - 1; /* -1 to account for auto-increment in loop */ + } +#endif + } + return ((char *)NULL); +} +#endif + +#if !defined (HAVE_STRCASECMP) +/* Compare at most COUNT characters from string1 to string2. Case + doesn't matter. */ +int +_rl_strnicmp (string1, string2, count) + char *string1, *string2; + int count; +{ + register char ch1, ch2; + + while (count) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) + count--; + else + break; + } + return (count); +} + +/* strcmp (), but caseless. */ +int +_rl_stricmp (string1, string2) + char *string1, *string2; +{ + register char ch1, ch2; + + while (*string1 && *string2) + { + ch1 = *string1++; + ch2 = *string2++; + if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) + return (1); + } + return (*string1 - *string2); +} +#endif /* !HAVE_STRCASECMP */ + +/* Stupid comparison routine for qsort () ing strings. */ +int +_rl_qsort_string_compare (s1, s2) + char **s1, **s2; +{ +#if defined (HAVE_STRCOLL) + return (strcoll (*s1, *s2)); +#else + int result; + + result = **s1 - **s2; + if (result == 0) + result = strcmp (*s1, *s2); + + return result; +#endif +} + +/* Function equivalents for the macros defined in chardefs.h. */ +#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } + +FUNCTION_FOR_MACRO (_rl_digit_p) +FUNCTION_FOR_MACRO (_rl_digit_value) +FUNCTION_FOR_MACRO (_rl_lowercase_p) +FUNCTION_FOR_MACRO (_rl_pure_alphabetic) +FUNCTION_FOR_MACRO (_rl_to_lower) +FUNCTION_FOR_MACRO (_rl_to_upper) +FUNCTION_FOR_MACRO (_rl_uppercase_p) + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +#undef _rl_savestring +char * +_rl_savestring (s) + const char *s; +{ + return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); +} diff --git a/readline-4.3/vi_keymap.c b/readline-4.3/vi_keymap.c new file mode 100644 index 0000000..53a67c6 --- /dev/null +++ b/readline-4.3/vi_keymap.c @@ -0,0 +1,877 @@ +/* vi_keymap.c -- the keymap for vi_mode in readline (). */ + +/* Copyright (C) 1987, 1989, 1992 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (BUFSIZ) +#include +#endif /* !BUFSIZ */ + +#include "readline.h" + +#if 0 +extern KEYMAP_ENTRY_ARRAY vi_escape_keymap; +#endif + +/* The keymap arrays for handling vi mode. */ +KEYMAP_ENTRY_ARRAY vi_movement_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_emacs_editing_mode }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, rl_abort }, /* Control-g */ + { ISFUNC, rl_backward_char }, /* Control-h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, rl_clear_screen }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_get_next_history }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, rl_get_previous_history }, /* Control-p */ + { ISFUNC, rl_quoted_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_forward_char }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, rl_insert_comment }, /* # */ + { ISFUNC, rl_end_of_line }, /* $ */ + { ISFUNC, rl_vi_match }, /* % */ + { ISFUNC, rl_vi_tilde_expand }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, rl_vi_complete }, /* * */ + { ISFUNC, rl_get_next_history}, /* + */ + { ISFUNC, rl_vi_char_search }, /* , */ + { ISFUNC, rl_get_previous_history }, /* - */ + { ISFUNC, rl_vi_redo }, /* . */ + { ISFUNC, rl_vi_search }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_beg_of_line }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, rl_vi_char_search }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, rl_vi_complete }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, rl_vi_search }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_vi_append_eol }, /* A */ + { ISFUNC, rl_vi_prev_word}, /* B */ + { ISFUNC, rl_vi_change_to }, /* C */ + { ISFUNC, rl_vi_delete_to }, /* D */ + { ISFUNC, rl_vi_end_word }, /* E */ + { ISFUNC, rl_vi_char_search }, /* F */ + { ISFUNC, rl_vi_fetch_history }, /* G */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* H */ + { ISFUNC, rl_vi_insert_beg }, /* I */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* J */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* K */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* L */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* M */ + { ISFUNC, rl_vi_search_again }, /* N */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* O */ + { ISFUNC, rl_vi_put }, /* P */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Q */ + { ISFUNC, rl_vi_replace }, /* R */ + { ISFUNC, rl_vi_subst }, /* S */ + { ISFUNC, rl_vi_char_search }, /* T */ + { 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_yank_to }, /* Y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */ + { ISFUNC, rl_vi_complete }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, rl_vi_first_print }, /* ^ */ + { ISFUNC, rl_vi_yank_arg }, /* _ */ + { ISFUNC, rl_vi_goto_mark }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_vi_append_mode }, /* a */ + { ISFUNC, rl_vi_prev_word }, /* b */ + { ISFUNC, rl_vi_change_to }, /* c */ + { ISFUNC, rl_vi_delete_to }, /* d */ + { ISFUNC, rl_vi_end_word }, /* e */ + { ISFUNC, rl_vi_char_search }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, rl_backward_char }, /* h */ + { ISFUNC, rl_vi_insertion_mode }, /* i */ + { ISFUNC, rl_get_next_history }, /* j */ + { ISFUNC, rl_get_previous_history }, /* k */ + { ISFUNC, rl_forward_char }, /* l */ + { ISFUNC, rl_vi_set_mark }, /* m */ + { ISFUNC, rl_vi_search_again }, /* n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* o */ + { ISFUNC, rl_vi_put }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, rl_vi_change_char }, /* r */ + { ISFUNC, rl_vi_subst }, /* s */ + { ISFUNC, rl_vi_char_search }, /* t */ + { ISFUNC, rl_vi_undo }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, rl_vi_next_word }, /* w */ + { ISFUNC, rl_vi_delete }, /* x */ + { ISFUNC, rl_vi_yank_to }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, rl_vi_column }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, rl_vi_change_case }, /* ~ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; + + +KEYMAP_ENTRY_ARRAY vi_insertion_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, rl_insert }, /* Control-a */ + { ISFUNC, rl_insert }, /* Control-b */ + { ISFUNC, rl_insert }, /* Control-c */ + { ISFUNC, rl_vi_eof_maybe }, /* Control-d */ + { ISFUNC, rl_insert }, /* Control-e */ + { ISFUNC, rl_insert }, /* Control-f */ + { ISFUNC, rl_insert }, /* Control-g */ + { ISFUNC, rl_rubout }, /* Control-h */ + { ISFUNC, rl_complete }, /* Control-i */ + { ISFUNC, rl_newline }, /* Control-j */ + { ISFUNC, rl_insert }, /* Control-k */ + { ISFUNC, rl_insert }, /* Control-l */ + { ISFUNC, rl_newline }, /* Control-m */ + { ISFUNC, rl_insert }, /* Control-n */ + { ISFUNC, rl_insert }, /* Control-o */ + { ISFUNC, rl_insert }, /* Control-p */ + { ISFUNC, rl_insert }, /* Control-q */ + { ISFUNC, rl_reverse_search_history }, /* Control-r */ + { ISFUNC, rl_forward_search_history }, /* Control-s */ + { ISFUNC, rl_transpose_chars }, /* Control-t */ + { ISFUNC, rl_unix_line_discard }, /* Control-u */ + { ISFUNC, rl_quoted_insert }, /* Control-v */ + { ISFUNC, rl_unix_word_rubout }, /* Control-w */ + { ISFUNC, rl_insert }, /* Control-x */ + { ISFUNC, rl_yank }, /* Control-y */ + { ISFUNC, rl_insert }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, rl_insert }, /* Control-\ */ + { ISFUNC, rl_insert }, /* Control-] */ + { ISFUNC, rl_insert }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, rl_insert }, /* SPACE */ + { ISFUNC, rl_insert }, /* ! */ + { ISFUNC, rl_insert }, /* " */ + { ISFUNC, rl_insert }, /* # */ + { ISFUNC, rl_insert }, /* $ */ + { ISFUNC, rl_insert }, /* % */ + { ISFUNC, rl_insert }, /* & */ + { ISFUNC, rl_insert }, /* ' */ + { ISFUNC, rl_insert }, /* ( */ + { ISFUNC, rl_insert }, /* ) */ + { ISFUNC, rl_insert }, /* * */ + { ISFUNC, rl_insert }, /* + */ + { ISFUNC, rl_insert }, /* , */ + { ISFUNC, rl_insert }, /* - */ + { ISFUNC, rl_insert }, /* . */ + { ISFUNC, rl_insert }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_insert }, /* 0 */ + { ISFUNC, rl_insert }, /* 1 */ + { ISFUNC, rl_insert }, /* 2 */ + { ISFUNC, rl_insert }, /* 3 */ + { ISFUNC, rl_insert }, /* 4 */ + { ISFUNC, rl_insert }, /* 5 */ + { ISFUNC, rl_insert }, /* 6 */ + { ISFUNC, rl_insert }, /* 7 */ + { ISFUNC, rl_insert }, /* 8 */ + { ISFUNC, rl_insert }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, rl_insert }, /* : */ + { ISFUNC, rl_insert }, /* ; */ + { ISFUNC, rl_insert }, /* < */ + { ISFUNC, rl_insert }, /* = */ + { ISFUNC, rl_insert }, /* > */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_insert }, /* A */ + { ISFUNC, rl_insert }, /* B */ + { ISFUNC, rl_insert }, /* C */ + { ISFUNC, rl_insert }, /* D */ + { ISFUNC, rl_insert }, /* E */ + { ISFUNC, rl_insert }, /* F */ + { ISFUNC, rl_insert }, /* G */ + { ISFUNC, rl_insert }, /* H */ + { ISFUNC, rl_insert }, /* I */ + { ISFUNC, rl_insert }, /* J */ + { ISFUNC, rl_insert }, /* K */ + { ISFUNC, rl_insert }, /* L */ + { ISFUNC, rl_insert }, /* M */ + { ISFUNC, rl_insert }, /* N */ + { ISFUNC, rl_insert }, /* O */ + { ISFUNC, rl_insert }, /* P */ + { ISFUNC, rl_insert }, /* Q */ + { ISFUNC, rl_insert }, /* R */ + { ISFUNC, rl_insert }, /* S */ + { ISFUNC, rl_insert }, /* T */ + { ISFUNC, rl_insert }, /* U */ + { ISFUNC, rl_insert }, /* V */ + { ISFUNC, rl_insert }, /* W */ + { ISFUNC, rl_insert }, /* X */ + { ISFUNC, rl_insert }, /* Y */ + { ISFUNC, rl_insert }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_insert }, /* [ */ + { ISFUNC, rl_insert }, /* \ */ + { ISFUNC, rl_insert }, /* ] */ + { ISFUNC, rl_insert }, /* ^ */ + { ISFUNC, rl_insert }, /* _ */ + { ISFUNC, rl_insert }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, rl_insert }, /* a */ + { ISFUNC, rl_insert }, /* b */ + { ISFUNC, rl_insert }, /* c */ + { ISFUNC, rl_insert }, /* d */ + { ISFUNC, rl_insert }, /* e */ + { ISFUNC, rl_insert }, /* f */ + { ISFUNC, rl_insert }, /* g */ + { ISFUNC, rl_insert }, /* h */ + { ISFUNC, rl_insert }, /* i */ + { ISFUNC, rl_insert }, /* j */ + { ISFUNC, rl_insert }, /* k */ + { ISFUNC, rl_insert }, /* l */ + { ISFUNC, rl_insert }, /* m */ + { ISFUNC, rl_insert }, /* n */ + { ISFUNC, rl_insert }, /* o */ + { ISFUNC, rl_insert }, /* p */ + { ISFUNC, rl_insert }, /* q */ + { ISFUNC, rl_insert }, /* r */ + { ISFUNC, rl_insert }, /* s */ + { ISFUNC, rl_insert }, /* t */ + { ISFUNC, rl_insert }, /* u */ + { ISFUNC, rl_insert }, /* v */ + { ISFUNC, rl_insert }, /* w */ + { ISFUNC, rl_insert }, /* x */ + { ISFUNC, rl_insert }, /* y */ + { ISFUNC, rl_insert }, /* z */ + + /* Final punctuation. */ + { ISFUNC, rl_insert }, /* { */ + { ISFUNC, rl_insert }, /* | */ + { ISFUNC, rl_insert }, /* } */ + { ISFUNC, rl_insert }, /* ~ */ + { ISFUNC, rl_rubout }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Pure 8-bit characters (128 - 159). + These might be used in some + character sets. */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + { ISFUNC, rl_insert }, /* ? */ + + /* ISO Latin-1 characters (160 - 255) */ + { ISFUNC, rl_insert }, /* No-break space */ + { ISFUNC, rl_insert }, /* Inverted exclamation mark */ + { ISFUNC, rl_insert }, /* Cent sign */ + { ISFUNC, rl_insert }, /* Pound sign */ + { ISFUNC, rl_insert }, /* Currency sign */ + { ISFUNC, rl_insert }, /* Yen sign */ + { ISFUNC, rl_insert }, /* Broken bar */ + { ISFUNC, rl_insert }, /* Section sign */ + { ISFUNC, rl_insert }, /* Diaeresis */ + { ISFUNC, rl_insert }, /* Copyright sign */ + { ISFUNC, rl_insert }, /* Feminine ordinal indicator */ + { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Not sign */ + { ISFUNC, rl_insert }, /* Soft hyphen */ + { ISFUNC, rl_insert }, /* Registered sign */ + { ISFUNC, rl_insert }, /* Macron */ + { ISFUNC, rl_insert }, /* Degree sign */ + { ISFUNC, rl_insert }, /* Plus-minus sign */ + { ISFUNC, rl_insert }, /* Superscript two */ + { ISFUNC, rl_insert }, /* Superscript three */ + { ISFUNC, rl_insert }, /* Acute accent */ + { ISFUNC, rl_insert }, /* Micro sign */ + { ISFUNC, rl_insert }, /* Pilcrow sign */ + { ISFUNC, rl_insert }, /* Middle dot */ + { ISFUNC, rl_insert }, /* Cedilla */ + { ISFUNC, rl_insert }, /* Superscript one */ + { ISFUNC, rl_insert }, /* Masculine ordinal indicator */ + { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */ + { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */ + { ISFUNC, rl_insert }, /* Vulgar fraction one half */ + { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */ + { ISFUNC, rl_insert }, /* Inverted questionk mark */ + { ISFUNC, rl_insert }, /* Latin capital letter a with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter a with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin capital letter ae */ + { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin capital letter e with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter e with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter i with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter i with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter o with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Multiplication sign */ + { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin capital letter u with grave */ + { ISFUNC, rl_insert }, /* Latin capital letter u with acute */ + { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */ + { 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) */ + { ISFUNC, rl_insert }, /* Latin small letter a with grave */ + { 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 */ + { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter a with ring above */ + { ISFUNC, rl_insert }, /* Latin small letter ae */ + { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */ + { ISFUNC, rl_insert }, /* Latin small letter e with grave */ + { ISFUNC, rl_insert }, /* Latin small letter e with acute */ + { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter i with grave */ + { ISFUNC, rl_insert }, /* Latin small letter i with acute */ + { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */ + { ISFUNC, rl_insert }, /* Latin small letter n with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with grave */ + { ISFUNC, rl_insert }, /* Latin small letter o with acute */ + { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter o with tilde */ + { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */ + { ISFUNC, rl_insert }, /* Division sign */ + { ISFUNC, rl_insert }, /* Latin small letter o with stroke */ + { ISFUNC, rl_insert }, /* Latin small letter u with grave */ + { ISFUNC, rl_insert }, /* Latin small letter u with acute */ + { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */ + { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */ + { ISFUNC, rl_insert }, /* Latin small letter y with acute */ + { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */ + { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */ +#endif /* KEYMAP_SIZE > 128 */ +}; + +/* Unused for the time being. */ +#if 0 +KEYMAP_ENTRY_ARRAY vi_escape_keymap = { + /* The regular control keys come first. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */ + { ISFUNC, rl_tab_insert}, /* Control-i */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-j */ + { ISFUNC, rl_kill_line }, /* Control-k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */ + { ISFUNC, rl_emacs_editing_mode}, /* Control-m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */ + + { ISFUNC, rl_vi_movement_mode }, /* Control-[ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */ + { ISFUNC, rl_vi_undo }, /* Control-_ */ + + /* The start of printing characters. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* " */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* # */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* % */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* & */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* * */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* + */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* , */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* - */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* . */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* / */ + + /* Regular digits. */ + { ISFUNC, rl_vi_arg_digit }, /* 0 */ + { ISFUNC, rl_vi_arg_digit }, /* 1 */ + { ISFUNC, rl_vi_arg_digit }, /* 2 */ + { ISFUNC, rl_vi_arg_digit }, /* 3 */ + { ISFUNC, rl_vi_arg_digit }, /* 4 */ + { ISFUNC, rl_vi_arg_digit }, /* 5 */ + { ISFUNC, rl_vi_arg_digit }, /* 6 */ + { ISFUNC, rl_vi_arg_digit }, /* 7 */ + { ISFUNC, rl_vi_arg_digit }, /* 8 */ + { ISFUNC, rl_vi_arg_digit }, /* 9 */ + + /* A little more punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* : */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* < */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* = */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* > */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */ + + /* Uppercase alphabet. */ + { ISFUNC, rl_do_lowercase_version }, /* A */ + { ISFUNC, rl_do_lowercase_version }, /* B */ + { ISFUNC, rl_do_lowercase_version }, /* C */ + { ISFUNC, rl_do_lowercase_version }, /* D */ + { ISFUNC, rl_do_lowercase_version }, /* E */ + { ISFUNC, rl_do_lowercase_version }, /* F */ + { ISFUNC, rl_do_lowercase_version }, /* G */ + { ISFUNC, rl_do_lowercase_version }, /* H */ + { ISFUNC, rl_do_lowercase_version }, /* I */ + { ISFUNC, rl_do_lowercase_version }, /* J */ + { ISFUNC, rl_do_lowercase_version }, /* K */ + { ISFUNC, rl_do_lowercase_version }, /* L */ + { ISFUNC, rl_do_lowercase_version }, /* M */ + { ISFUNC, rl_do_lowercase_version }, /* N */ + { ISFUNC, rl_do_lowercase_version }, /* O */ + { ISFUNC, rl_do_lowercase_version }, /* P */ + { ISFUNC, rl_do_lowercase_version }, /* Q */ + { ISFUNC, rl_do_lowercase_version }, /* R */ + { ISFUNC, rl_do_lowercase_version }, /* S */ + { ISFUNC, rl_do_lowercase_version }, /* T */ + { ISFUNC, rl_do_lowercase_version }, /* U */ + { ISFUNC, rl_do_lowercase_version }, /* V */ + { ISFUNC, rl_do_lowercase_version }, /* W */ + { ISFUNC, rl_do_lowercase_version }, /* X */ + { ISFUNC, rl_do_lowercase_version }, /* Y */ + { ISFUNC, rl_do_lowercase_version }, /* Z */ + + /* Some more punctuation. */ + { ISFUNC, rl_arrow_keys }, /* [ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */ + + /* Lowercase alphabet. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* a */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* b */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* c */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* d */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* e */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* f */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* h */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* i */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* j */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* k */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* l */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* m */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* n */ + { ISFUNC, rl_arrow_keys }, /* o */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* p */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* q */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* r */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* s */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* t */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* u */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* v */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* w */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* x */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* y */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* z */ + + /* Final punctuation. */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* { */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* | */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* } */ + { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */ + { ISFUNC, rl_backward_kill_word }, /* RUBOUT */ + +#if KEYMAP_SIZE > 128 + /* Undefined keys. */ + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 }, + { ISFUNC, (rl_command_func_t *)0x0 } +#endif /* KEYMAP_SIZE > 128 */ +}; +#endif diff --git a/readline-4.3/vi_mode.c b/readline-4.3/vi_mode.c new file mode 100644 index 0000000..5d146b3 --- /dev/null +++ b/readline-4.3/vi_mode.c @@ -0,0 +1,1485 @@ +/* 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. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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 + +/* **************************************************************** */ +/* */ +/* VI Emulation Mode */ +/* */ +/* **************************************************************** */ +#include "rlconf.h" + +#if defined (VI_MODE) + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include + +/* Some standard library routines. */ +#include "rldefs.h" +#include "rlmbutil.h" + +#include "readline.h" +#include "history.h" + +#include "rlprivate.h" +#include "xmalloc.h" + +#ifndef member +#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) +#endif + +/* Non-zero means enter insertion mode. */ +static int _rl_vi_doing_insert; + +/* Command keys which do movement for xxx_to commands. */ +static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|"; + +/* Keymap used for vi replace characters. Created dynamically since + rarely used. */ +static Keymap vi_replace_map; + +/* The number of characters inserted in the last replace operation. */ +static int vi_replace_count; + +/* If non-zero, we have text inserted after a c[motion] command that put + us implicitly into insert mode. Some people want this text to be + attached to the command so that it is `redoable' with `.'. */ +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]; +#else +static int _rl_vi_last_search_char; +#endif +static int _rl_vi_last_replacement; + +static int _rl_vi_last_key_before_insert; + +static int vi_redoing; + +/* Text modification commands. These are the `redoable' commands. */ +static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; + +/* Arrays for the saved marks. */ +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_digit_loop1 PARAMS((void)); + +void +_rl_vi_initialize_line () +{ + register int i; + + for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++) + vi_mark_chars[i] = -1; +} + +void +_rl_vi_reset_last () +{ + _rl_vi_last_command = 'i'; + _rl_vi_last_repeat = 1; + _rl_vi_last_arg_sign = 1; + _rl_vi_last_motion = 0; +} + +void +_rl_vi_set_last (key, repeat, sign) + int key, repeat, sign; +{ + _rl_vi_last_command = key; + _rl_vi_last_repeat = repeat; + _rl_vi_last_arg_sign = sign; +} + +/* Is the command C a VI mode text modification command? */ +int +_rl_vi_textmod_command (c) + int c; +{ + return (member (c, vi_textmod)); +} + +static void +_rl_vi_stuff_insert (count) + int count; +{ + rl_begin_undo_group (); + while (count--) + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); +} + +/* Bound to `.'. Called from command mode, so we know that we have to + redo a text modification command. The default for _rl_vi_last_command + puts you back into insert mode. */ +int +rl_vi_redo (count, c) + int count, c; +{ + int r; + + if (!rl_explicit_arg) + { + rl_numeric_arg = _rl_vi_last_repeat; + rl_arg_sign = _rl_vi_last_arg_sign; + } + + r = 0; + vi_redoing = 1; + /* If we're redoing an insert with `i', stuff in the inserted text + and do not go into insertion mode. */ + if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer) + { + _rl_vi_stuff_insert (count); + /* And back up point over the last character inserted. */ + if (rl_point > 0) + rl_point--; + } + else + r = _rl_dispatch (_rl_vi_last_command, _rl_keymap); + vi_redoing = 0; + + return (r); +} + +/* A placeholder for further expansion. */ +int +rl_vi_undo (count, key) + int count, key; +{ + return (rl_undo_command (count, key)); +} + +/* Yank the nth arg from the previous line into this line at point. */ +int +rl_vi_yank_arg (count, key) + int count, key; +{ + /* Readline thinks that the first word on a line is the 0th, while vi + thinks the first word on a line is the 1st. Compensate. */ + if (rl_explicit_arg) + rl_yank_nth_arg (count - 1, 0); + else + rl_yank_nth_arg ('$', 0); + + return (0); +} + +/* With an argument, move back that many history lines, else move to the + beginning of history. */ +int +rl_vi_fetch_history (count, c) + int count, c; +{ + int wanted; + + /* Giving an argument of n means we want the nth command in the history + file. The command number is interpreted the same way that the bash + `history' command does it -- that is, giving an argument count of 450 + to this command would get the command listed as number 450 in the + output of `history'. */ + if (rl_explicit_arg) + { + wanted = history_base + where_history () - count; + if (wanted <= 0) + rl_beginning_of_history (0, 0); + else + rl_get_previous_history (wanted, c); + } + else + rl_beginning_of_history (count, 0); + return (0); +} + +/* Search again for the last thing searched for. */ +int +rl_vi_search_again (count, key) + int count, key; +{ + switch (key) + { + case 'n': + rl_noninc_reverse_search_again (count, key); + break; + + case 'N': + rl_noninc_forward_search_again (count, key); + break; + } + return (0); +} + +/* Do a vi style search. */ +int +rl_vi_search (count, key) + int count, key; +{ + switch (key) + { + case '?': + rl_noninc_forward_search (count, key); + break; + + case '/': + rl_noninc_reverse_search (count, key); + break; + + default: + rl_ding (); + break; + } + return (0); +} + +/* Completion, from vi's point of view. */ +int +rl_vi_complete (ignore, key) + int ignore, key; +{ + if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) + { + if (!whitespace (rl_line_buffer[rl_point + 1])) + rl_vi_end_word (1, 'E'); + rl_point++; + } + + if (key == '*') + rl_complete_internal ('*'); /* Expansion and replacement. */ + else if (key == '=') + rl_complete_internal ('?'); /* List possible completions. */ + else if (key == '\\') + rl_complete_internal (TAB); /* Standard Readline completion. */ + else + rl_complete (0, key); + + if (key == '*' || key == '\\') + { + _rl_vi_set_last (key, 1, rl_arg_sign); + rl_vi_insertion_mode (1, key); + } + return (0); +} + +/* Tilde expansion for vi mode. */ +int +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); + return (0); +} + +/* Previous word in vi mode. */ +int +rl_vi_prev_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_vi_next_word (-count, key)); + + if (rl_point == 0) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_bWord (count, key); + else + rl_vi_bword (count, key); + + return (0); +} + +/* Next word in vi mode. */ +int +rl_vi_next_word (count, key) + int count, key; +{ + if (count < 0) + return (rl_vi_prev_word (-count, key)); + + if (rl_point >= (rl_end - 1)) + { + rl_ding (); + return (0); + } + + if (_rl_uppercase_p (key)) + rl_vi_fWord (count, key); + else + rl_vi_fword (count, key); + return (0); +} + +/* Move to the end of the ?next? word. */ +int +rl_vi_end_word (count, key) + int count, key; +{ + if (count < 0) + { + rl_ding (); + return -1; + } + + if (_rl_uppercase_p (key)) + rl_vi_eWord (count, key); + else + rl_vi_eword (count, key); + return (0); +} + +/* Move forward a word the way that 'W' does. */ +int +rl_vi_fWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + /* Skip until whitespace. */ + while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + + /* Now skip whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + return (0); +} + +int +rl_vi_bWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point > 0) + { + /* If we are at the start of a word, move back to whitespace so + we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + if (rl_point > 0) + { + while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point])); + rl_point++; + } + } + return (0); +} + +int +rl_vi_eWord (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* 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])); + + if (rl_point && rl_point < rl_end) + { + /* Skip whitespace. */ + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Skip until whitespace. */ + while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point])) + rl_point++; + + /* Move back to the last character of the word. */ + rl_point--; + } + } + return (0); +} + +int +rl_vi_fword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < (rl_end - 1)) + { + /* Move to white space (really non-identifer). */ + if (_rl_isident (rl_line_buffer[rl_point])) + { + while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + else /* if (!whitespace (rl_line_buffer[rl_point])) */ + { + while (!_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + + /* Move past whitespace. */ + while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) + rl_point++; + } + return (0); +} + +int +rl_vi_bword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point > 0) + { + int last_is_ident; + + /* If we are at the start of a word, move back to whitespace + so we will go back to the start of the previous word. */ + if (!whitespace (rl_line_buffer[rl_point]) && + whitespace (rl_line_buffer[rl_point - 1])) + rl_point--; + + /* If this character and the previous character are `opposite', move + back so we don't get messed up by the rl_point++ down there in + the while loop. Without this code, words like `l;' screw up the + function. */ + last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]); + if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) || + (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident)) + rl_point--; + + while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + if (rl_point > 0) + { + if (_rl_isident (rl_line_buffer[rl_point])) + while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point])); + else + while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) && + !whitespace (rl_line_buffer[rl_point])); + rl_point++; + } + } + return (0); +} + +int +rl_vi_eword (count, ignore) + int count, ignore; +{ + while (count-- && rl_point < rl_end - 1) + { + if (!whitespace (rl_line_buffer[rl_point])) + rl_point++; + + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + + if (rl_point < rl_end) + { + if (_rl_isident (rl_line_buffer[rl_point])) + while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); + else + while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) + && !whitespace (rl_line_buffer[rl_point])); + } + rl_point--; + } + return (0); +} + +int +rl_vi_insert_beg (count, key) + int count, key; +{ + rl_beg_of_line (1, key); + rl_vi_insertion_mode (1, key); + return (0); +} + +int +rl_vi_append_mode (count, key) + int count, key; +{ + if (rl_point < rl_end) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point++; + else + { + int point = rl_point; + rl_forward_char (1, key); + if (point == rl_point) + rl_point = rl_end; + } + } + rl_vi_insertion_mode (1, key); + return (0); +} + +int +rl_vi_append_eol (count, key) + int count, key; +{ + rl_end_of_line (1, key); + rl_vi_append_mode (1, key); + return (0); +} + +/* What to do in the case of C-d. */ +int +rl_vi_eof_maybe (count, c) + int count, c; +{ + return (rl_newline (1, '\n')); +} + +/* Insertion mode stuff. */ + +/* Switching from one mode to the other really just involves + switching keymaps. */ +int +rl_vi_insertion_mode (count, key) + int count, key; +{ + _rl_keymap = vi_insertion_keymap; + _rl_vi_last_key_before_insert = key; + return (0); +} + +static void +_rl_vi_save_insert (up) + UNDO_LIST *up; +{ + int len, start, end; + + if (up == 0) + { + if (vi_insert_buffer_size >= 1) + vi_insert_buffer[0] = '\0'; + return; + } + + start = up->start; + end = up->end; + len = end - start + 1; + if (len >= vi_insert_buffer_size) + { + vi_insert_buffer_size += (len + 32) - (len % 32); + vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size); + } + strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); + vi_insert_buffer[len-1] = '\0'; +} + +void +_rl_vi_done_inserting () +{ + if (_rl_vi_doing_insert) + { + /* The `C', `s', and `S' commands set this. */ + rl_end_undo_group (); + /* Now, the text between rl_undo_list->next->start and + rl_undo_list->next->end is what was inserted while in insert + mode. It gets copied to VI_INSERT_BUFFER because it depends + on absolute indices into the line which may change (though they + probably will not). */ + _rl_vi_doing_insert = 0; + _rl_vi_save_insert (rl_undo_list->next); + vi_continued_command = 1; + } + else + { + if (_rl_vi_last_key_before_insert == 'i' && 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') + rl_end_undo_group (); + while (_rl_undo_group_level > 0) + rl_end_undo_group (); + vi_continued_command = 0; + } +} + +int +rl_vi_movement_mode (count, key) + int count, key; +{ + if (rl_point > 0) + rl_backward_char (1, key); + + _rl_keymap = vi_movement_keymap; + _rl_vi_done_inserting (); + return (0); +} + +int +rl_vi_arg_digit (count, c) + int count, c; +{ + if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) + return (rl_beg_of_line (1, c)); + else + return (rl_digit_argument (count, c)); +} + +/* Change the case of the next COUNT characters. */ +#if defined (HANDLE_MULTIBYTE) +static int +_rl_vi_change_mbchar_case (count) + int count; +{ + wchar_t wc; + char mb[MB_LEN_MAX]; + mbstate_t ps; + + memset (&ps, 0, sizeof (mbstate_t)); + if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0) + count--; + while (count-- && rl_point < rl_end) + { + mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps); + if (iswupper (wc)) + wc = towlower (wc); + else if (iswlower (wc)) + wc = towupper (wc); + else + { + /* Just skip over chars neither upper nor lower case */ + rl_forward_char (1, 0); + continue; + } + + /* Vi is kind of strange here. */ + if (wc) + { + wctomb (mb, wc); + rl_begin_undo_group (); + rl_delete (1, 0); + rl_insert_text (mb); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, 0); + } + + return 0; +} +#endif + +int +rl_vi_change_case (count, ignore) + int count, ignore; +{ + char c = 0; + + /* Don't try this on an empty line. */ + if (rl_point >= rl_end) + return (0); + +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + return (_rl_vi_change_mbchar_case (count)); +#endif + + while (count-- && rl_point < rl_end) + { + if (_rl_uppercase_p (rl_line_buffer[rl_point])) + c = _rl_to_lower (rl_line_buffer[rl_point]); + else if (_rl_lowercase_p (rl_line_buffer[rl_point])) + c = _rl_to_upper (rl_line_buffer[rl_point]); + else + { + /* Just skip over characters neither upper nor lower case. */ + rl_forward_char (1, c); + continue; + } + + /* Vi is kind of strange here. */ + if (c) + { + rl_begin_undo_group (); + rl_delete (1, c); + _rl_insert_char (1, c); + rl_end_undo_group (); + rl_vi_check (); + } + else + rl_forward_char (1, c); + } + return (0); +} + +int +rl_vi_put (count, key) + int 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); + rl_backward_char (1, key); + return (0); +} + +int +rl_vi_check () +{ + if (rl_point && 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--; + } + return (0); +} + +int +rl_vi_column (count, key) + int count, key; +{ + if (count > rl_end) + rl_end_of_line (1, key); + else + rl_point = count - 1; + return (0); +} + +int +rl_vi_domove (key, nextkey) + int key, *nextkey; +{ + int c, save; + int old_end; + + rl_mark = rl_point; + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + *nextkey = c; + + if (!member (c, vi_motion)) + { + if (_rl_digit_p (c)) + { + save = rl_numeric_arg; + rl_numeric_arg = _rl_digit_value (c); + rl_digit_loop1 (); + rl_numeric_arg *= save; + RL_SETSTATE(RL_STATE_MOREINPUT); + c = rl_read_key (); /* real command */ + RL_UNSETSTATE(RL_STATE_MOREINPUT); + *nextkey = c; + } + else if (key == c && (key == 'd' || key == 'y' || key == 'c')) + { + rl_mark = rl_end; + rl_beg_of_line (1, c); + _rl_vi_last_motion = c; + return (0); + } + else + return (-1); + } + + _rl_vi_last_motion = c; + + /* Append a blank character temporarily so that the motion routines + work right at the end of the line. */ + old_end = rl_end; + rl_line_buffer[rl_end++] = ' '; + rl_line_buffer[rl_end] = '\0'; + + _rl_dispatch (c, _rl_keymap); + + /* Remove the blank that we added. */ + rl_end = old_end; + rl_line_buffer[rl_end] = '\0'; + if (rl_point > rl_end) + rl_point = rl_end; + + /* No change in position means the command failed. */ + if (rl_mark == rl_point) + return (-1); + + /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next + word. If we are not at the end of the line, and we are on a + non-whitespace character, move back one (presumably to whitespace). */ + if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && + !whitespace (rl_line_buffer[rl_point])) + rl_point--; + + /* If cw or cW, back up to the end of a word, so the behaviour of ce + or cE is the actual result. Brute-force, no subtlety. */ + if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W')) + { + /* Don't move farther back than where we started. */ + while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point])) + rl_point--; + + /* Posix.2 says that if cw or cW moves the cursor towards the end of + the line, the character under the cursor should be deleted. */ + if (rl_point == rl_mark) + rl_point++; + else + { + /* Move past the end of the word so that the kill doesn't + remove the last letter of the previous word. Only do this + if we are not at the end of the line. */ + if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point])) + rl_point++; + } + } + + if (rl_mark < rl_point) + SWAP (rl_point, rl_mark); + + 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; + + 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 (c >= 0 && _rl_keymap[c].type == ISFUNC && + _rl_keymap[c].function == rl_universal_argument) + { + rl_numeric_arg *= 4; + continue; + } + + 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; + } + } + + RL_UNSETSTATE(RL_STATE_NUMERICARG); + return (0); +} + +int +rl_vi_delete_to (count, key) + int count, key; +{ + int c; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + else if (vi_redoing) + rl_stuff_char (_rl_vi_last_motion); + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. */ + if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + rl_kill_text (rl_point, rl_mark); + return (0); +} + +int +rl_vi_change_to (count, key) + int count, key; +{ + int c, start_pos; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + else if (vi_redoing) + rl_stuff_char (_rl_vi_last_motion); + + start_pos = rl_point; + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. c[wW] are handled by special-case code in rl_vi_domove(), + and already leave the mark at the correct location. */ + if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + /* The cursor never moves with c[wW]. */ + if ((_rl_to_upper (c) == 'W') && rl_point < start_pos) + rl_point = start_pos; + + if (vi_redoing) + { + if (vi_insert_buffer && *vi_insert_buffer) + rl_begin_undo_group (); + rl_delete_text (rl_point, rl_mark); + if (vi_insert_buffer && *vi_insert_buffer) + { + rl_insert_text (vi_insert_buffer); + rl_end_undo_group (); + } + } + else + { + rl_begin_undo_group (); /* to make the `u' command work */ + rl_kill_text (rl_point, rl_mark); + /* `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); + } + + return (0); +} + +int +rl_vi_yank_to (count, key) + int count, key; +{ + int c, save = rl_point; + + if (_rl_uppercase_p (key)) + rl_stuff_char ('$'); + + if (rl_vi_domove (key, &c)) + { + rl_ding (); + return -1; + } + + /* These are the motion commands that do not require adjusting the + mark. */ + if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end)) + rl_mark++; + + rl_begin_undo_group (); + rl_kill_text (rl_point, rl_mark); + rl_end_undo_group (); + rl_do_undo (); + rl_point = save; + + return (0); +} + +int +rl_vi_delete (count, key) + int count, key; +{ + int end; + + if (rl_end == 0) + { + rl_ding (); + return -1; + } + + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO); + else + end = rl_point + count; + + if (end >= rl_end) + end = rl_end; + + rl_kill_text (rl_point, end); + + if (rl_point > 0 && rl_point == rl_end) + rl_backward_char (1, key); + return (0); +} + +int +rl_vi_back_to_indent (count, key) + int count, key; +{ + rl_beg_of_line (1, key); + while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) + rl_point++; + return (0); +} + +int +rl_vi_first_print (count, key) + int count, key; +{ + return (rl_vi_back_to_indent (1, key)); +} + +int +rl_vi_char_search (count, key) + int count, key; +{ +#if defined (HANDLE_MULTIBYTE) + static char *target; + static int mb_len; +#else + static char target; +#endif + static int orig_dir, dir; + + if (key == ';' || key == ',') + dir = key == ';' ? orig_dir : -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; + break; + + case 'T': + orig_dir = dir = BTO; + break; + + case 'f': + orig_dir = dir = FFIND; + break; + + case 'F': + orig_dir = dir = BFIND; + break; + } + } + +#if defined (HANDLE_MULTIBYTE) + return (_rl_char_search_internal (count, dir, target, mb_len)); +#else + return (_rl_char_search_internal (count, dir, target)); +#endif +} + +/* Match brackets */ +int +rl_vi_match (ignore, key) + int ignore, key; +{ + int count = 1, brack, pos, tmp, pre; + + pos = rl_point; + if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + { + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) + { + pre = rl_point; + rl_forward_char (1, key); + if (pre == rl_point) + break; + } + } + else + while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && + rl_point < rl_end - 1) + rl_forward_char (1, key); + + if (brack <= 0) + { + rl_point = pos; + rl_ding (); + return -1; + } + } + + pos = rl_point; + + if (brack < 0) + { + while (count) + { + tmp = pos; + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos--; + else + { + pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY); + if (tmp == pos) + pos--; + } + if (pos >= 0) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return -1; + } + } + } + else + { /* brack > 0 */ + while (count) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + pos++; + else + pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY); + + if (pos < rl_end) + { + int b = rl_vi_bracktype (rl_line_buffer[pos]); + if (b == -brack) + count--; + else if (b == brack) + count++; + } + else + { + rl_ding (); + return -1; + } + } + } + rl_point = pos; + return (0); +} + +int +rl_vi_bracktype (c) + int c; +{ + switch (c) + { + case '(': return 1; + case ')': return -1; + case '[': return 2; + case ']': return -2; + case '{': return 3; + case '}': return -3; + default: return 0; + } +} + +/* 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; +{ + 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); + } + + if (c == '\033' || c == CTRL ('C')) + return -1; + + while (count-- && rl_point < rl_end) + { + rl_begin_undo_group (); + + rl_delete (1, c); +#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); + } + else +#endif + _rl_insert_char (1, c); + if (count == 0) + rl_backward_char (1, c); + + rl_end_undo_group (); + } + return (0); +} + +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 ' */ + + return (rl_vi_change_to (count, 'c')); +} + +int +rl_vi_overstrike (count, key) + int count, key; +{ + if (_rl_vi_doing_insert == 0) + { + _rl_vi_doing_insert = 1; + rl_begin_undo_group (); + } + + if (count > 0) + { + _rl_overwrite_char (count, key); + vi_replace_count += count; + } + + return (0); +} + +int +rl_vi_overstrike_delete (count, key) + int count, key; +{ + int i, s; + + for (i = 0; i < count; i++) + { + if (vi_replace_count == 0) + { + rl_ding (); + break; + } + s = rl_point; + + if (rl_do_undo ()) + vi_replace_count--; + + if (rl_point == s) + rl_backward_char (1, key); + } + + if (vi_replace_count == 0 && _rl_vi_doing_insert) + { + rl_end_undo_group (); + rl_do_undo (); + _rl_vi_doing_insert = 0; + } + return (0); +} + +int +rl_vi_replace (count, key) + int count, key; +{ + int i; + + vi_replace_count = 0; + + if (!vi_replace_map) + { + vi_replace_map = rl_make_bare_keymap (); + + for (i = ' '; i < KEYMAP_SIZE; i++) + vi_replace_map[i].function = rl_vi_overstrike; + + vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete; + vi_replace_map[ESC].function = rl_vi_movement_mode; + vi_replace_map[RETURN].function = rl_newline; + vi_replace_map[NEWLINE].function = rl_newline; + + /* If the normal vi insertion keymap has ^H bound to erase, do the + same here. Probably should remove the assignment to RUBOUT up + there, but I don't think it will make a difference in real life. */ + if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC && + vi_insertion_keymap[CTRL ('H')].function == rl_rubout) + vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + + } + _rl_keymap = vi_replace_map; + return (0); +} + +#if 0 +/* Try to complete the word we are standing on or the word that ends with + the previous character. A space matches everything. Word delimiters are + space and ;. */ +int +rl_vi_possible_completions() +{ + int save_pos = rl_point; + + if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') + { + while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' && + rl_line_buffer[rl_point] != ';') + rl_point++; + } + else if (rl_line_buffer[rl_point - 1] == ';') + { + rl_ding (); + return (0); + } + + rl_possible_completions (); + rl_point = save_pos; + + return (0); +} +#endif + +/* Functions to save and restore marks. */ +int +rl_vi_set_mark (count, key) + int count, key; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch < 'a' || ch > 'z') + { + rl_ding (); + return -1; + } + ch -= 'a'; + vi_mark_chars[ch] = rl_point; + return 0; +} + +int +rl_vi_goto_mark (count, key) + int count, key; +{ + int ch; + + RL_SETSTATE(RL_STATE_MOREINPUT); + ch = rl_read_key (); + RL_UNSETSTATE(RL_STATE_MOREINPUT); + + if (ch == '`') + { + rl_point = rl_mark; + return 0; + } + else if (ch < 'a' || ch > 'z') + { + rl_ding (); + return -1; + } + + ch -= 'a'; + if (vi_mark_chars[ch] == -1) + { + rl_ding (); + return -1; + } + rl_point = vi_mark_chars[ch]; + return 0; +} + +#endif /* VI_MODE */ diff --git a/readline-4.3/xmalloc.c b/readline-4.3/xmalloc.c new file mode 100644 index 0000000..8985d34 --- /dev/null +++ b/readline-4.3/xmalloc.c @@ -0,0 +1,88 @@ +/* xmalloc.c -- safe versions of malloc and realloc */ + +/* Copyright (C) 1991 Free Software Foundation, Inc. + + This file is part of GNU Readline, a library for reading lines + of text with interactive input and history editing. + + Readline 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. + + Readline 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 Readline; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#define READLINE_LIBRARY + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include "xmalloc.h" + +/* **************************************************************** */ +/* */ +/* Memory Allocation and Deallocation. */ +/* */ +/* **************************************************************** */ + +static void +memory_error_and_abort (fname) + char *fname; +{ + fprintf (stderr, "%s: out of virtual memory\n", fname); + exit (2); +} + +/* Return a pointer to free()able block of memory large enough + to hold BYTES number of bytes. If the memory cannot be allocated, + print an error message and abort. */ +PTR_T +xmalloc (bytes) + size_t bytes; +{ + PTR_T temp; + + temp = malloc (bytes); + if (temp == 0) + memory_error_and_abort ("xmalloc"); + return (temp); +} + +PTR_T +xrealloc (pointer, bytes) + PTR_T pointer; + size_t bytes; +{ + PTR_T temp; + + temp = pointer ? realloc (pointer, bytes) : malloc (bytes); + + if (temp == 0) + memory_error_and_abort ("xrealloc"); + return (temp); +} + +/* Use this as the function to call when adding unwind protects so we + don't need to know what free() returns. */ +void +xfree (string) + PTR_T string; +{ + if (string) + free (string); +} diff --git a/readline-4.3/xmalloc.h b/readline-4.3/xmalloc.h new file mode 100644 index 0000000..9cb08ba --- /dev/null +++ b/readline-4.3/xmalloc.h @@ -0,0 +1,46 @@ +/* xmalloc.h -- memory allocation that aborts on errors. */ + +/* Copyright (C) 1999 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. + + The GNU Readline Library 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. + + The GNU Readline Library 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. + + The GNU General Public License is often shipped with GNU software, and + 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. */ + +#if !defined (_XMALLOC_H_) +#define _XMALLOC_H_ + +#if defined (READLINE_LIBRARY) +# include "rlstdc.h" +#else +# include +#endif + +#ifndef PTR_T + +#ifdef __STDC__ +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* !PTR_T */ + +extern PTR_T xmalloc PARAMS((size_t)); +extern PTR_T xrealloc PARAMS((void *, size_t)); +extern void xfree PARAMS((void *)); + +#endif /* _XMALLOC_H_ */ diff --git a/readline-doc-4.3/MANIFEST.doc b/readline-doc-4.3/MANIFEST.doc new file mode 100644 index 0000000..47041b3 --- /dev/null +++ b/readline-doc-4.3/MANIFEST.doc @@ -0,0 +1,21 @@ +# +# Master Manifest file for documentation-only distribution +# +doc d +MANIFEST.doc f +doc/readline.ps f +doc/history.ps f +doc/rluserman.ps f +doc/readline.dvi f +doc/history.dvi f +doc/rluserman.dvi f +doc/readline.info f +doc/history.info f +doc/rluserman.info f +doc/readline.html f +doc/history.html f +doc/rluserman.html f +doc/readline.0 f +doc/history.0 f +doc/readline_3.ps f +doc/history_3.ps f diff --git a/readline-doc-4.3/doc/history.0 b/readline-doc-4.3/doc/history.0 new file mode 100644 index 0000000..324c363 --- /dev/null +++ b/readline-doc-4.3/doc/history.0 @@ -0,0 +1,660 @@ + + + +HISTORY(3) HISTORY(3) + + +NNAAMMEE + history - GNU History Library + +CCOOPPYYRRIIGGHHTT + The GNU History Library is Copyright (C) 1989-2002 by the + Free Software Foundation, Inc. + +DDEESSCCRRIIPPTTIIOONN + Many programs read input from the user a line at a time. + The GNU History library is able to keep track of those + lines, associate arbitrary data with each line, and uti- + lize information from previous lines in composing new + ones. + + +HHIISSTTOORRYY EEXXPPAANNSSIIOONN + The history library supports a history expansion feature + that is identical to the history expansion in bbaasshh.. This + section describes what syntax features are available. + + 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 cur- + rent input line, or fix errors in previous commands + quickly. + + History expansion is usually performed immediately after a + complete line is read. It takes place in two parts. The + first is to determine which line from the history list to + use during substitution. The second is to select portions + of that line for inclusion into the current one. The line + selected from the history is the _e_v_e_n_t, and the portions + of that line that are acted upon are _w_o_r_d_s. Various _m_o_d_i_- + _f_i_e_r_s are available to manipulate the selected words. The + line is broken into words in the same fashion as bbaasshh does + when reading input, so that several words that would oth- + erwise be separated are considered one word when sur- + rounded by quotes (see the description of hhiissttoorryy__ttookk-- + eenniizzee(()) below). History expansions are introduced by the + appearance of the history expansion character, which is !! + by default. Only backslash (\\) and single quotes can + quote the history expansion character. + + EEvveenntt DDeessiiggnnaattoorrss + An event designator is a reference to a command line entry + in the history list. + + !! Start a history substitution, except when followed + by a bbllaannkk, newline, = or (. + !!_n Refer to command line _n. + !!--_n Refer to the current command line minus _n. + !!!! Refer to the previous command. This is a synonym + for `!-1'. + + + + +GNU History 4.3 2002 January 31 1 + + + + + +HISTORY(3) HISTORY(3) + + + !!_s_t_r_i_n_g + Refer to the most recent command starting with + _s_t_r_i_n_g. + !!??_s_t_r_i_n_g[[??]] + Refer to the most recent command containing _s_t_r_i_n_g. + The trailing ?? may be omitted if _s_t_r_i_n_g is followed + immediately by a newline. + ^^_s_t_r_i_n_g_1^^_s_t_r_i_n_g_2^^ + Quick substitution. Repeat the last command, + replacing _s_t_r_i_n_g_1 with _s_t_r_i_n_g_2. Equivalent to + ``!!:s/_s_t_r_i_n_g_1/_s_t_r_i_n_g_2/'' (see MMooddiiffiieerrss below). + !!## The entire command line typed so far. + + WWoorrdd DDeessiiggnnaattoorrss + Word designators are used to select desired words from the + event. A :: separates the event specification from the + word designator. It may be omitted if the word designator + begins with a ^^, $$, **, --, or %%. 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. + + 00 ((zzeerroo)) + The zeroth word. For the shell, this is the com- + mand word. + _n The _nth word. + ^^ The first argument. That is, word 1. + $$ The last argument. + %% The word matched by the most recent `?_s_t_r_i_n_g?' + search. + _x--_y A range of words; `-_y' abbreviates `0-_y'. + ** All of the words but the zeroth. This is a synonym + for `_1_-_$'. It is not an error to use ** if there is + just one word in the event; the empty string is + returned in that case. + xx** Abbreviates _x_-_$. + xx-- Abbreviates _x_-_$ like xx**, but omits the last word. + + If a word designator is supplied without an event specifi- + cation, the previous command is used as the event. + + MMooddiiffiieerrss + After the optional word designator, there may appear a + sequence of one or more of the following modifiers, each + preceded by a `:'. + + hh Remove a trailing file name component, leaving only + the head. + tt Remove all leading file name components, leaving + the tail. + rr Remove a trailing suffix of the form _._x_x_x, leaving + the basename. + ee Remove all but the trailing suffix. + pp Print the new command but do not execute it. + + + +GNU History 4.3 2002 January 31 2 + + + + + +HISTORY(3) HISTORY(3) + + + qq Quote the substituted words, escaping further sub- + stitutions. + xx Quote the substituted words as with qq, but break + into words at bbllaannkkss and newlines. + ss//_o_l_d//_n_e_w// + Substitute _n_e_w for the first occurrence of _o_l_d in + the event line. Any delimiter can be used in place + of /. The final delimiter is optional if it is the + last character of the event line. The delimiter + may be quoted in _o_l_d and _n_e_w with a single back- + slash. If & appears in _n_e_w, it is replaced by _o_l_d. + A single backslash will quote the &. If _o_l_d is + null, it is set to the last _o_l_d substituted, or, if + no previous history substitutions took place, the + last _s_t_r_i_n_g in a !!??_s_t_r_i_n_g[[??]] search. + && Repeat the previous substitution. + gg Cause changes to be applied over the entire event + line. This is used in conjunction with `::ss' (e.g., + `::ggss//_o_l_d//_n_e_w//') or `::&&'. If used with `::ss', any + delimiter can be used in place of /, and the final + delimiter is optional if it is the last character + of the event line. + +PPRROOGGRRAAMMMMIINNGG WWIITTHH HHIISSTTOORRYY FFUUNNCCTTIIOONNSS + This section describes how to use the History library in + other programs. + + IInnttrroodduuccttiioonn ttoo HHiissttoorryy + The programmer using the History library has available + functions for remembering lines on a history list, associ- + ating 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 _e_x_p_a_n_s_i_o_n function + is available which provides for a consistent user inter- + face 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 previ- + ous lines and using that text in new commands. The basic + history manipulation commands are identical to the history + substitution provided by bbaasshh. + + 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 edit- + ing. + + Before declaring any functions using any functionality the + History library provides in other code, an application + writer should include the file _<_r_e_a_d_l_i_n_e_/_h_i_s_t_o_r_y_._h_> in any + file that uses the History library's features. It sup- + plies extern declarations for all of the library's public + + + +GNU History 4.3 2002 January 31 3 + + + + + +HISTORY(3) HISTORY(3) + + + functions and variables, and declares all of the public + data structures. + + + HHiissttoorryy SSttoorraaggee + The history list is an array of history entries. A his- + tory entry is declared as follows: + + _t_y_p_e_d_e_f _v_o_i_d _* hhiissttddaattaa__tt;; + + typedef struct _hist_entry { + char *line; + histdata_t data; + } HIST_ENTRY; + + The history list itself might therefore be declared as + + _H_I_S_T___E_N_T_R_Y _*_* tthhee__hhiissttoorryy__lliisstt;; + + The state of the History library is encapsulated into a + single structure: + + /* + * 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; + + If the flags member includes HHSS__SSTTIIFFLLEEDD, the history has + been stifled. + +HHiissttoorryy FFuunnccttiioonnss + This section describes the calling sequence for the vari- + ous functions exported by the GNU History library. + + IInniittiiaalliizziinngg HHiissttoorryy aanndd SSttaattee MMaannaaggeemmeenntt + 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. + + _v_o_i_d uussiinngg__hhiissttoorryy (_v_o_i_d) + Begin a session in which the history functions might be + used. This initializes the interactive variables. + + _H_I_S_T_O_R_Y___S_T_A_T_E _* hhiissttoorryy__ggeett__hhiissttoorryy__ssttaattee (_v_o_i_d) + Return a structure describing the current state of the + input history. + + _v_o_i_d hhiissttoorryy__sseett__hhiissttoorryy__ssttaattee (_H_I_S_T_O_R_Y___S_T_A_T_E _*_s_t_a_t_e) + + + +GNU History 4.3 2002 January 31 4 + + + + + +HISTORY(3) HISTORY(3) + + + Set the state of the history list according to _s_t_a_t_e. + + + HHiissttoorryy LLiisstt MMaannaaggeemmeenntt + These functions manage individual entries on the history + list, or set parameters managing the list itself. + + _v_o_i_d aadddd__hhiissttoorryy (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g) + Place _s_t_r_i_n_g at the end of the history list. The associ- + ated data field (if any) is set to NNUULLLL. + + _H_I_S_T___E_N_T_R_Y _* rreemmoovvee__hhiissttoorryy (_i_n_t _w_h_i_c_h) + Remove history entry at offset _w_h_i_c_h from the history. + The removed element is returned so you can free the line, + data, and containing structure. + + _H_I_S_T___E_N_T_R_Y _* rreeppllaaccee__hhiissttoorryy__eennttrryy (_i_n_t _w_h_i_c_h_, _c_o_n_s_t _c_h_a_r + _*_l_i_n_e_, _h_i_s_t_d_a_t_a___t _d_a_t_a) + Make the history entry at offset _w_h_i_c_h have _l_i_n_e and _d_a_t_a. + This returns the old entry so you can dispose of the data. + In the case of an invalid _w_h_i_c_h, a NNUULLLL pointer is + returned. + + _v_o_i_d cclleeaarr__hhiissttoorryy (_v_o_i_d) + Clear the history list by deleting all the entries. + + _v_o_i_d ssttiiffllee__hhiissttoorryy (_i_n_t _m_a_x) + Stifle the history list, remembering only the last _m_a_x + entries. + + _i_n_t uunnssttiiffllee__hhiissttoorryy (_v_o_i_d) + Stop stifling the history. This returns the previously- + set maximum number of history entries (as set by ssttii-- + ffllee__hhiissttoorryy(())). history was stifled. The value is posi- + tive if the history was stifled, negative if it wasn't. + + _i_n_t hhiissttoorryy__iiss__ssttiifflleedd (_v_o_i_d) + Returns non-zero if the history is stifled, zero if it is + not. + + + IInnffoorrmmaattiioonn AAbboouutt tthhee HHiissttoorryy LLiisstt + These functions return information about the entire his- + tory list or individual list entries. + + _H_I_S_T___E_N_T_R_Y _*_* hhiissttoorryy__lliisstt (_v_o_i_d) + Return a NNUULLLL terminated array of _H_I_S_T___E_N_T_R_Y _* which is + the current input history. Element 0 of this list is the + beginning of time. If there is no history, return NNUULLLL. + + _i_n_t wwhheerree__hhiissttoorryy (_v_o_i_d) + Returns the offset of the current history element. + + _H_I_S_T___E_N_T_R_Y _* ccuurrrreenntt__hhiissttoorryy (_v_o_i_d) + + + +GNU History 4.3 2002 January 31 5 + + + + + +HISTORY(3) HISTORY(3) + + + Return the history entry at the current position, as + determined by wwhheerree__hhiissttoorryy(()). If there is no entry + there, return a NNUULLLL pointer. + + _H_I_S_T___E_N_T_R_Y _* hhiissttoorryy__ggeett (_i_n_t _o_f_f_s_e_t) + Return the history entry at position _o_f_f_s_e_t, starting from + hhiissttoorryy__bbaassee. If there is no entry there, or if _o_f_f_s_e_t is + greater than the history length, return a NNUULLLL pointer. + + _i_n_t hhiissttoorryy__ttoottaall__bbyytteess (_v_o_i_d) + 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. + + + MMoovviinngg AArroouunndd tthhee HHiissttoorryy LLiisstt + These functions allow the current index into the history + list to be set or changed. + + _i_n_t hhiissttoorryy__sseett__ppooss (_i_n_t _p_o_s) + Set the current history offset to _p_o_s, an absolute index + into the list. Returns 1 on success, 0 if _p_o_s is less + than zero or greater than the number of history entries. + + _H_I_S_T___E_N_T_R_Y _* pprreevviioouuss__hhiissttoorryy (_v_o_i_d) + 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 NNUULLLL pointer. + + _H_I_S_T___E_N_T_R_Y _* nneexxtt__hhiissttoorryy (_v_o_i_d) + Move the current history offset forward to the next his- + tory entry, and return the a pointer to that entry. If + there is no next entry, return a NNUULLLL pointer. + + + SSeeaarrcchhiinngg tthhee HHiissttoorryy LLiisstt + 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 his- + tory position. The search may be _a_n_c_h_o_r_e_d, meaning that + the string must match at the beginning of the history + entry. + + _i_n_t hhiissttoorryy__sseeaarrcchh (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g_, _i_n_t _d_i_r_e_c_t_i_o_n) + Search the history for _s_t_r_i_n_g, starting at the current + history offset. If _d_i_r_e_c_t_i_o_n is less than 0, then the + search is through previous entries, otherwise through sub- + sequent entries. If _s_t_r_i_n_g 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 + _s_t_r_i_n_g was found. Otherwise, nothing is changed, and a -1 + is returned. + + _i_n_t hhiissttoorryy__sseeaarrcchh__pprreeffiixx (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g_, _i_n_t + + + +GNU History 4.3 2002 January 31 6 + + + + + +HISTORY(3) HISTORY(3) + + + _d_i_r_e_c_t_i_o_n) + Search the history for _s_t_r_i_n_g, starting at the current + history offset. The search is anchored: matching lines + must begin with _s_t_r_i_n_g. If _d_i_r_e_c_t_i_o_n is less than 0, then + the search is through previous entries, otherwise through + subsequent entries. If _s_t_r_i_n_g 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. + + _i_n_t hhiissttoorryy__sseeaarrcchh__ppooss (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g_, _i_n_t _d_i_r_e_c_t_i_o_n_, + _i_n_t _p_o_s) + Search for _s_t_r_i_n_g in the history list, starting at _p_o_s, an + absolute index into the list. If _d_i_r_e_c_t_i_o_n is negative, + the search proceeds backward from _p_o_s, otherwise forward. + Returns the absolute index of the history element where + _s_t_r_i_n_g was found, or -1 otherwise. + + + MMaannaaggiinngg tthhee HHiissttoorryy FFiillee + The History library can read the history from and write it + to a file. This section documents the functions for man- + aging a history file. + + _i_n_t rreeaadd__hhiissttoorryy (_c_o_n_s_t _c_h_a_r _*_f_i_l_e_n_a_m_e) + Add the contents of _f_i_l_e_n_a_m_e to the history list, a line + at a time. If _f_i_l_e_n_a_m_e is NNUULLLL, then read from _~_/_._h_i_s_- + _t_o_r_y. Returns 0 if successful, or eerrrrnnoo if not. + + _i_n_t rreeaadd__hhiissttoorryy__rraannggee (_c_o_n_s_t _c_h_a_r _*_f_i_l_e_n_a_m_e_, _i_n_t _f_r_o_m_, + _i_n_t _t_o) + Read a range of lines from _f_i_l_e_n_a_m_e, adding them to the + history list. Start reading at line _f_r_o_m and end at _t_o. + If _f_r_o_m is zero, start at the beginning. If _t_o is less + than _f_r_o_m, then read until the end of the file. If _f_i_l_e_- + _n_a_m_e is NNUULLLL, then read from _~_/_._h_i_s_t_o_r_y. Returns 0 if + successful, or eerrrrnnoo if not. + + _i_n_t wwrriittee__hhiissttoorryy (_c_o_n_s_t _c_h_a_r _*_f_i_l_e_n_a_m_e) + Write the current history to _f_i_l_e_n_a_m_e, overwriting _f_i_l_e_- + _n_a_m_e if necessary. If _f_i_l_e_n_a_m_e is NNUULLLL, then write the + history list to _~_/_._h_i_s_t_o_r_y. Returns 0 on success, or + eerrrrnnoo on a read or write error. + + + _i_n_t aappppeenndd__hhiissttoorryy (_i_n_t _n_e_l_e_m_e_n_t_s_, _c_o_n_s_t _c_h_a_r _*_f_i_l_e_n_a_m_e) + Append the last _n_e_l_e_m_e_n_t_s of the history list to _f_i_l_e_n_a_m_e. + If _f_i_l_e_n_a_m_e is NNUULLLL, then append to _~_/_._h_i_s_t_o_r_y. Returns 0 + on success, or eerrrrnnoo on a read or write error. + + _i_n_t hhiissttoorryy__ttrruunnccaattee__ffiillee (_c_o_n_s_t _c_h_a_r _*_f_i_l_e_n_a_m_e_, _i_n_t + _n_l_i_n_e_s) + Truncate the history file _f_i_l_e_n_a_m_e, leaving only the last + _n_l_i_n_e_s lines. If _f_i_l_e_n_a_m_e is NNUULLLL, then _~_/_._h_i_s_t_o_r_y is + + + +GNU History 4.3 2002 January 31 7 + + + + + +HISTORY(3) HISTORY(3) + + + truncated. Returns 0 on success, or eerrrrnnoo on failure. + + + HHiissttoorryy EExxppaannssiioonn + These functions implement history expansion. + + _i_n_t hhiissttoorryy__eexxppaanndd (_c_h_a_r _*_s_t_r_i_n_g_, _c_h_a_r _*_*_o_u_t_p_u_t) + Expand _s_t_r_i_n_g, placing the result into _o_u_t_p_u_t, a pointer + to a string. Returns: + 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); + 1 if expansions did take place; + -1 if there was an error in expansion; + 2 if the returned line should be displayed, + but not executed, as with the ::pp modifier. + If an error ocurred in expansion, then _o_u_t_p_u_t contains a + descriptive error message. + + _c_h_a_r _* ggeett__hhiissttoorryy__eevveenntt (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g_, _i_n_t _*_c_i_n_d_e_x_, + _i_n_t _q_c_h_a_r) + Returns the text of the history event beginning at _s_t_r_i_n_g + + _*_c_i_n_d_e_x. _*_c_i_n_d_e_x is modified to point to after the + event specifier. At function entry, _c_i_n_d_e_x points to the + index into _s_t_r_i_n_g where the history event specification + begins. _q_c_h_a_r is a character that is allowed to end the + event specification in addition to the ``normal'' termi- + nating characters. + + _c_h_a_r _*_* hhiissttoorryy__ttookkeenniizzee (_c_o_n_s_t _c_h_a_r _*_s_t_r_i_n_g) + Return an array of tokens parsed out of _s_t_r_i_n_g, much as + the shell might. The tokens are split on the characters + in the hhiissttoorryy__wwoorrdd__ddeelliimmiitteerrss variable, and shell quoting + conventions are obeyed. + + _c_h_a_r _* hhiissttoorryy__aarrgg__eexxttrraacctt (_i_n_t _f_i_r_s_t_, _i_n_t _l_a_s_t_, _c_o_n_s_t + _c_h_a_r _*_s_t_r_i_n_g) + Extract a string segment consisting of the _f_i_r_s_t through + _l_a_s_t arguments present in _s_t_r_i_n_g. Arguments are split + using hhiissttoorryy__ttookkeenniizzee(()). + + + HHiissttoorryy VVaarriiaabblleess + This section describes the externally-visible variables + exported by the GNU History Library. + + _i_n_t hhiissttoorryy__bbaassee + The logical offset of the first entry in the history list. + + _i_n_t hhiissttoorryy__lleennggtthh + The number of entries currently stored in the history + list. + + + + +GNU History 4.3 2002 January 31 8 + + + + + +HISTORY(3) HISTORY(3) + + + _i_n_t hhiissttoorryy__mmaaxx__eennttrriieess + The maximum number of history entries. This must be + changed using ssttiiffllee__hhiissttoorryy(()). + + _c_h_a_r hhiissttoorryy__eexxppaannssiioonn__cchhaarr + The character that introduces a history event. The + default is !!. Setting this to 0 inhibits history expan- + sion. + + _c_h_a_r hhiissttoorryy__ssuubbsstt__cchhaarr + The character that invokes word substitution if found at + the start of a line. The default is ^^. + + _c_h_a_r hhiissttoorryy__ccoommmmeenntt__cchhaarr + 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 his- + tory expansion for the remainder of the line. This is + disabled by default. + + _c_h_a_r _* hhiissttoorryy__wwoorrdd__ddeelliimmiitteerrss + The characters that separate tokens for hhiissttoorryy__ttookk-- + eenniizzee(()). The default value is "" \\tt\\nn(())<<>>;;&&||"". + + _c_h_a_r _* hhiissttoorryy__nnoo__eexxppaanndd__cchhaarrss + The list of characters which inhibit history expansion if + found immediately following hhiissttoorryy__eexxppaannssiioonn__cchhaarr. The + default is space, tab, newline, \\rr, and ==. + + _c_h_a_r _* hhiissttoorryy__sseeaarrcchh__ddeelliimmiitteerr__cchhaarrss + The list of additional characters which can delimit a his- + tory search string, in addition to space, tab, _: and _? in + the case of a substring search. The default is empty. + + _i_n_t hhiissttoorryy__qquuootteess__iinnhhiibbiitt__eexxppaannssiioonn + If non-zero, single-quoted words are not scanned for the + history expansion character. The default value is 0. + + _r_l___l_i_n_e_b_u_f___f_u_n_c___t _* hhiissttoorryy__iinnhhiibbiitt__eexxppaannssiioonn__ffuunnccttiioonn + This should be set to the address of a function that takes + two arguments: a cchhaarr ** (_s_t_r_i_n_g) and an iinntt index into + that string (_i). It should return a non-zero value if the + history expansion starting at _s_t_r_i_n_g_[_i_] should not be per- + formed; zero if the expansion should be done. It is + intended for use by applications like bbaasshh that use the + history expansion character for additional purposes. By + default, this variable is set to NNUULLLL. + +FFIILLEESS + _~_/_._h_i_s_t_o_r_y + Default filename for reading and writing saved his- + tory + + + + + +GNU History 4.3 2002 January 31 9 + + + + + +HISTORY(3) HISTORY(3) + + +SSEEEE AALLSSOO + _T_h_e _G_n_u _R_e_a_d_l_i_n_e _L_i_b_r_a_r_y, Brian Fox and Chet Ramey + _T_h_e _G_n_u _H_i_s_t_o_r_y _L_i_b_r_a_r_y, Brian Fox and Chet Ramey + _b_a_s_h(1) + _r_e_a_d_l_i_n_e(3) + +AAUUTTHHOORRSS + Brian Fox, Free Software Foundation + bfox@gnu.org + + Chet Ramey, Case Western Reserve University + chet@ins.CWRU.Edu + +BBUUGG RREEPPOORRTTSS + If you find a bug in the hhiissttoorryy library, you should + report it. But first, you should make sure that it really + is a bug, and that it appears in the latest version of the + hhiissttoorryy library that you have. + + Once you have determined that a bug actually exists, mail + a bug report to _b_u_g_-_r_e_a_d_l_i_n_e@_g_n_u_._o_r_g. If you have a fix, + you are welcome to mail that as well! Suggestions and + `philosophical' bug reports may be mailed to _b_u_g_-_r_e_a_d_- + _l_i_n_e@_g_n_u_._o_r_g or posted to the Usenet newsgroup + ggnnuu..bbaasshh..bbuugg. + + Comments and bug reports concerning this manual page + should be directed to _c_h_e_t_@_i_n_s_._C_W_R_U_._E_d_u. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +GNU History 4.3 2002 January 31 10 + + diff --git a/readline-doc-4.3/doc/history.dvi b/readline-doc-4.3/doc/history.dvi new file mode 100644 index 0000000..bf7444e Binary files /dev/null and b/readline-doc-4.3/doc/history.dvi differ diff --git a/readline-doc-4.3/doc/history.html b/readline-doc-4.3/doc/history.html new file mode 100644 index 0000000..5afe15b --- /dev/null +++ b/readline-doc-4.3/doc/history.html @@ -0,0 +1,1639 @@ + + + + + +GNU History Library: + + + + + + + + + + + + +
    ' . + &t2h_anchor('', $href, $entry) . + '  ' . + $descr . + "
    ' . + $entry . + '' . $descr . + "
    + + + + +
    [Top][Contents][Index][ ? ]
    +

    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. +

    + +

    + + + + +
    1. Using History Interactively  GNU History User's Manual.
    2. Programming with GNU History  GNU History Programmer's Manual.
    A. Concept Index  Index of concepts described in this manual.
    B. Function and Variable Index  Index of externally visible functions + and variables.
    +

    + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    + +

    1. Using History Interactively

    + +

    + +This chapter describes how to use the GNU History Library interactively, +from a user's standpoint. It should be considered a user's guide. For +information on using the GNU History Library in your own programs, +see section 2. Programming with GNU History. +

    + +

    + +
    1.1 History Expansion  What it feels like using History as a user.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1 History Expansion

    + +

    + +The History library provides a history expansion feature that is similar +to the history expansion provided by 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 +event, and the portions of that line that are acted upon are +called words. Various 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 `!' by default. +

    + +

    + + + +
    1.1.1 Event Designators  How to specify which history line to use.
    1.1.2 Word Designators  Specifying which words are of interest.
    1.1.3 Modifiers  Modifying the results of substitution.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1.1 Event Designators

    + +

    + +An event designator is a reference to a command line entry in the +history list. + +

    + +

    + +
    ! +
    Start a history substitution, except when followed by a space, tab, +the end of the line, `=' or `('. +

    + +

    !n +
    Refer to command line n. +

    + +

    !-n +
    Refer to the command n lines back. +

    + +

    !! +
    Refer to the previous command. This is a synonym for `!-1'. +

    + +

    !string +
    Refer to the most recent command starting with string. +

    + +

    !?string[?] +
    Refer to the most recent command containing string. The trailing +`?' may be omitted if the string is followed immediately by +a newline. +

    + +

    ^string1^string2^ +
    Quick Substitution. Repeat the last command, replacing string1 +with string2. Equivalent to +!!:s/string1/string2/. +

    + +

    !# +
    The entire command line typed so far. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1.2 Word Designators

    + +

    + +Word designators are used to select desired words from the event. +A `:' separates the event specification from the word designator. It +may be omitted if the word designator begins with a `^', `$', +`*', `-', or `%'. 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. +

    + +For example, +

    + +

    +
    !! +
    designates the preceding command. When you type this, the preceding +command is repeated in toto. +

    + +

    !!:$ +
    designates the last argument of the preceding command. This may be +shortened to !$. +

    + +

    !fi:2 +
    designates the second argument of the most recent command starting with +the letters fi. +
    +

    + +Here are the word designators: + +

    + +
    0 (zero) +
    The 0th word. For many applications, this is the command word. +

    + +

    n +
    The nth word. +

    + +

    ^ +
    The first argument; that is, word 1. +

    + +

    $ +
    The last argument. +

    + +

    % +
    The word matched by the most recent `?string?' search. +

    + +

    x-y +
    A range of words; `-y' abbreviates `0-y'. +

    + +

    * +
    All of the words, except the 0th. This is a synonym for `1-$'. +It is not an error to use `*' if there is just one word in the event; +the empty string is returned in that case. +

    + +

    x* +
    Abbreviates `x-$' +

    + +

    x- +
    Abbreviates `x-$' like `x*', but omits the last word. +

    + +

    +

    + +If a word designator is supplied without an event specification, the +previous command is used as the event. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1.3 Modifiers

    + +

    + +After the optional word designator, you can add a sequence of one or more +of the following modifiers, each preceded by a `:'. +

    + +

    + +
    h +
    Remove a trailing pathname component, leaving only the head. +

    + +

    t +
    Remove all leading pathname components, leaving the tail. +

    + +

    r +
    Remove a trailing suffix of the form `.suffix', leaving +the basename. +

    + +

    e +
    Remove all but the trailing suffix. +

    + +

    p +
    Print the new command but do not execute it. +

    + +

    s/old/new/ +
    Substitute new for the first occurrence of old in the +event line. Any delimiter may be used in place of `/'. +The delimiter may be quoted in old and new +with a single backslash. If `&' appears in new, +it is replaced by old. A single backslash will quote +the `&'. The final delimiter is optional if it is the last +character on the input line. +

    + +

    & +
    Repeat the previous substitution. +

    + +

    g +
    Cause changes to be applied over the entire event line. Used in +conjunction with `s', as in gs/old/new/, +or with `&'. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2. Programming with GNU History

    + +

    + +This chapter describes how to interface programs that you write +with the GNU History Library. +It should be considered a technical guide. +For information on the interactive use of GNU History, see section 1. Using History Interactively. +

    + +

    + + + + + +
    2.1 Introduction to History  What is the GNU History library for?
    2.2 History Storage  How information is stored.
    2.3 History Functions  Functions that you can use.
    2.4 History Variables  Variables that control behaviour.
    2.5 History Programming Example  Example of using the GNU History Library.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.1 Introduction to History

    + +

    + +Many programs read input from the user a line at a time. The 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 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 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 <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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.2 History Storage

    + +

    + +The history list is an array of history entries. A history entry is +declared as follows: +

    + +
     
    typedef void *histdata_t;
    +
    +typedef struct _hist_entry {
    +  char *line;
    +  histdata_t data;
    +} HIST_ENTRY;
    +

    + +The history list itself might therefore be declared as +

    + +
     
    HIST_ENTRY **the_history_list;
    +

    + +The state of the History library is encapsulated into a single structure: +

    + +
     
    /*
    + * 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;
    +

    + +If the flags member includes HS_STIFLED, the history has been +stifled. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3 History Functions

    + +

    + +This section describes the calling sequence for the various functions +exported by the GNU History library. +

    + +

    + + + + + + + +
    2.3.1 Initializing History and State Management  Functions to call when you + want to use history in a + program.
    2.3.2 History List Management  Functions used to manage the list + of history entries.
    2.3.3 Information About the History List  Functions returning information about + the history list.
    2.3.4 Moving Around the History List  Functions used to change the position + in the history list.
    2.3.5 Searching the History List  Functions to search the history list + for entries containing a string.
    2.3.6 Managing the History File  Functions that read and write a file + containing the history list.
    2.3.7 History Expansion  Functions to perform csh-like history + expansion.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.1 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. +

    + + +

    +
    Function: void using_history (void) +
    Begin a session in which the history functions might be used. This +initializes the interactive variables. +
    +

    + + +

    +
    Function: HISTORY_STATE * history_get_history_state (void) +
    Return a structure describing the current state of the input history. +
    +

    + + +

    +
    Function: void history_set_history_state (HISTORY_STATE *state) +
    Set the state of the history list according to state. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.2 History List Management

    + +

    + +These functions manage individual entries on the history list, or set +parameters managing the list itself. +

    + + +

    +
    Function: void add_history (const char *string) +
    Place string at the end of the history list. The associated data +field (if any) is set to NULL. +
    +

    + + +

    +
    Function: HIST_ENTRY * remove_history (int which) +
    Remove history entry at offset which from the history. The +removed element is returned so you can free the line, data, +and containing structure. +
    +

    + + +

    +
    Function: HIST_ENTRY * replace_history_entry (int which, const char *line, histdata_t data) +
    Make the history entry at offset 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. +
    +

    + + +

    +
    Function: void clear_history (void) +
    Clear the history list by deleting all the entries. +
    +

    + + +

    +
    Function: void stifle_history (int max) +
    Stifle the history list, remembering only the last max entries. +
    +

    + + +

    +
    Function: int unstifle_history (void) +
    Stop stifling the history. This returns the previously-set +maximum number of history entries (as set by stifle_history()). +The value is positive if the history was +stifled, negative if it wasn't. +
    +

    + + +

    +
    Function: int history_is_stifled (void) +
    Returns non-zero if the history is stifled, zero if it is not. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.3 Information About the History List

    + +

    + +These functions return information about the entire history list or +individual list entries. +

    + + +

    +
    Function: HIST_ENTRY ** history_list (void) +
    Return a NULL terminated array of HIST_ENTRY * which is the +current input history. Element 0 of this list is the beginning of time. +If there is no history, return NULL. +
    +

    + + +

    +
    Function: int where_history (void) +
    Returns the offset of the current history element. +
    +

    + + +

    +
    Function: HIST_ENTRY * current_history (void) +
    Return the history entry at the current position, as determined by +where_history(). If there is no entry there, return a NULL +pointer. +
    +

    + + +

    +
    Function: HIST_ENTRY * history_get (int offset) +
    Return the history entry at position offset, starting from +history_base (see section 2.4 History Variables). +If there is no entry there, or if offset +is greater than the history length, return a NULL pointer. +
    +

    + + +

    +
    Function: 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. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.4 Moving Around the History List

    + +

    + +These functions allow the current index into the history list to be +set or changed. +

    + + +

    +
    Function: int history_set_pos (int pos) +
    Set the current history offset to pos, an absolute index +into the list. +Returns 1 on success, 0 if pos is less than zero or greater +than the number of history entries. +
    +

    + + +

    +
    Function: 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 NULL pointer. +
    +

    + + +

    +
    Function: 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 NULL pointer. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.5 Searching the History List

    + +

    + +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 anchored, +meaning that the string must match at the beginning of the history entry. + +

    + + +

    +
    Function: int history_search (const char *string, int direction) +
    Search the history for string, starting at the current history offset. +If direction is less than 0, then the search is through +previous entries, otherwise through subsequent entries. +If 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 +string was found. Otherwise, nothing is changed, and a -1 is +returned. +
    +

    + + +

    +
    Function: int history_search_prefix (const char *string, int direction) +
    Search the history for string, starting at the current history +offset. The search is anchored: matching lines must begin with +string. If direction is less than 0, then the search is +through previous entries, otherwise through subsequent entries. +If 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. +
    +

    + + +

    +
    Function: int history_search_pos (const char *string, int direction, int pos) +
    Search for string in the history list, starting at pos, an +absolute index into the list. If direction is negative, the search +proceeds backward from pos, otherwise forward. Returns the absolute +index of the history element where string was found, or -1 otherwise. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.6 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. +

    + + +

    +
    Function: int read_history (const char *filename) +
    Add the contents of filename to the history list, a line at a time. +If filename is NULL, then read from `~/.history'. +Returns 0 if successful, or errno if not. +
    +

    + + +

    +
    Function: int read_history_range (const char *filename, int from, int to) +
    Read a range of lines from filename, adding them to the history list. +Start reading at line from and end at to. +If from is zero, start at the beginning. If to is less than +from, then read until the end of the file. If filename is +NULL, then read from `~/.history'. Returns 0 if successful, +or errno if not. +
    +

    + + +

    +
    Function: int write_history (const char *filename) +
    Write the current history to filename, overwriting filename +if necessary. +If filename is NULL, then write the history list to +`~/.history'. +Returns 0 on success, or errno on a read or write error. +
    +

    + + +

    +
    Function: int append_history (int nelements, const char *filename) +
    Append the last nelements of the history list to filename. +If filename is NULL, then append to `~/.history'. +Returns 0 on success, or errno on a read or write error. +
    +

    + + +

    +
    Function: int history_truncate_file (const char *filename, int nlines) +
    Truncate the history file filename, leaving only the last +nlines lines. +If filename is NULL, then `~/.history' is truncated. +Returns 0 on success, or errno on failure. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3.7 History Expansion

    + +

    + +These functions implement history expansion. +

    + + +

    +
    Function: int history_expand (char *string, char **output) +
    Expand string, placing the result into output, a pointer +to a string (see section 1.1 History Expansion). Returns: +
    +
    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); +
    1 +
    if expansions did take place; +
    -1 +
    if there was an error in expansion; +
    2 +
    if the returned line should be displayed, but not executed, +as with the :p modifier (see section 1.1.3 Modifiers). +
    +

    + +If an error ocurred in expansion, then output contains a descriptive +error message. +

    +

    + + +

    +
    Function: char * get_history_event (const char *string, int *cindex, int qchar) +
    Returns the text of the history event beginning at string + +*cindex. *cindex is modified to point to after the event +specifier. At function entry, cindex points to the index into +string where the history event specification begins. qchar +is a character that is allowed to end the event specification in addition +to the "normal" terminating characters. +
    +

    + + +

    +
    Function: char ** history_tokenize (const char *string) +
    Return an array of tokens parsed out of string, much as the +shell might. The tokens are split on the characters in the +history_word_delimiters variable, +and shell quoting conventions are obeyed. +
    +

    + + +

    +
    Function: char * history_arg_extract (int first, int last, const char *string) +
    Extract a string segment consisting of the first through last +arguments present in string. Arguments are split using +history_tokenize. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4 History Variables

    + +

    + +This section describes the externally-visible variables exported by +the GNU History Library. +

    + + +

    +
    Variable: int history_base +
    The logical offset of the first entry in the history list. +
    +

    + + +

    +
    Variable: int history_length +
    The number of entries currently stored in the history list. +
    +

    + + +

    +
    Variable: int history_max_entries +
    The maximum number of history entries. This must be changed using +stifle_history(). +
    +

    + + +

    +
    Variable: char history_expansion_char +
    The character that introduces a history event. The default is `!'. +Setting this to 0 inhibits history expansion. +
    +

    + + +

    +
    Variable: char history_subst_char +
    The character that invokes word substitution if found at the start of +a line. The default is `^'. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: char * history_word_delimiters +
    The characters that separate tokens for history_tokenize(). +The default value is " \t\n()<>;&|". +
    +

    + + +

    +
    Variable: char * history_no_expand_chars +
    The list of characters which inhibit history expansion if found immediately +following history_expansion_char. The default is space, tab, newline, +carriage return, and `='. +
    +

    + + +

    +
    Variable: char * history_search_delimiter_chars +
    The list of additional characters which can delimit a history search +string, in addition to space, TAB, `:' and `?' in the case of +a substring search. The default is empty. +
    +

    + + +

    +
    Variable: int history_quotes_inhibit_expansion +
    If non-zero, single-quoted words are not scanned for the history expansion +character. The default value is 0. +
    +

    + + +

    +
    Variable: rl_linebuf_func_t * history_inhibit_expansion_function +
    This should be set to the address of a function that takes two arguments: +a char * (string) +and an int index into that string (i). +It should return a non-zero value if the history expansion starting at +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 NULL. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.5 History Programming Example

    + +

    + +The following program demonstrates simple use of the GNU History Library. +

    + +
     
    #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");
    +            }
    +        }
    +    }
    +}
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    A. Concept Index

    + +
    Jump to:   A +   +E +   +H +   +

    + + + + + + + + + + + + + + +
    Index Entry Section

    A
    anchored search2.3.5 Searching the History List

    E
    event designators1.1.1 Event Designators

    H
    history events1.1.1 Event Designators
    history expansion1.1 History Expansion
    History Searching2.3.5 Searching the History List

    Jump to:   A +   +E +   +H +   +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    B. Function and Variable Index

    + +
    Jump to:   A +   +C +   +G +   +H +   +N +   +P +   +R +   +S +   +U +   +W +   +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Index Entry Section

    A
    add_history2.3.2 History List Management
    append_history2.3.6 Managing the History File

    C
    clear_history2.3.2 History List Management
    current_history2.3.3 Information About the History List

    G
    get_history_event2.3.7 History Expansion

    H
    history_arg_extract2.3.7 History Expansion
    history_base2.4 History Variables
    history_comment_char2.4 History Variables
    history_expand2.3.7 History Expansion
    history_expansion_char2.4 History Variables
    history_get2.3.3 Information About the History List
    history_get_history_state2.3.1 Initializing History and State Management
    history_inhibit_expansion_function2.4 History Variables
    history_is_stifled2.3.2 History List Management
    history_length2.4 History Variables
    history_list2.3.3 Information About the History List
    history_max_entries2.4 History Variables
    history_no_expand_chars2.4 History Variables
    history_quotes_inhibit_expansion2.4 History Variables
    history_search2.3.5 Searching the History List
    history_search_delimiter_chars2.4 History Variables
    history_search_pos2.3.5 Searching the History List
    history_search_prefix2.3.5 Searching the History List
    history_set_history_state2.3.1 Initializing History and State Management
    history_set_pos2.3.4 Moving Around the History List
    history_subst_char2.4 History Variables
    history_tokenize2.3.7 History Expansion
    history_total_bytes2.3.3 Information About the History List
    history_truncate_file2.3.6 Managing the History File
    history_word_delimiters2.4 History Variables

    N
    next_history2.3.4 Moving Around the History List

    P
    previous_history2.3.4 Moving Around the History List

    R
    read_history2.3.6 Managing the History File
    read_history_range2.3.6 Managing the History File
    remove_history2.3.2 History List Management
    replace_history_entry2.3.2 History List Management

    S
    stifle_history2.3.2 History List Management

    U
    unstifle_history2.3.2 History List Management
    using_history2.3.1 Initializing History and State Management

    W
    where_history2.3.3 Information About the History List
    write_history2.3.6 Managing the History File

    Jump to:   A +   +C +   +G +   +H +   +N +   +P +   +R +   +S +   +U +   +W +   +

    + +


    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Table of Contents

    + +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Short Table of Contents

    +
    +1. Using History Interactively +
    +2. Programming with GNU History +
    +A. Concept Index +
    +B. Function and Variable Index +
    + +
    +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    About this document

    +This document was generated by Chet Ramey on June, 27 2002 +using texi2html +

    +The buttons in the navigation panels have the following meaning: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Button Name Go to From 1.2.3 go to
    + [ < ] +Back + +previous section in reading order + +1.2.2 +
    + [ > ] +Forward + +next section in reading order + +1.2.4 +
    + [ << ] +FastBack + +previous or up-and-previous section + +1.1 +
    + [ Up ] +Up + +up section + +1.2 +
    + [ >> ] +FastForward + +next or up-and-next section + +1.3 +
    + [Top] +Top + +cover (top) of document + +   +
    + [Contents] +Contents + +table of contents + +   +
    + [Index] +Index + +concept index + +   +
    + [ ? ] +About + +this page + +   +
    +

    +where the Example assumes that the current position +is at Subsubsection One-Two-Three of a document of +the following structure: +
      +
    • 1. Section One
    • +
        +
      • 1.1 Subsection One-One
      • +
          +
        • ...
        • +
        +
      • 1.2 Subsection One-Two
      • +
          +
        • 1.2.1 Subsubsection One-Two-One +
        • 1.2.2 Subsubsection One-Two-Two +
        • 1.2.3 Subsubsection One-Two-Three     +<== Current Position +
        • 1.2.4 Subsubsection One-Two-Four +
        +
      • 1.3 Subsection One-Three
      • +
          +
        • ...
        • +
        +
      • 1.4 Subsection One-Four
      • +
      +
    + +
    +
    + +This document was generated +by Chet Ramey on June, 27 2002 +using texi2html + + + diff --git a/readline-doc-4.3/doc/history.info b/readline-doc-4.3/doc/history.info new file mode 100644 index 0000000..98c0002 --- /dev/null +++ b/readline-doc-4.3/doc/history.info @@ -0,0 +1,840 @@ +This is history.info, produced by makeinfo version 4.1 from +/usr/homes/chet/src/bash/readline-src/doc/hist.texinfo. + +INFO-DIR-SECTION Libraries +START-INFO-DIR-ENTRY +* History: (history). The GNU history library API +END-INFO-DIR-ENTRY + + 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. + + 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. + + +File: history.info, Node: Top, Next: Using History Interactively, Up: (dir) + +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. + + +File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top + +Using History Interactively +*************************** + + This chapter describes how to use the GNU History Library +interactively, from a user's standpoint. It should be considered a +user's guide. For information on using the GNU History Library in your +own programs, *note Programming with GNU History::. + +* Menu: + +* History Interaction:: What it feels like using History as a user. + + +File: history.info, Node: History Interaction, Up: Using History Interactively + +History Expansion +================= + + The History library provides a history expansion feature that is +similar to the history expansion provided by `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 "event", and the portions of that line that are acted upon +are called "words". Various "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 `!' by default. + +* 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. + + +File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction + +Event Designators +----------------- + + An event designator is a reference to a command line entry in the +history list. + +`!' + Start a history substitution, except when followed by a space, tab, + the end of the line, `=' or `('. + +`!N' + Refer to command line N. + +`!-N' + Refer to the command N lines back. + +`!!' + Refer to the previous command. This is a synonym for `!-1'. + +`!STRING' + Refer to the most recent command starting with STRING. + +`!?STRING[?]' + Refer to the most recent command containing STRING. The trailing + `?' may be omitted if the STRING is followed immediately by a + newline. + +`^STRING1^STRING2^' + Quick Substitution. Repeat the last command, replacing STRING1 + with STRING2. Equivalent to `!!:s/STRING1/STRING2/'. + +`!#' + The entire command line typed so far. + + +File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction + +Word Designators +---------------- + + Word designators are used to select desired words from the event. A +`:' separates the event specification from the word designator. It may +be omitted if the word designator begins with a `^', `$', `*', `-', or +`%'. 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. + + For example, + +`!!' + designates the preceding command. When you type this, the + preceding command is repeated in toto. + +`!!:$' + designates the last argument of the preceding command. This may be + shortened to `!$'. + +`!fi:2' + designates the second argument of the most recent command starting + with the letters `fi'. + + Here are the word designators: + +`0 (zero)' + The `0'th word. For many applications, this is the command word. + +`N' + The Nth word. + +`^' + The first argument; that is, word 1. + +`$' + The last argument. + +`%' + The word matched by the most recent `?STRING?' search. + +`X-Y' + A range of words; `-Y' abbreviates `0-Y'. + +`*' + All of the words, except the `0'th. This is a synonym for `1-$'. + It is not an error to use `*' if there is just one word in the + event; the empty string is returned in that case. + +`X*' + Abbreviates `X-$' + +`X-' + Abbreviates `X-$' like `X*', but omits the last word. + + If a word designator is supplied without an event specification, the +previous command is used as the event. + + +File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction + +Modifiers +--------- + + After the optional word designator, you can add a sequence of one or +more of the following modifiers, each preceded by a `:'. + +`h' + Remove a trailing pathname component, leaving only the head. + +`t' + Remove all leading pathname components, leaving the tail. + +`r' + Remove a trailing suffix of the form `.SUFFIX', leaving the + basename. + +`e' + Remove all but the trailing suffix. + +`p' + Print the new command but do not execute it. + +`s/OLD/NEW/' + Substitute NEW for the first occurrence of OLD in the event line. + Any delimiter may be used in place of `/'. The delimiter may be + quoted in OLD and NEW with a single backslash. If `&' appears in + NEW, it is replaced by OLD. A single backslash will quote the + `&'. The final delimiter is optional if it is the last character + on the input line. + +`&' + Repeat the previous substitution. + +`g' + Cause changes to be applied over the entire event line. Used in + conjunction with `s', as in `gs/OLD/NEW/', or with `&'. + + +File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top + +Programming with GNU History +**************************** + + This chapter describes how to interface programs that you write with +the GNU History Library. It should be considered a technical guide. +For information on the interactive use of GNU History, *note 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. + + +File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History + +Introduction to History +======================= + + Many programs read input from the user a line at a time. The 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 "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 `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 `' 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. + + +File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History + +History Storage +=============== + + The history list is an array of history entries. A history entry is +declared as follows: + + typedef void *histdata_t; + + typedef struct _hist_entry { + char *line; + histdata_t data; + } HIST_ENTRY; + + The history list itself might therefore be declared as + + HIST_ENTRY **the_history_list; + + The state of the History library is encapsulated into a single +structure: + + /* + * 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; + + If the flags member includes `HS_STIFLED', the history has been +stifled. + + +File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History + +History Functions +================= + + This section describes the calling sequence for the various functions +exported by the 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. + + +File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions + +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. + + - Function: void using_history (void) + Begin a session in which the history functions might be used. This + initializes the interactive variables. + + - Function: HISTORY_STATE * history_get_history_state (void) + Return a structure describing the current state of the input + history. + + - Function: void history_set_history_state (HISTORY_STATE *state) + Set the state of the history list according to STATE. + + +File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions + +History List Management +----------------------- + + These functions manage individual entries on the history list, or set +parameters managing the list itself. + + - Function: void add_history (const char *string) + Place STRING at the end of the history list. The associated data + field (if any) is set to `NULL'. + + - Function: HIST_ENTRY * remove_history (int which) + Remove history entry at offset WHICH from the history. The + removed element is returned so you can free the line, data, and + containing structure. + + - Function: HIST_ENTRY * replace_history_entry (int which, const char + *line, histdata_t data) + Make the history entry at offset 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. + + - Function: void clear_history (void) + Clear the history list by deleting all the entries. + + - Function: void stifle_history (int max) + Stifle the history list, remembering only the last MAX entries. + + - Function: int unstifle_history (void) + Stop stifling the history. This returns the previously-set + maximum number of history entries (as set by `stifle_history()'). + The value is positive if the history was stifled, negative if it + wasn't. + + - Function: int history_is_stifled (void) + Returns non-zero if the history is stifled, zero if it is not. + + +File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions + +Information About the History List +---------------------------------- + + These functions return information about the entire history list or +individual list entries. + + - Function: HIST_ENTRY ** history_list (void) + Return a `NULL' terminated array of `HIST_ENTRY *' which is the + current input history. Element 0 of this list is the beginning of + time. If there is no history, return `NULL'. + + - Function: int where_history (void) + Returns the offset of the current history element. + + - Function: HIST_ENTRY * current_history (void) + Return the history entry at the current position, as determined by + `where_history()'. If there is no entry there, return a `NULL' + pointer. + + - Function: HIST_ENTRY * history_get (int offset) + Return the history entry at position OFFSET, starting from + `history_base' (*note History Variables::). If there is no entry + there, or if OFFSET is greater than the history length, return a + `NULL' pointer. + + - Function: 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. + + +File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions + +Moving Around the History List +------------------------------ + + These functions allow the current index into the history list to be +set or changed. + + - Function: int history_set_pos (int pos) + Set the current history offset to POS, an absolute index into the + list. Returns 1 on success, 0 if POS is less than zero or greater + than the number of history entries. + + - Function: 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 `NULL' pointer. + + - Function: 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 `NULL' pointer. + + +File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions + +Searching the History List +-------------------------- + + 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 +"anchored", meaning that the string must match at the beginning of the +history entry. + + - Function: int history_search (const char *string, int direction) + Search the history for STRING, starting at the current history + offset. If DIRECTION is less than 0, then the search is through + previous entries, otherwise through subsequent entries. If 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 STRING was found. Otherwise, nothing is changed, and + a -1 is returned. + + - Function: int history_search_prefix (const char *string, int + direction) + Search the history for STRING, starting at the current history + offset. The search is anchored: matching lines must begin with + STRING. If DIRECTION is less than 0, then the search is through + previous entries, otherwise through subsequent entries. If 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. + + - Function: int history_search_pos (const char *string, int direction, + int pos) + Search for STRING in the history list, starting at POS, an + absolute index into the list. If DIRECTION is negative, the search + proceeds backward from POS, otherwise forward. Returns the + absolute index of the history element where STRING was found, or + -1 otherwise. + + +File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions + +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. + + - Function: int read_history (const char *filename) + Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is `NULL', then read from `~/.history'. Returns 0 if + successful, or `errno' if not. + + - Function: int read_history_range (const char *filename, int from, + int to) + Read a range of lines from FILENAME, adding them to the history + list. Start reading at line FROM and end at TO. If FROM is zero, + start at the beginning. If TO is less than FROM, then read until + the end of the file. If FILENAME is `NULL', then read from + `~/.history'. Returns 0 if successful, or `errno' if not. + + - Function: int write_history (const char *filename) + Write the current history to FILENAME, overwriting FILENAME if + necessary. If FILENAME is `NULL', then write the history list to + `~/.history'. Returns 0 on success, or `errno' on a read or write + error. + + - Function: int append_history (int nelements, const char *filename) + Append the last NELEMENTS of the history list to FILENAME. If + FILENAME is `NULL', then append to `~/.history'. Returns 0 on + success, or `errno' on a read or write error. + + - Function: int history_truncate_file (const char *filename, int + nlines) + Truncate the history file FILENAME, leaving only the last NLINES + lines. If FILENAME is `NULL', then `~/.history' is truncated. + Returns 0 on success, or `errno' on failure. + + +File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions + +History Expansion +----------------- + + These functions implement history expansion. + + - Function: int history_expand (char *string, char **output) + Expand STRING, placing the result into OUTPUT, a pointer to a + string (*note History Interaction::). Returns: + `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); + + `1' + if expansions did take place; + + `-1' + if there was an error in expansion; + + `2' + if the returned line should be displayed, but not executed, + as with the `:p' modifier (*note Modifiers::). + + If an error ocurred in expansion, then OUTPUT contains a + descriptive error message. + + - Function: char * get_history_event (const char *string, int *cindex, + int qchar) + Returns the text of the history event beginning at STRING + + *CINDEX. *CINDEX is modified to point to after the event + specifier. At function entry, CINDEX points to the index into + STRING where the history event specification begins. QCHAR is a + character that is allowed to end the event specification in + addition to the "normal" terminating characters. + + - Function: char ** history_tokenize (const char *string) + Return an array of tokens parsed out of STRING, much as the shell + might. The tokens are split on the characters in the + HISTORY_WORD_DELIMITERS variable, and shell quoting conventions + are obeyed. + + - Function: char * history_arg_extract (int first, int last, const + char *string) + Extract a string segment consisting of the FIRST through LAST + arguments present in STRING. Arguments are split using + `history_tokenize'. + + +File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History + +History Variables +================= + + This section describes the externally-visible variables exported by +the GNU History Library. + + - Variable: int history_base + The logical offset of the first entry in the history list. + + - Variable: int history_length + The number of entries currently stored in the history list. + + - Variable: int history_max_entries + The maximum number of history entries. This must be changed using + `stifle_history()'. + + - Variable: char history_expansion_char + The character that introduces a history event. The default is `!'. + Setting this to 0 inhibits history expansion. + + - Variable: char history_subst_char + The character that invokes word substitution if found at the start + of a line. The default is `^'. + + - Variable: 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. + + - Variable: char * history_word_delimiters + The characters that separate tokens for `history_tokenize()'. The + default value is `" \t\n()<>;&|"'. + + - Variable: char * history_no_expand_chars + The list of characters which inhibit history expansion if found + immediately following HISTORY_EXPANSION_CHAR. The default is + space, tab, newline, carriage return, and `='. + + - Variable: char * history_search_delimiter_chars + The list of additional characters which can delimit a history + search string, in addition to space, TAB, `:' and `?' in the case + of a substring search. The default is empty. + + - Variable: int history_quotes_inhibit_expansion + If non-zero, single-quoted words are not scanned for the history + expansion character. The default value is 0. + + - Variable: rl_linebuf_func_t * history_inhibit_expansion_function + This should be set to the address of a function that takes two + arguments: a `char *' (STRING) and an `int' index into that string + (I). It should return a non-zero value if the history expansion + starting at 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 `NULL'. + + +File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History + +History Programming Example +=========================== + + The following program demonstrates simple use of the GNU History +Library. + + #include + #include + + 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"); + } + } + } + } + + +File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top + +Concept Index +************* + +* Menu: + +* anchored search: Searching the History List. +* event designators: Event Designators. +* history events: Event Designators. +* history expansion: History Interaction. +* History Searching: Searching the History List. + + +File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top + +Function and Variable Index +*************************** + +* Menu: + +* add_history: History List Management. +* append_history: Managing the History File. +* clear_history: History List Management. +* current_history: Information About the History List. +* get_history_event: History Expansion. +* history_arg_extract: History Expansion. +* history_base: History Variables. +* history_comment_char: History Variables. +* history_expand: History Expansion. +* history_expansion_char: History Variables. +* history_get: Information About the History List. +* history_get_history_state: Initializing History and State Management. +* history_inhibit_expansion_function: History Variables. +* history_is_stifled: History List Management. +* history_length: History Variables. +* history_list: Information About the History List. +* history_max_entries: History Variables. +* history_no_expand_chars: History Variables. +* history_quotes_inhibit_expansion: History Variables. +* history_search: Searching the History List. +* history_search_delimiter_chars: History Variables. +* history_search_pos: Searching the History List. +* history_search_prefix: Searching the History List. +* history_set_history_state: Initializing History and State Management. +* history_set_pos: Moving Around the History List. +* history_subst_char: History Variables. +* history_tokenize: History Expansion. +* history_total_bytes: Information About the History List. +* history_truncate_file: Managing the History File. +* history_word_delimiters: History Variables. +* next_history: Moving Around the History List. +* previous_history: Moving Around the History List. +* read_history: Managing the History File. +* read_history_range: Managing the History File. +* remove_history: History List Management. +* replace_history_entry: History List Management. +* stifle_history: History List Management. +* unstifle_history: History List Management. +* using_history: Initializing History and State Management. +* where_history: Information About the History List. +* write_history: Managing the History File. + + + +Tag Table: +Node: Top1136 +Node: Using History Interactively1716 +Node: History Interaction2223 +Node: Event Designators3642 +Node: Word Designators4569 +Node: Modifiers6198 +Node: Programming with GNU History7336 +Node: Introduction to History8061 +Node: History Storage9746 +Node: History Functions10857 +Node: Initializing History and State Management11841 +Node: History List Management12641 +Node: Information About the History List14235 +Node: Moving Around the History List15591 +Node: Searching the History List16580 +Node: Managing the History File18498 +Node: History Expansion20304 +Node: History Variables22199 +Node: History Programming Example24766 +Node: Concept Index27488 +Node: Function and Variable Index27974 + +End Tag Table diff --git a/readline-doc-4.3/doc/history.ps b/readline-doc-4.3/doc/history.ps new file mode 100644 index 0000000..a35bcf4 --- /dev/null +++ b/readline-doc-4.3/doc/history.ps @@ -0,0 +1,1658 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: history.dvi +%%Pages: 20 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -D 300 -t letter -o history.ps history.dvi +%DVIPSParameters: dpi=300, compressed +%DVIPSSource: TeX output 2002.06.27:1354 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 300 300 (history.dvi) +@start +%DVIPSBitmapFont: Fa cmti10 10.95 1 +/Fa 1 47 df<127012F8A212F012E005057B840E>46 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmbxti10 14.4 1 +/Fb 1 47 df<120E123FEA7F80A212FFA21300127E123C0909798815>46 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmtt9 9 26 +/Fc 26 123 df95 D97 +D<12FCA2121CA513F8EA1DFEEA1F07EA1E03001C1380EB01C0A6EB0380001E1300EA1F0E +EA1DFCEA0CF81217809614>II<137EA2130EA5EA07CEEA0FFEEA1C3EEA +301EEA700E12E0A61270EA301EEA383E381FEFC0EA07CF12177F9614>II<13FCEA01FEEA038EEA07041300A3EA7FFE12FFEA0700ACEAFFF8A20F17 +7F9614>II<12FCA2121CA51378EA1DFEEA1F86EA1E07121CAA38FF8FE0A21317809614>I<1206 +120FA21206C7FCA4B4FCA21207ACEAFFF8A20D187C9714>I<12FCA2121CA5EBFF80A2EB +1C005B5B5BEA1DC0EA1FE0A2EA1E70EA1C38133C131C7F38FF1F80A21117809614>107 +DII +IIIII +I<1206120EA4EA7FFC12FFEA0E00A8130EA3131CEA07F8EA01F00F157F9414>II<38FE3F80A2383C1E00EA1C1CA36C5A +A3EA0630EA0770A36C5AA311107F8F14>I<38FE3F80A238700700EA380EA3EA39CEA3EA +1B6C121AA3EA1E7CA2EA0E3811107F8F14>II<38FE3F80A2381C0E005B +A2120E5BA212071330A2EA0370A25B1201A25BA3485A12730077C7FC127E123C11187F8F +14>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd cmti9 9 1 +/Fd 1 47 df<1230127812F0126005047C830C>46 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe cmr9 9 24 +/Fe 24 122 df48 D<12035AB4FC1207B3A2EA7FF80D187D +9713>I54 +D<1240EA7FFF13FEA2EA4004EA80081310A2EA00201340A21380120113005AA25A1206A2 +120EA5120410197E9813>II +I<39FFE1FFC0390E001C00AB380FFFFC380E001CAC39FFE1FFC01A1A7F991D>72 +D83 +D97 D99 D<133F1307A9EA03E7EA0C17EA180F487E127012E0A6126012706C +5AEA1C373807C7E0131A7F9915>II103 D<12FC121CA9137CEA1D87381E0380A2121CAB38FF9FF014 +1A809915>I<1218123CA212181200A612FC121CAE12FF081A80990A>I110 DII< +EAFC78EA1D9CEA1E1C1308EA1C00ABEAFF800E10808F0F>114 DI<1208A41218A21238EAFFC0EA3800A81320A41218EA1C40EA07800B177F960F>I<38 +FF0F80383C0700EA1C061304A26C5AA26C5AA3EA03A0A2EA01C0A36C5A11107F8F14> +118 D<38FE3F80383C1E00EA1C086C5AEA0F306C5A6C5A12017F1203EA0270487E1208EA +181CEA381E38FC3FC012107F8F14>120 D<38FF0F80383C0700EA1C061304A26C5AA26C +5AA3EA03A0A2EA01C0A36C5AA248C7FCA212E112E212E4127811177F8F14>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmss10 10.95 2 +/Ff 2 42 df<13E0EA01C0EA0380120713005A121EA2121C123CA212381278A3127012F0 +AE12701278A31238123CA2121C121EA27E7E13801203EA01C0EA00E00B2E7CA112>40 +D<12E012707E123C121C121E7EA27E1380A2120313C0A3120113E0AE13C01203A3138012 +07A213005AA2121E121C123C12385A5A0B2E7EA112>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg cmbx10 12 27 +/Fg 27 123 df12 D<90380FFF80137F3801FC1F +3803F03FEA07E0EA0FC0141FA7B6FCA2380FC01FB2397FF8FFF0A21C237FA220>I97 DII<49B4FC +A2EB003FAB13FE3807FFBF380FC1FF48C67E003E7F127E127CA212FCA7127C127E123E6C +5B380F81FF3907FF3FE0EA01FC1B237EA220>I<13FE3807FF80380F83C0381E01E0383E +00F0127E007C13F8147812FCB512F8A200FCC7FCA3127CA26C1318A26C1330380F80E038 +03FFC0C6130015167E951A>II<9038FE0F803903FF9FC0380F83E338 +1F01F3391E00F000003E7FA5001E5BEA1F01380F83E0380BFF80D808FEC7FC0018C8FCA2 +121C381FFFE014FC6C13FF7E001F1480397C001FC00078130F00F81307A3007CEB0F806C +EB1F00381F807E6CB45A000113E01A217F951D>II<121E123FEA7F80A4EA3F00121E +C7FCA6EAFF80A2121FB2EAFFF0A20C247EA30F>I107 DI<3AFF03F8 +03F890390FFE0FFE3A1F183F183F9039201F201F014001C01380A201801380AE3BFFF0FF +F0FFF0A22C167D9531>I<38FF03F0EB0FFC381F187EEB203EEB403FA21380AE39FFF1FF +E0A21B167D9520>I<13FF000713E0380F81F0381F00F8003E137C48133EA300FC133FA7 +007C133E007E137E003E137C6C13F8380F81F03807FFE0C6130018167E951D>I<38FF87 +F0EBBFFC381FF07EEBC01F9038800F8015C0A2EC07E0A715C0140FA2EC1F8001C01300EB +F07EEBBFFCEB8FE00180C7FCA8EAFFF0A21B207E9520>II<38FF0F80EB1FE0381F33F013631343A2EBC1E0EB8000AD +EAFFF8A214167E9518>I<3807F980EA1FFFEA3807EA7003EAF001A26CC7FCB4FC13F8EA +7FFE6C7E6C1380120738003FC0EAC007130312E0A200F0138038FC0F00EAEFFEEAC3F812 +167E9517>I<487EA41203A21207A2120F123FB5FCA2EA1F80ABEB8180A5380F830013C3 +EA07FEEA01F811207F9F16>I<38FF81FFA2381F803FAF5C5C380FC1BF3907FF3FE0EA01 +FC1B167D9520>I<39FFF01FE0A2391FC00700000F1306EBE00E0007130C13F000035BA2 +6C6C5AA26C6C5AA2EBFEE0EB7EC0137F6D5AA26DC7FCA2130EA21B167F951E>I<3AFFF3 +FF83FCA23A1F807C00E0D80FC014C08001E013010007017F1380A2D803F0EB0300ECCF83 +01F81387D801F913C61487D800FD13ECEBFF0315FC017F5BEB7E01013E5BEB3C00A20118 +136026167F9529>I<39FFF07FC0A2390FC01C006C6C5A6D5A00035B6C6C5A3800FD8013 +7F91C7FC7F6D7E497EEB37E0EB67F013C33801C1F8380380FC48487E000E137F39FF81FF +E0A21B167F951E>I<39FFF01FE0A2391FC00700000F1306EBE00E0007130C13F000035B +A26C6C5AA26C6C5AA2EBFEE0EB7EC0137F6D5AA26DC7FCA2130EA2130CA25B1278EAFC38 +13305BEA69C0EA7F80001FC8FC1B207F951E>I<387FFFF0A2387C07E038700FC0EA601F +00E0138038C03F005B137EC65A1201485AEBF030EA07E0120FEBC070EA1F80003F1360EB +00E0EA7E03B5FCA214167E9519>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh cmtt10 12 27 +/Fh 27 119 df<13E0A538F0E1E0EAFCE7387EEFC0381FFF00EA07FCEA01F0EA07FCEA1F +FF387EEFC038FCE7E0EAF0E13800E000A513157D991A>42 D<1338137CA2136C13EEA313 +C6A2EA01C7A438038380A4380701C0A213FFA24813E0EA0E00A4481370387F01FC38FF83 +FE387F01FC171E7F9D1A>65 D69 D<38FF83FEA3381C0070AA381FFFF0A3381C +0070AB38FF83FEA3171E7F9D1A>72 D +I<38FE03FE12FFA2381D8070A213C0121CA213E0A213601370A213301338A21318131CA2 +130C130EA21306A213071303A238FF81F0A21380171E7F9D1A>78 +DI82 D<3803F1C0EA0FFDEA3FFFEA7C0FEA700312E01301A390C7FC12 +701278123FEA1FF0EA07FE3800FF80EB0FC0EB01E013001470A2126012E0A214E0EAF001 +38FC03C0B5128000EF1300EAE3FC141E7D9D1A>I<387FFFFEB5FCA238E0380EA5000013 +00B33803FF80A3171E7F9D1A>I<38FF01FEA3381C00706C13E0A2380701C0A213830003 +138013C700011300A2EA00EEA2137CA21338AA48B4FCA3171E7F9D1A>89 +D<387FFFC0B512E0A26C13C013047D7E1A>95 D97 D<12FEA3120EA6133EEBFF80000F13E0EBC1F0EB8070EB0038120E14 +1CA7000F13381478EB80F0EBC1E0EBFFC0000E138038063E00161E7F9D1A>IIIII<12FEA3120EA6133EEBFF80000F13C013C1EB80E01300120EAC38FFE3 +FE13E713E3171E7F9D1A>104 DI108 +D +110 DI<387F81F838FF8F +FC387F9FFE3803FE1EEBF80CEBE000A25B5BAAEA7FFFB5FC7E17157F941A>114 +D<487E1203A6387FFFE0B5FCA238038000AA1470A43801C1E013FF6C1380EB3F00141C7F +9B1A>116 D<38FE0FE0A3EA0E00AD1301EA0F033807FFFE7EEA00FC17157F941A>I<387F +C7FC00FF13FE007F13FC380E00E0A3380701C0A338038380A33801C700A3EA00EEA3137C +A2133817157F941A>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi cmbx12 13.14 41 +/Fi 41 123 df12 +D<123C127E12FFA4127E123C08087C8711>46 D<131C133C13FC12FFA21200B3AA387FFF +FCA216237CA21F>49 D<48B4FC000713C0381E07F0383803F8386001FC387C00FE12FE14 +FF147FA2127C003813FFC7FC14FEA2EB01FC14F8EB03F0EB07E01480EB0F00131E5B1370 +EBE003EA01C038038007380700061206380FFFFE5A5A4813FCB5FCA218237DA21F>I<48 +B4FC000713E0381E03F0383801F8003C13FC387E00FEA3123EEA1C01000013FCA2EB03F8 +EB07F0EB0FC03801FF00A2380007E0EB01F014F8EB00FC14FE14FFA21210127C12FEA214 +FEA2387C01FC007013F8383E07F0380FFFC00001130018237DA21F>I<14381478A214F8 +1301130313071306130C131C13381330136013E0EA01C01380EA03005A120E5A12185A12 +705AB612C0A2390001F800A790387FFFC0A21A237EA21F>I<0018130C001F137CEBFFF8 +14F014E014C01480EBFC000018C7FCA513FF001B13E0381F03F0381C00F8000813FCC712 +7EA3147FA2127812FCA3147E5A006013FC1270383801F8381E07E03807FFC03801FE0018 +237DA21F>II<1230123C003FB512C0A2 +15804814005C5C38600018A200E05B485B5CC6485AA249C7FC1306130EA25BA2133CA25B +A213F8A41201A66C5A13601A257DA41F>I<141CA2143EA3147FA24A7EA39038019FC0A2 +9038031FE0140F01077FEB0607A2010C7F1403011C7FEB1801A2496C7EA2017FB5FCA290 +39E0007F8049133FA2484880151F00038190C7120FA2486E7ED8FFF090B51280A229257E +A42E>65 D68 +DII72 DI76 D +I<01FF1380000713E3380F80F7381E001F48130F481307140312F81401A27E91C7FCB4FC +EA7FE013FE383FFFE014F86C13FE00077F6C1480C67E010313C0EB003FEC0FE01407A200 +C01303A315C07E6C13076C14806CEB0F0038FFC03E38E3FFF838803FE01B257DA422>83 +D87 +D97 +DIII<137F3803FFC03807C1F0380F80F8EA1F0048137C127E147E +12FEA2B512FEA248C7FCA3127EA214067E6C130C380F80183807E0703803FFE038007F80 +17187E971C>II<3901FF07C00007EBDFE0380F83F1EA1F01393E00F800 +007E7FA6003E5B6C485A380F83E0EBFFC0001190C7FC0030C8FCA21238123C383FFFE06C +13FC806C7F481480383C003F48EB0FC000F81307A4007CEB0F806CEB1F00381F807E3807 +FFF8C613C01B247E971F>II<120FEA1F80EA3FC0A4EA1F80EA0F00 +C7FCA7EA7FC0A2120FB3A2EAFFF8A20D277EA611>I108 D<26FF80FE137F903A83FF81FFC03B0F8E0FC707E0019813CC903A9007E8 +03F001A013F0A201C013E0AF3BFFFC7FFE3FFFA230187E9733>I<38FF80FE903883FF80 +390F8E0FC0139890389007E013A0A213C0AF39FFFC7FFEA21F187E9722>II<38FFC1FCEBCFFF390FFC1FC09038F0 +07E001C013F0140315F8140115FCA8EC03F8A215F0EBE0079038F00FE09038DC1F809038 +CFFF00EBC3F801C0C7FCA9EAFFFCA21E237F9722>I<38FF83E0EB8FF8380F8C7CEB90FC +13B013A01478EBE0005BAEEAFFFEA216187F9719>114 D<3807F8C0EA1FFFEA3C07EA70 +01EAF000A300FC1300B47EEA7FFC7F383FFF80000F13C0120338001FE01303EAC001A212 +E014C0EAF00338FC078038EFFF00EAC3FC13187E9718>I<13C0A41201A312031207120F +121FB512C0A2380FC000AC1460A63807E0C013E13801FF8038007E0013237FA218>I<39 +FFC07FE0A2000F1307B0140FA200071317EBE0673903FFC7FE38007F071F187E9722>I< +39FFF80FF8A2390FC001C015803907E00300A26D5A00031306EBF80E0001130C13FC0000 +5B13FEEB7E30A26D5AA214E06D5AA26D5AA26DC7FCA21D187F9720>I<39FFF83FF0A239 +0FC00F003807E00E6C6C5A6D5A6C6C5A00001360EB7EC06D5AA2131F6D7E497E80EB33F8 +1361EBE0FC3801C07E3803807F3907003F8048131F39FFC07FF8A21D187F9720>120 +D<39FFF80FF8A2390FC001C015803907E00300A26D5A00031306EBF80E0001130C13FC00 +005B13FEEB7E30A26D5AA214E06D5AA26D5AA26DC7FCA21306A25B1230EA781CEAFC185B +1370EA68E0EA7FC0001FC8FC1D237F9720>I<387FFFF8A2387C03F0EA700738600FE000 +E013C0EB1F80EAC03F1400137EEA00FE5B485A0003130C13F0EA07E0120FEBC01C381F80 +18003F1338387F0078387E01F8B5FCA216187E971B>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj cmsl10 10.95 30 +/Fj 30 122 df<903803F07C90381E0DC69038380F0FEB701E01E0130EEC0C003801C01C +A548485A007FB512C03903803800A448485AA6000E5BA648485A001E7F38FF8FFC20207E +9F1B>11 DI<903803F03F9039 +1E09E0809039380F80C09039701F01E0EBE03E021E13C02601C01CC7FCA548485A007FB6 +12803903803803A43A0700700700A6000EEBE00EA64848485A001EEBE01E3AFF8FF8FFC0 +23207E9F26>14 D<13201360A4383061C0383C4380380E4E00EA0778EA01E0A2EA07B8EA +1C9CEA708FEAE083EA0180A490C7FC12147AA117>42 D<13181338EA01F8EA0E701200A5 +13E0A6EA01C0A6EA0380A6EA07001380EAFFFC0E1E7B9D17>49 DI<13 +FFEA01FE1380A5EA0300A61206A65AA65AA65AA65AA6B4FCA2102D7EA10D>91 +D<13FFEA01FEEA0006A5130CA61318A61330A61360A613C0A6EA0180A6EAFF00A2102D82 +A10D>93 D97 D<13FEEA0383380E0780121C00 +38130090C7FC12785AA45AA37E5BEA70026C5AEA1C18EA07E011147D9314>99 +D<1438EB01F8EB00781438A21470A614E013FCEA0382EA0601121CEA3C00383801C01278 +12F0A438E00380A412F0EA700738380F00381C37803807C7E015207D9F19>I<13F8EA07 +0EEA0E07381C038012381278127012F0B5FC00F0C7FCA25AA46C5AEA7002EA3004EA1C18 +EA07E011147D9314>II<140EEB3E11EBE1A33801C1C238 +0381E0EA07801301120FA3380703C01480EB8700EA04FC48C7FCA21218121CEA0FFF14C0 +14E0381800F04813305A5AA3006013606C13C0381C0700EA07FC181F809417>I<13E012 +0712011200A2485AA6485AEB8F80EB90E013A0EBC0601380000713E01300A5380E01C0A6 +381C0380001E13C038FF8FF014207E9F19>II<13E0120712011200 +A2EA01C0A6EA0380A6EA0700A6120EA65A121EEAFF800B207F9F0C>108 +D<390387C07C391F9861863907A072073903C03403EB80380007EB7807EB0070A5000EEB +E00EA64848485A001EEBE01E3AFFCFFCFFC022147E9326>I<38038F80381F90E0EA07A0 +3803C0601380000713E01300A5380E01C0A6381C0380001E13C038FF8FF014147E9319> +I<13FCEA0387380E0180381C00C04813E0A24813F012F0A438E001E0A214C0130300F013 +8038700700EA380E6C5AEA07E014147D9317>IIIII<1380EA0100 +A35A5A5A121EEAFFF8EA0E00A45AA65A1310A41320A2EA1840EA0F800D1C7C9B12>I<38 +1C0380EAFC1FEA3C07EA1C03A238380700A6EA700EA4131EA25BEA305E381F9F8011147B +9319>I<38FF83F8381E00E0001C13C01480121E380E01005B13025B12075BA25BEA0390 +13A013E05B5B120190C7FC15147C9318>I<39FF9FE1FC393C078070391C030060148015 +401580EA0E0790380D81001309EB19C21311380F21C4EA0720EB40C814E8EB80F0A26C48 +5A1460000213401E147C9321>I<381FF0FF3803C0780001137014403800E0C0EBE180EB +73001376133CA2131C132E134E1387EA0107380203801204380C01C0383C03E038FE07FC +18147F9318>I<390FF83F803901E00E00EBC00C140813E000005B143014205C13705CA2 +0171C7FC1339133A133E133C133813181310A25BA25BEA70C0EAF08000F1C8FC12E61278 +191D809318>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk cmcsc10 10.95 3 +/Fk 3 118 df103 +D<38FC01FC381E007014201217EA1380A2EA11C0EA10E0A213701338A2131C130E1307A2 +EB03A0EB01E0A213001460123800FE132016177E961C>110 D<38FF81FC381C00701420 +B0000C1340120E6C138038018300EA007C16177E961C>117 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl cmbx12 17.28 36 +/Fl 36 122 df49 DI<1578A215FCA34A7E +A24A7EA24A7FA34A7FEC0E7F021E7FEC1C3FA202387F151F02787FEC700FA202E07F1507 +010180ECC003A249486C7EA201078191C7FC498191B6FCA24981011CC7123F013C810138 +141FA24981160F01F081491407A2484881486C1403B549B512FCA336317DB03D>65 +DI<913A03FF800180023F +EBF00349B5EAFC0701079038003F0FD91FF8EB079FD93FC0EB01FFD9FF807F4848C8127F +4848153F0007161F49150F485A001F1607A2485A1703127FA24992C7FCA212FFA9127FA2 +7FEF0380123FA26C7E1707000F17006C7E6D150E0003161E6C6C151C6C6C6C1478D93FC0 +5CD91FF8EB03E0D907FFEB3F800101D9FFFEC7FCD9003F13F80203138031317CB03A>I< +B812E0A3C6903880007FEE0FF016031601A21600A21770A31738A21507A21700A35D5D5D +91B5FCA3EC803F818181A592C8FCACB612C0A32D317EB033>70 DIII78 +D80 +D<007FB8FCA39039C00FF801D87E00EC003F007C82007882A200708200F01780A3481603 +A5C792C7FCB3AA017FB6FCA331307DAF38>84 DII97 DIIIII<90391FF007C09039FFFE3F +E03A01F83F79F03907E00FC3000F14E19039C007E0E0001FECF000A2003F80A5001F5CA2 +000F5CEBE00F00075C2603F83FC7FC3806FFFE380E1FF090C9FC121EA2121F7F90B57E6C +14F015FC6C806C801680000F15C0003FC7127F007EEC1FE0007C140F00FC1407A4007EEC +0FC0003E1580003F141FD80FC0EB7E003907F803FC0001B512F0D8001F90C7FC242F7E9F +28>III108 D<2703F007F8EB1FE000FFD93FFEEBFFF8913A783F01 +E0FC02C090388300FE280FF1801FC6137F2607F30013CC01F602F8148001FC5CA3495CB3 +B500C3B5380FFFFCA33E207D9F43>I<3903F007F800FFEB3FFEEC783F02C013803A0FF1 +801FC03807F30001F614E013FCA35BB3B500C3B5FCA328207D9F2D>II<3901F83FE000FFEBFFFC9038FBE07F9039FF00 +3F80D80FFEEB1FC06C48EB0FE04914F0ED07F8A216FC1503A216FEA816FC1507A216F8A2 +ED0FF06D14E06DEB1FC06DEB3F809039FBC0FE009038F8FFF8EC3FC091C8FCABB512C0A3 +272E7E9F2D>I<3803F03F00FFEB7FC09038F1C3E01487390FF30FF0EA07F6A29038FC07 +E0EC03C091C7FCA25BB2B512E0A31C207E9F21>114 D<3801FF86000713FEEA1F00003C +133E48131E140E12F8A36C90C7FCB47E13FC387FFFC06C13F0806C7F00077F00017FEA00 +3F01001380143F0060131F00E0130FA27E15007E6C131E6C131C38FF807838F3FFF038C0 +7F8019207D9F20>I<131CA5133CA3137CA213FC120112031207381FFFFEB5FCA2D803FC +C7FCB0EC0380A71201EC0700EA00FEEB7F0EEB3FFCEB07F0192E7FAD1F>IIII<3A7FFF807FFCA33A03FC000F006C6C131E6C6C5BEC803890387FC078013F5B90 +381FE1E090380FF3C0ECFF806D90C7FC6D5A13016D7E81815B903803DFE09038078FF081 +90380F07FC90381E03FEEB3C01496C7E4914804848EB7FC00003EC3FE026FFFC01B5FCA3 +28207F9F2B>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm cmsy10 10.95 1 +/Fm 1 14 df<14FE903807FFC090381F01F0903878003C01E0130ED80180130348C7EA01 +800006EC00C0481560A2481530481518A248150CA4481506A90060150CA46C1518A26C15 +306C1560A26C15C06CEC01806C6CEB0300D800E0130E0178133C90381F01F0903807FFC0 +D900FEC7FC272B7DA02E>13 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn cmbx12 14.4 44 +/Fn 44 122 df<123C127FEAFF80A213C0A3127F123E1200A2EA0180A3EA0300A2120612 +0E5A5A12100A157B8813>44 D<121C127FA2EAFF80A3EA7F00A2121C09097B8813>46 +D<130E131E137EEA07FE12FFA212F81200B3ABB512FEA317277BA622>49 +DII<140FA25C5C5C5C5BA2EB03 +BFEB073F130E131C133C1338137013E0EA01C0EA038012071300120E5A5A5A12F0B612F8 +A3C7EA7F00A890381FFFF8A31D277EA622>I<00181303381F801FEBFFFE5C5C5C14C091 +C7FC001CC8FCA7EB7FC0381DFFF8381F80FC381E003F1208C7EA1F8015C0A215E0A21218 +127C12FEA315C05A0078EB3F80A26CEB7F00381F01FE6CB45A000313F0C613801B277DA6 +22>I65 DI<91387FE003903907FFFC07011FEBFF0F90397FF0 +0F9F9039FF0001FFD801FC7F4848147F4848143F4848141F485A160F485A1607127FA290 +C9FC5AA97E7F1607123FA26C7E160E6C7E6C6C141C6C6C143C6C6C14786CB4EB01F09039 +7FF007C0011FB512800107EBFE009038007FF028297CA831>I69 +DI<91387FE003903907 +FFFC07011FEBFF0F90397FF00F9F9039FF0001FFD801FC7F484880484880484880485A82 +485A82127FA290CAFC5AA892B512F87E7F03001300123FA26C7EA26C7E6C7E6C7E6C7E6C +B45B90387FF007011FB5129F0107EBFE0F9039007FF0032D297CA835>III78 D80 D82 D<9038FF80600003EBF0E0 +000F13F8381F80FD383F001F003E1307481303A200FC1301A214007EA26C140013C0EA7F +FCEBFFE06C13F86C13FE80000714806C14C0C6FC010F13E0EB007FEC1FF0140F140700E0 +1303A46C14E0A26C13076C14C0B4EB0F80EBE03F39E3FFFE0000E15B38C01FF01C297CA8 +25>I85 +DII<3803FF80000F13F0381F01FC383F80FE147F801580EA1F00C7FCA4EB3FFF3801 +FC3FEA0FE0EA1F80EA3F00127E5AA4145F007E13DF393F839FFC381FFE0F3803FC031E1B +7E9A21>97 DIIIII<9038FF80F000 +03EBE3F8390FC1FE1C391F007C7C48137E003EEB3E10007EEB3F00A6003E133E003F137E +6C137C380FC1F8380BFFE00018138090C8FC1238A2123C383FFFF814FF6C14C06C14E06C +14F0121F383C0007007CEB01F8481300A4007CEB01F0A2003FEB07E0390FC01F806CB512 +0038007FF01E287E9A22>II<1207EA0F80EA1FC0EA3FE0 +A3EA1FC0EA0F80EA0700C7FCA7EAFFE0A3120FB3A3EAFFFEA30F2B7EAA12>I108 D<26FFC07FEB1FC0903AC1FFC07FF0903AC307E0 +C1F8D80FC49038F101FC9039C803F20001D801FE7F01D05BA201E05BB03CFFFE3FFF8FFF +E0A3331B7D9A38>I<38FFC07E9038C1FF809038C30FC0D80FC413E0EBC80701D813F013 +D0A213E0B039FFFE3FFFA3201B7D9A25>II<38FFE1FE9038EFFF809038FE +0FE0390FF803F09038F001F801E013FC140015FEA2157FA8157E15FEA215FC140101F013 +F89038F807F09038FC0FE09038EFFF809038E1FC0001E0C7FCA9EAFFFEA320277E9A25> +I<38FFC1F0EBC7FCEBC63E380FCC7F13D813D0A2EBF03EEBE000B0B5FCA3181B7F9A1B> +114 D<3803FE30380FFFF0EA3E03EA7800127000F01370A27E00FE1300EAFFE06CB4FC14 +C06C13E06C13F0000713F8C6FCEB07FC130000E0137C143C7E14387E6C137038FF01E038 +E7FFC000C11300161B7E9A1B>I<13E0A41201A31203A21207120F381FFFE0B5FCA2380F +E000AD1470A73807F0E0000313C03801FF8038007F0014267FA51A>I<39FFE07FF0A300 +0F1307B2140FA2000713173903F067FF3801FFC738007F87201B7D9A25>I<39FFFC03FF +A3390FF000F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0E +A2149EEB3F9C14FC6D5AA26D5AA36D5AA26D5AA2201B7F9A23>I<3BFFFC7FFC1FFCA33B +0FE00FE001C02607F007EB0380A201F8EBF00700031600EC0FF801FC5C0001150EEC1FFC +2600FE1C5B15FE9039FF387E3C017F1438EC787F6D486C5A16F0ECE01F011F5CA26D486C +5AA2EC800701075CA22E1B7F9A31>I<39FFFC1FFEA33907F003803803F8079038FC0F00 +3801FE1E00005BEB7F3814F86D5A6D5A130F806D7E130F497EEB3CFEEB38FFEB787F9038 +F03F803901E01FC0D803C013E0EB800F39FFF03FFFA3201B7F9A23>I<39FFFC03FFA339 +0FF000F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0EA214 +9EEB3F9C14FC6D5AA26D5AA36D5AA26D5AA25CA21307003890C7FCEA7C0FEAFE0E131E13 +1C5BEA74F0EA3FE0EA0F8020277F9A23>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo cmtt10 10.95 76 +/Fo 76 127 df<127012F8B012701200A5127012F8A31270051C779B18>33 +DI +I<13C01201A3EA03F0EA0FFCEA3FFEEA7DCFEA71C738E1C38013C7A338F1C0001279123F +6C7EEA0FF8EA01FC13DE13CF13C73861C38012F1A212E1EBC7001271EA79DEEA3FFEEA1F +F8EA07E0EA01C0A3120011247D9F18>III<1238127CA2127E +123E120EA3121CA2123812F812F012C0070E789B18>I<137013F0EA01E0EA03C0EA0780 +EA0F00121E121C5AA25AA45AA81270A47EA27E121E7EEA0780EA03C0EA01F0120013700C +24799F18>I<126012F012787E7E7EEA07801203EA01C0A2EA00E0A41370A813E0A4EA01 +C0A2EA03801207EA0F00121E5A5A5A12600C247C9F18>II<136013F0A7387FFFC0B512E0A26C13C03800F000A7136013147E9718>I<121C +123E127E127F123F121F1207120E121E127C12F81260080C788518>I<387FFFC0B512E0 +A26C13C013047E8F18>I<1230127812FCA2127812300606778518>I<1303EB0780A2130F +14005B131EA2133E133C137C1378A213F85B12015B12035BA212075B120F90C7FCA25A12 +1E123E123CA2127C127812F85AA2126011247D9F18>IIII<131F5B1377A213E7120113C7EA038712 +071307120E121E123C1238127812F0B512F8A338000700A6EB7FF0A3151C7F9B18>52 +D<137E48B4FC00071380380F83C0EA1E03121C3838018090C7FC5AA2EAE1F8EAE7FEB5FC +38FE078038F803C0EAF001EB00E05AA21270A3383801C0EA3C03381E0780380FFF006C5A +EA01F8131C7E9B18>54 D<1230127812FCA2127812301200A81230127812FCA212781230 +0614779318>58 D<1218123C127EA2123C12181200A81218123C127EA2123E121E120E12 +1C123C127812F01260071A789318>I<14C0EB03E01307EB1FC0EB3F80EBFE00485AEA07 +F0485AEA3F8048C7FC12FCA2127F6C7EEA0FE06C7EEA01FC6C7EEB3F80EB1FC0EB07E013 +03EB00C013187E9918>I<387FFFC0B512E0A26C13C0C8FCA4387FFFC0B512E0A26C13C0 +130C7E9318>I<126012F87E127F6C7EEA0FE06C7EEA01FC6C7EEB3F80EB1FC0EB07E0A2 +EB1FC0EB3F80EBFE00485AEA07F0485AEA3F8048C7FC12FC5A126013187E9918>II<137013F8A213D8A2EA01DCA3138CEA038EA4EA0707 +A5380FFF80A3EA0E03381C01C0A3387F07F000FF13F8007F13F0151C7F9B18>65 +D68 DII<387F07F038FF +8FF8387F07F0381C01C0A9EA1FFFA3EA1C01AA387F07F038FF8FF8387F07F0151C7F9B18 +>72 DI76 D<387E07F038FF0FF8387F07F0381D81C0 +A313C1121CA213E1A313611371A213311339A31319A2131D130DA3EA7F07EAFF87EA7F03 +151C7F9B18>78 DII< +EA7FF8EAFFFE6C7E381C0F80130314C01301A313031480130F381FFF005BA2EA1C0F7FEB +0380A5149CA3387F01F8EAFF81387F00F0161C7F9B18>82 D<3803F1C0EA1FFF5AEA7C0F +EA7003EAE001A390C7FC12701278123FEA1FF0EA07FEC67EEB0F80EB03C01301EB00E0A2 +126012E0130100F013C038F80780B5FCEBFE00EAE7F8131C7E9B18>I<387FFFF8B5FCA2 +38E07038A400001300B2EA07FFA3151C7F9B18>I<38FF83FEA3381C0070B36C13E0EA0F +01380783C03803FF806C1300EA007C171C809B18>I<38FE03F8EAFF07EAFE03381C01C0 +EA1E03000E1380EA0F0700071300A2EA038EA2EA01DCA3EA00F8A21370A9EA01FC487E6C +5A151C7F9B18>89 D91 +D<126012F0A27E1278127C123CA2123E121E121F7EA27F12077F1203A27F12017F12007F +1378A2137C133C133E131EA2131F7F14801307A2EB030011247D9F18>III<387FFFC0B512E0A26C13C013047E7F18>I<1206121E123E12381270A212E0A312F8 +12FC127CA21238070E789E18>II<127E +12FE127E120EA5133EEBFF80000F13C0EBC1E01380EB0070120E1438A6000F1370A2EB80 +E013C1EBFFC0000E138038063E00151C809B18>II< +EB1F80133F131F1303A5EA03E3EA0FFBEA1FFFEA3C1FEA380FEA7007130312E0A6EA7007 +A2EA380FEA3C1F381FFFF0380FFBF83803E3F0151C7E9B18>III<3801E1F03807FFF85A381E1E30381C0E00 +487EA5EA1C0EEA1E1EEA1FFC5BEA39E00038C7FC7EEA1FFEEBFFC04813E0387801F03870 +0070481338A4007813F0EA7E03381FFFC06C13803801FC00151F7F9318>I<127E12FE12 +7E120EA5133EEBFF80000F13C013C1EB80E01300120EAB387FC7FC38FFE7FE387FC7FC17 +1C809B18>II<127E12FE127E120EA5EB3FF0A3EB0780EB0F00131E5B5B5BEA0FF87F139C130EEA +0E0F7FEB038014C0387FC7F812FF127F151C7F9B18>107 DI<38F9C1C038FFF7F013FF383E3E38EA3C3CA2EA3838AB38FE3E3EEB7E +7EEB3E3E1714809318>IIII<3801F380EA07FB +EA1FFFEA3E1FEA380FEA7007A2EAE003A6EA7007A2EA380FEA3C1FEA1FFFEA0FFBEA03E3 +EA0003A7EB1FF0EB3FF8EB1FF0151E7E9318>I<38FF0FC0EB3FE0EB7FF0EA07F0EBE060 +EBC0005BA290C7FCA9EAFFFC7F5B14147E9318>II<487E1203A4387FFFC0B5FCA238038000A9144014E0A33801C1C013FF6C +1380EB3E0013197F9818>I<387E07E0EAFE0FEA7E07EA0E00AC1301EA0F033807FFFC6C +13FE3801FCFC1714809318>I<387F8FF000FF13F8007F13F0381C01C0380E0380A33807 +0700A3138FEA038EA3EA01DCA3EA00F8A2137015147F9318>I<38FF07F8138F13073838 +00E0A4381C01C0137113F9A213D9EA1DDD000D1380A3138DEA0F8FA23807070015147F93 +18>I<387F8FF0139F138F380F0700EA078EEA039EEA01DC13F81200137013F07FEA01DC +EA039E138EEA0707000E1380387F8FF000FF13F8007F13F015147F9318>I<387F8FF000 +FF13F8007F13F0380E01C0EB0380A21207EB0700A2EA0387A2138EEA01CEA213CC120013 +DC1378A31370A313F05B1279EA7BC0EA7F806CC7FC121E151E7F9318>I<383FFFF05AA2 +387001E0EB03C0EB078038000F00131E5B13F8485AEA03C0485A380F0070121E5A5AB512 +F0A314147F9318>II<126012F0B3B012600424769F18>I<127CB4FC +13C01203C67EAB7FEB7FC0EB3FE0A2EB7FC0EBF0005BABEA03C012FF90C7FC127C13247E +9F18>II +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fp cmr10 10.95 74 +/Fp 74 123 df<90381F83E09038F06E303901C07878380380F8903800F03048EB7000A7 +B612803907007000B2383FE3FF1D20809F1B>11 D<133FEBE0C0EA01C0380381E0EA0701 +A290C7FCA6B512E0EA0700B2383FC3FC1620809F19>II<90381F81F89038F04F043901C07C063903 +80F80FEB00F05A0270C7FCA6B7FC3907007007B23A3FE3FE3FE02320809F26>I34 +D<127012F812FCA212741204A31208A21210A212201240060E7C9F0D>39 +D<13401380EA01005A12061204120C5AA212381230A212701260A412E0AC1260A4127012 +30A212381218A27E120412067E7EEA008013400A2E7BA112>I<7E12407E12307E120812 +0C7EA212077EA213801201A413C0AC1380A412031300A25A1206A25A120812185A12205A +5A0A2E7EA112>I<127012F012F8A212781208A31210A31220A21240050E7C840D>44 +DI<127012F8A3127005057C840D>I48 D<13801203120F12F31203B3A6EA07C0EA7FFE0F1E7C9D17>III<1306A2130EA2131E132EA2134E138EA2EA010E1202A212041208A212101220A2 +124012C0B512F038000E00A7EBFFE0141E7F9D17>II<137CEA0182EA0701380E0380EA0C07121838 +38030090C7FC12781270A2EAF1F0EAF21CEAF406EAF807EB0380A200F013C0A51270A214 +801238EB07001218EA0C0E6C5AEA01F0121F7E9D17>I<1240387FFFE014C0A238400080 +38800100A21302485AA25B5BA25BA21360A213E05B1201A41203A76C5A131F7E9D17>I< +EA03F0EA0C0CEA1006EA3003382001801260A3127038780300123EEA3F06EA1FC8EA0FF0 +EA03F8487EEA0C7EEA103F38300F80EA6007EB01C012C01300A31480EA600100201300EA +1002EA0C0CEA03F0121F7E9D17>II<127012F8A312701200AA127012F8A3127005147C93 +0D>I<127012F8A312701200AA127012F012F8A212781208A31210A31220A21240051D7C +930D>I<5B497EA3497EA3EB09E0A3EB10F0A3EB2078A3497EA2EBC03EEB801EA248B5FC +EB000FA20002EB0780A348EB03C0A2120C001E14E039FF801FFE1F207F9F22>65 +DI<90380FE0109038381C30 +9038E002703803C00139078000F048C71270121E15305A1510127C127800F81400A91278 +007C1410123CA26C1420A27E6C6C13406C6C13803900E00300EB380CEB0FF01C217E9F21 +>IIII<90380FE02090 +387818609038E004E03803800238070001481300001E1460A25A1520127C127800F81400 +A7EC7FFCEC03E000781301127C123CA27EA27E7E380380023900E0046090387818209038 +0FE0001E217D9F24>I<39FFF07FF8390F000780AD90B5FCEB0007AF39FFF07FF81D1F7E +9E22>II76 DIIIIII<38 +03F040380C0CC0EA1803EA3001EA6000A212E01440A36C13007E127CEA7F80EA3FF86CB4 +FC00071380C613C0EB1FE013031301EB00F014707EA46C136014E06C13C038F8018038C6 +0300EA81FC14217E9F19>I<007FB512E038780F010060EB006000401420A200C0143000 +801410A400001400B3497E3803FFFC1C1F7E9E21>I<39FFF00FF8390F0003E0EC0080B3 +A46CEB01001380120314026C6C5A6C6C5AEB3830EB0FC01D207E9E22>I<39FFF003FE39 +1F8000F86CC7126015206C6C1340A36C6C1380A2EBE00100011400A23800F002A213F8EB +7804A26D5AA36D5AA2131F6D5AA2EB07C0A36D5AA36DC7FC1F207F9E22>I<3BFFF07FF8 +1FF03B1F000FC007C06C903907800180170015C001805C00071502EC09E013C000035DEC +19F01410D801E05CA2EC2078D800F05CA2EC403C01785CA2EC801E017C1460013C144090 +383D000F133F6D5CA2011E1307010E91C7FCA2010C7F010413022C207F9E2F>I<12FFA2 +12C0B3B3A512FFA2082D7CA10D>91 DI<12FFA21203B3B3A512FFA2082D80A10D>I<12 +0812101220A21240A21280A312B812FCA2127C1238060E7D9F0D>96 +DI<121C12FC121CAA137CEA1D87381E0180EB00 +C0001C13E01470A21478A6147014F014E0001E13C0381A018038198700EA107C15207E9F +19>IIII<137CEA01C6EA030F1207EA0E061300A7EAFFF0EA0E00B2EA7FE010 +20809F0E>I<14E03803E330EA0E3CEA1C1C38380E00EA780FA5EA380E6C5AEA1E38EA33 +E00020C7FCA21230A2EA3FFE381FFF8014C0383001E038600070481330A4006013606C13 +C0381C03803803FC00141F7F9417>I<121C12FC121CAA137C1386EA1D03001E1380A212 +1CAE38FF8FF014207E9F19>I<1238127CA31238C7FCA6121C12FC121CB1EAFF80091F7F +9E0C>I<13E0EA01F0A3EA00E01300A61370EA07F012001370B3A31260EAF06013C0EA61 +80EA3F000C28829E0E>I<121C12FC121CAAEB1FE0EB0780EB060013045B5B5B136013E0 +EA1DF0EA1E70EA1C38133C131C7F130F7F148014C038FF9FF014207E9F18>I<121C12FC +121CB3ABEAFF8009207F9F0C>I<391C3E03E039FCC30C30391D019018001EEBE01CA200 +1C13C0AE3AFF8FF8FF8021147E9326>IIII<3801F04038070CC0EA0E02EA1C03EA38011278127012F0A61270 +12781238EA1C03EA0C05EA0709EA01F1EA0001A8EB0FF8151D7F9318>III<1202A31206A2120EA2123EEAFFF8EA0E00AB1304A5EA07081203EA01F00E1C7F +9B12>I<381C0380EAFC1FEA1C03AE1307120CEA061B3803E3F014147E9319>I<38FF83F8 +383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8A21370A3 +132015147F9318>I<39FF9FE1FC393C078070391C030060EC8020000E1440A214C0D807 +04138014E0A239038861001471A23801D032143A143E3800E01CA2EB6018EB40081E147F +9321>I<38FF87F8381E03C0380E0180EB0300EA0702EA0384EA01C813D8EA00F0137013 +7813F8139CEA010E1202EA060738040380000C13C0003C13E038FE07FC16147F9318>I< +38FF83F8383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8 +A21370A31320A25BA3EAF080A200F1C7FC1262123C151D7F9318>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fq cmbx12 20.736 13 +/Fq 13 122 df71 DI76 +D78 +D85 D97 D<13FE12FFA412071203B04AB4 +FC021F13F0027F13FC9138FC03FE9039FFF000FF02C0EB3F8091C7EA1FC04915E0EE0FF0 +17F8A2EE07FCA317FEA917FCA3160F17F817F0161F6D15E06EEB3FC06EEB7F80D9F9E0EB +FF009039F0FC07FE91387FFFF8D9E01F13E09026C003FEC7FC2F3C7DBB36>I105 D<903801FFC0010F13F8017F13FFD9FF807F3A03FE003FE0D807F8EB0FF0 +48486D7EA248486D7E003F81A248486D7EA400FF1680A9007F1600A36C6C495AA2001F5D +6D1307000F5D6C6C495AD803FEEB3FE03A00FF80FF806DB5C7FC010F13F8010113C02926 +7DA530>111 D<3901FC03F000FFEB0FFC4AB4FC91383C3F80EC707F00079038E0FFC000 +035BEBFD80A201FFEB7F809138003F00151E92C7FC5BB3A3B512FCA422267DA528>114 +D<90383FF0383903FFFE7848EBFFF8381FC00F383F0003003E13005A157812FCA27E6C14 +0013C013FC387FFFF06C13FEECFF806C14C06C14E0000314F0C614F8011F13FCEB007FEC +07FE0070130100F01300157E7EA27E157C6C14FC6C14F890388001F09038F00FE000F9B5 +12C0D8F07F130038C01FF81F267DA526>I<130FA55BA45BA25BA25B5A5A5A001FEBFFF0 +B6FCA3000190C7FCB3153CA86C14781480017F13F090383FC1E090381FFFC06D13809038 +01FE001E377EB626>I121 D E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 75 659 a Fq(GNU)33 b(History)f(Library)p 75 709 +1800 17 v 960 757 a Fp(Edition)16 b(4.3,)e(for)h Fo(History)f(Library)g +Fp(V)l(ersion)i(4.3.)1643 811 y(Marc)o(h)e(2002)75 2467 +y Fn(Brian)23 b(F)-6 b(o)n(x,)23 b(F)-6 b(ree)23 b(Soft)n(w)n(are)f(F) +-6 b(oundation)75 2534 y(Chet)22 b(Ramey)-6 b(,)23 b(Case)e(W)-6 +b(estern)23 b(Reserv)n(e)f(Univ)n(ersit)n(y)p 75 2570 +1800 9 v eop +%%Page: 2 2 +2 1 bop 75 217 a Fp(This)21 b(do)q(cumen)o(t)g(describ)q(es)h(the)f +(GNU)f(History)g(library)l(,)j(a)d(programming)g(to)q(ol)g(that)g(pro)o +(vides)h(a)75 271 y(consisten)o(t)15 b(user)h(in)o(terface)f(for)g +(recalling)i(lines)f(of)f(previously)i(t)o(yp)q(ed)e(input.)75 +339 y(Published)i(b)o(y)f(the)f(F)l(ree)g(Soft)o(w)o(are)f(F)l +(oundation)75 394 y(59)h(T)l(emple)h(Place,)f(Suite)i(330,)75 +448 y(Boston,)d(MA)h(02111)f(USA)75 516 y(P)o(ermission)j(is)f(gran)o +(ted)g(to)f(mak)o(e)h(and)g(distribute)i(v)o(erbatim)d(copies)i(of)f +(this)h(man)o(ual)f(pro)o(vided)h(the)75 570 y(cop)o(yrigh)o(t)e +(notice)h(and)f(this)h(p)q(ermission)g(notice)g(are)f(preserv)o(ed)h +(on)f(all)h(copies.)75 638 y(P)o(ermission)c(is)h(gran)o(ted)e(to)g +(cop)o(y)h(and)g(distribute)h(mo)q(di\014ed)g(v)o(ersions)f(of)f(this)h +(man)o(ual)g(under)h(the)f(con-)75 692 y(ditions)k(for)e(v)o(erbatim)h +(cop)o(ying,)g(pro)o(vided)h(that)e(the)h(en)o(tire)h(resulting)g +(deriv)o(ed)g(w)o(ork)e(is)h(distributed)75 747 y(under)h(the)f(terms)g +(of)g(a)f(p)q(ermission)j(notice)f(iden)o(tical)h(to)e(this)g(one.)75 +814 y(P)o(ermission)i(is)g(gran)o(ted)f(to)g(cop)o(y)h(and)f +(distribute)i(translations)f(of)f(this)h(man)o(ual)g(in)o(to)f(another) +g(lan-)75 869 y(guage,)e(under)h(the)f(ab)q(o)o(v)o(e)g(conditions)i +(for)d(mo)q(di\014ed)j(v)o(ersions,)e(except)h(that)f(this)h(p)q +(ermission)g(notice)75 924 y(ma)o(y)f(b)q(e)i(stated)f(in)h(a)f +(translation)g(appro)o(v)o(ed)g(b)o(y)g(the)g(F)l(ree)h(Soft)o(w)o(are) +d(F)l(oundation.)75 2661 y(Cop)o(yrigh)o(t)301 2660 y(c)289 +2661 y Fm(\015)h Fp(1988-2002)f(F)l(ree)i(Soft)o(w)o(are)f(F)l +(oundation,)h(Inc.)p eop +%%Page: 1 3 +1 2 bop 75 -58 a Fp(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o +(ely)1007 b(1)75 149 y Fl(1)41 b(Using)26 b(History)h(In)n(teractiv)n +(ely)137 289 y Fp(This)17 b(c)o(hapter)g(describ)q(es)h(ho)o(w)e(to)g +(use)h(the)g Fk(gnu)f Fp(History)g(Library)h(in)o(teractiv)o(ely)l(,)h +(from)e(a)g(user's)75 344 y(standp)q(oin)o(t.)38 b(It)21 +b(should)h(b)q(e)g(considered)g(a)f(user's)g(guide.)38 +b(F)l(or)21 b(information)g(on)g(using)h(the)f Fk(gnu)75 +398 y Fp(History)c(Library)h(in)h(y)o(our)e(o)o(wn)g(programs,)f(see)i +(Chapter)f(2)h([Programming)e(with)i(GNU)f(History],)75 +453 y(page)e(5.)75 600 y Fn(1.1)33 b(History)22 b(Expansion)137 +704 y Fp(The)c(History)g(library)h(pro)o(vides)f(a)f(history)h +(expansion)h(feature)e(that)h(is)g(similar)h(to)e(the)h(history)75 +759 y(expansion)12 b(pro)o(vided)g(b)o(y)f Fo(csh)p Fp(.)18 +b(This)11 b(section)h(describ)q(es)g(the)g(syn)o(tax)e(used)h(to)g +(manipulate)h(the)f(history)75 814 y(information.)137 +888 y(History)k(expansions)h(in)o(tro)q(duce)h(w)o(ords)d(from)g(the)i +(history)f(list)h(in)o(to)f(the)h(input)g(stream,)e(making)75 +943 y(it)h(easy)g(to)g(rep)q(eat)g(commands,)g(insert)h(the)f(argumen)o +(ts)f(to)h(a)g(previous)h(command)f(in)o(to)g(the)g(curren)o(t)75 +998 y(input)h(line,)h(or)d(\014x)i(errors)e(in)i(previous)g(commands)f +(quic)o(kly)l(.)137 1072 y(History)j(expansion)i(tak)o(es)d(place)i(in) +h(t)o(w)o(o)d(parts.)28 b(The)19 b(\014rst)f(is)g(to)g(determine)i +(whic)o(h)f(line)h(from)75 1127 y(the)h(history)f(list)i(should)g(b)q +(e)f(used)g(during)h(substitution.)37 b(The)21 b(second)g(is)g(to)f +(select)i(p)q(ortions)e(of)75 1182 y(that)15 b(line)i(for)d(inclusion)k +(in)o(to)d(the)h(curren)o(t)f(one.)20 b(The)c(line)g(selected)h(from)e +(the)g(history)g(is)h(called)h(the)75 1237 y Fj(ev)o(en)o(t)p +Fp(,)c(and)h(the)g(p)q(ortions)g(of)f(that)g(line)i(that)e(are)g(acted) +h(up)q(on)g(are)f(called)j Fj(w)o(ords)p Fp(.)i(V)l(arious)c +Fj(mo)q(di\014ers)75 1292 y Fp(are)i(a)o(v)m(ailable)i(to)e(manipulate) +i(the)e(selected)i(w)o(ords.)23 b(The)17 b(line)h(is)f(brok)o(en)f(in)o +(to)h(w)o(ords)e(in)j(the)e(same)75 1346 y(fashion)c(that)e(Bash)i(do)q +(es,)g(so)f(that)g(sev)o(eral)g(w)o(ords)g(surrounded)h(b)o(y)f(quotes) +h(are)f(considered)h(one)g(w)o(ord.)75 1401 y(History)18 +b(expansions)h(are)g(in)o(tro)q(duced)g(b)o(y)f(the)h(app)q(earance)g +(of)f(the)g(history)h(expansion)g(c)o(haracter,)75 1456 +y(whic)o(h)d(is)g(`)p Fo(!)p Fp(')e(b)o(y)h(default.)75 +1583 y Fi(1.1.1)30 b(Ev)n(en)n(t)21 b(Designators)137 +1687 y Fp(An)16 b(ev)o(en)o(t)f(designator)g(is)g(a)g(reference)h(to)f +(a)g(command)g(line)i(en)o(try)d(in)i(the)g(history)f(list.)75 +1777 y Fo(!)216 b Fp(Start)16 b(a)g(history)h(substitution,)g(except)h +(when)f(follo)o(w)o(ed)g(b)o(y)f(a)h(space,)g(tab,)f(the)h(end)g(of)315 +1832 y(the)e(line,)i(`)p Fo(=)p Fp(')d(or)h(`)p Fo(\()p +Fp('.)75 1919 y Fo(!)p Fj(n)191 b Fp(Refer)15 b(to)f(command)h(line)i +Fj(n)p Fp(.)75 2006 y Fo(!-)p Fj(n)167 b Fp(Refer)15 +b(to)f(the)i(command)f Fj(n)g Fp(lines)i(bac)o(k.)75 +2094 y Fo(!!)192 b Fp(Refer)15 b(to)f(the)i(previous)f(command.)20 +b(This)c(is)g(a)f(synon)o(ym)g(for)f(`)p Fo(!-1)p Fp('.)75 +2181 y Fo(!)p Fj(string)102 b Fp(Refer)15 b(to)f(the)i(most)e(recen)o +(t)h(command)g(starting)g(with)g Fj(string)p Fp(.)75 +2268 y Fo(!?)p Fj(string)t Fo([?])315 2323 y Fp(Refer)h(to)g(the)h +(most)f(recen)o(t)h(command)g(con)o(taining)g Fj(string)p +Fp(.)25 b(The)17 b(trailing)g(`)p Fo(?)p Fp(')f(ma)o(y)g(b)q(e)315 +2377 y(omitted)f(if)h(the)f Fj(string)k Fp(is)d(follo)o(w)o(ed)f +(immediately)i(b)o(y)e(a)g(newline.)75 2464 y Fo(^)p +Fj(string1)t Fo(^)p Fj(string2)t Fo(^)315 2519 y Fp(Quic)o(k)i +(Substitution.)23 b(Rep)q(eat)16 b(the)g(last)f(command,)h(replacing)h +Fj(string1)i Fp(with)e Fj(string2)p Fp(.)315 2574 y(Equiv)m(alen)o(t)g +(to)d Fo(!!:s/)p Fj(string1)t Fo(/)p Fj(string2)t Fo(/)p +Fp(.)75 2661 y Fo(!#)192 b Fp(The)15 b(en)o(tire)h(command)f(line)i(t)o +(yp)q(ed)f(so)e(far.)p eop +%%Page: 2 4 +2 3 bop 75 -58 a Fp(2)1347 b(GNU)15 b(History)g(Library)75 +149 y Fi(1.1.2)30 b(W)-5 b(ord)20 b(Designators)137 247 +y Fp(W)l(ord)d(designators)g(are)g(used)h(to)f(select)h(desired)h(w)o +(ords)d(from)h(the)g(ev)o(en)o(t.)26 b(A)18 b(`)p Fo(:)p +Fp(')e(separates)h(the)75 302 y(ev)o(en)o(t)j(sp)q(eci\014cation)h +(from)e(the)h(w)o(ord)f(designator.)34 b(It)20 b(ma)o(y)f(b)q(e)h +(omitted)g(if)g(the)g(w)o(ord)f(designator)75 357 y(b)q(egins)f(with)g +(a)e(`)p Fo(^)p Fp(',)h(`)p Fo($)p Fp(',)f(`)p Fo(*)p +Fp(',)g(`)p Fo(-)p Fp(',)g(or)h(`)p Fo(\045)p Fp('.)24 +b(W)l(ords)17 b(are)g(n)o(um)o(b)q(ered)g(from)g(the)g(b)q(eginning)i +(of)e(the)g(line,)75 411 y(with)j(the)g(\014rst)f(w)o(ord)h(b)q(eing)h +(denoted)f(b)o(y)g(0)f(\(zero\).)33 b(W)l(ords)20 b(are)f(inserted)i +(in)o(to)f(the)g(curren)o(t)f(line)75 466 y(separated)c(b)o(y)g(single) +i(spaces.)137 535 y(F)l(or)e(example,)75 616 y Fo(!!)192 +b Fp(designates)18 b(the)g(preceding)i(command.)28 b(When)18 +b(y)o(ou)g(t)o(yp)q(e)g(this,)h(the)f(preceding)h(com-)315 +671 y(mand)c(is)h(rep)q(eated)g(in)g(toto.)75 752 y Fo(!!:$)144 +b Fp(designates)12 b(the)f(last)g(argumen)o(t)f(of)h(the)g(preceding)i +(command.)19 b(This)11 b(ma)o(y)g(b)q(e)h(shortened)315 +807 y(to)j Fo(!$)p Fp(.)75 887 y Fo(!fi:2)120 b Fp(designates)15 +b(the)g(second)g(argumen)o(t)f(of)g(the)h(most)f(recen)o(t)g(command)h +(starting)f(with)h(the)315 942 y(letters)g Fo(fi)p Fp(.)137 +1024 y(Here)h(are)f(the)g(w)o(ord)f(designators:)75 1105 +y Fo(0)h(\(zero\))57 b Fp(The)15 b Fo(0)p Fp(th)g(w)o(ord.)20 +b(F)l(or)14 b(man)o(y)h(applications,)h(this)g(is)g(the)f(command)g(w)o +(ord.)75 1186 y Fj(n)215 b Fp(The)15 b Fj(n)p Fp(th)h(w)o(ord.)75 +1267 y Fo(^)216 b Fp(The)15 b(\014rst)g(argumen)o(t;)f(that)h(is,)g(w)o +(ord)g(1.)75 1348 y Fo($)216 b Fp(The)15 b(last)h(argumen)o(t.)75 +1429 y Fo(\045)216 b Fp(The)15 b(w)o(ord)g(matc)o(hed)g(b)o(y)g(the)g +(most)g(recen)o(t)g(`)p Fo(?)p Fj(string)t Fo(?)p Fp(')f(searc)o(h.)75 +1510 y Fj(x)p Fo(-)p Fj(y)168 b Fp(A)15 b(range)g(of)g(w)o(ords;)f(`)p +Fo(-)p Fj(y)t Fp(')g(abbreviates)i(`)p Fo(0-)p Fj(y)t +Fp('.)75 1591 y Fo(*)216 b Fp(All)15 b(of)f(the)f(w)o(ords,)g(except)i +(the)f Fo(0)p Fp(th.)19 b(This)14 b(is)h(a)e(synon)o(ym)h(for)f(`)p +Fo(1-$)p Fp('.)18 b(It)c(is)g(not)g(an)g(error)315 1645 +y(to)g(use)h(`)p Fo(*)p Fp(')f(if)i(there)e(is)i(just)e(one)h(w)o(ord)f +(in)i(the)f(ev)o(en)o(t;)f(the)h(empt)o(y)g(string)g(is)g(returned)g +(in)315 1700 y(that)f(case.)75 1781 y Fj(x)s Fo(*)189 +b Fp(Abbreviates)16 b(`)p Fj(x)p Fo(-$)p Fp(')75 1862 +y Fj(x)p Fo(-)192 b Fp(Abbreviates)16 b(`)p Fj(x)p Fo(-$)p +Fp(')e(lik)o(e)i(`)p Fj(x)s Fo(*)p Fp(',)e(but)i(omits)f(the)g(last)g +(w)o(ord.)137 1943 y(If)i(a)g(w)o(ord)f(designator)h(is)h(supplied)h +(without)e(an)g(ev)o(en)o(t)f(sp)q(eci\014cation,)j(the)e(previous)h +(command)75 1998 y(is)e(used)f(as)g(the)h(ev)o(en)o(t.)75 +2113 y Fi(1.1.3)30 b(Mo)r(di\014ers)137 2210 y Fp(After)10 +b(the)h(optional)g(w)o(ord)e(designator,)i(y)o(ou)f(can)h(add)f(a)g +(sequence)i(of)e(one)g(or)g(more)g(of)g(the)g(follo)o(wing)75 +2265 y(mo)q(di\014ers,)16 b(eac)o(h)f(preceded)i(b)o(y)e(a)g(`)p +Fo(:)p Fp('.)75 2346 y Fo(h)216 b Fp(Remo)o(v)o(e)14 +b(a)h(trailing)h(pathname)f(comp)q(onen)o(t,)g(lea)o(ving)h(only)g(the) +f(head.)75 2427 y Fo(t)216 b Fp(Remo)o(v)o(e)14 b(all)i(leading)h +(pathname)e(comp)q(onen)o(ts,)g(lea)o(ving)h(the)f(tail.)75 +2508 y Fo(r)216 b Fp(Remo)o(v)o(e)14 b(a)h(trailing)h(su\016x)f(of)g +(the)g(form)g(`)p Fo(.)p Fj(su\016x)s Fp(',)f(lea)o(ving)i(the)f +(basename.)75 2589 y Fo(e)216 b Fp(Remo)o(v)o(e)14 b(all)i(but)g(the)f +(trailing)h(su\016x.)75 2670 y Fo(p)216 b Fp(Prin)o(t)15 +b(the)g(new)h(command)f(but)g(do)g(not)g(execute)h(it.)p +eop +%%Page: 3 5 +3 4 bop 75 -58 a Fp(Chapter)15 b(1:)k(Using)d(History)f(In)o(teractiv)o +(ely)1007 b(3)75 149 y Fo(s/)p Fj(old)r Fo(/)p Fj(new)t +Fo(/)315 204 y Fp(Substitute)17 b Fj(new)j Fp(for)c(the)h(\014rst)e(o)q +(ccurrence)j(of)e Fj(old)i Fp(in)f(the)g(ev)o(en)o(t)f(line.)25 +b(An)o(y)16 b(delimiter)315 259 y(ma)o(y)c(b)q(e)h(used)g(in)g(place)g +(of)f(`)p Fo(/)p Fp('.)18 b(The)13 b(delimiter)h(ma)o(y)e(b)q(e)h +(quoted)f(in)i Fj(old)g Fp(and)f Fj(new)k Fp(with)12 +b(a)315 314 y(single)j(bac)o(kslash.)20 b(If)15 b(`)p +Fo(&)p Fp(')e(app)q(ears)h(in)h Fj(new)p Fp(,)f(it)g(is)h(replaced)g(b) +o(y)f Fj(old)p Fp(.)20 b(A)14 b(single)i(bac)o(kslash)315 +369 y(will)j(quote)e(the)h(`)p Fo(&)p Fp('.)25 b(The)17 +b(\014nal)i(delimiter)g(is)f(optional)g(if)f(it)h(is)g(the)f(last)g(c)o +(haracter)g(on)315 423 y(the)e(input)h(line.)75 503 y +Fo(&)216 b Fp(Rep)q(eat)15 b(the)g(previous)h(substitution.)75 +583 y Fo(g)216 b Fp(Cause)19 b(c)o(hanges)h(to)e(b)q(e)i(applied)h(o)o +(v)o(er)e(the)g(en)o(tire)h(ev)o(en)o(t)f(line.)34 b(Used)20 +b(in)g(conjunction)315 638 y(with)c(`)p Fo(s)p Fp(',)d(as)i(in)h +Fo(gs/)p Fj(old)r Fo(/)p Fj(new)t Fo(/)p Fp(,)f(or)g(with)g(`)p +Fo(&)p Fp('.)p eop +%%Page: 4 6 +4 5 bop 75 -58 a Fp(4)1347 b(GNU)15 b(History)g(Library)p +eop +%%Page: 5 7 +5 6 bop 75 -58 a Fp(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(History)889 b(5)75 149 y Fl(2)41 b(Programming)28 b(with)e(GNU)i +(History)137 269 y Fp(This)17 b(c)o(hapter)f(describ)q(es)i(ho)o(w)e +(to)f(in)o(terface)i(programs)e(that)g(y)o(ou)h(write)g(with)h(the)f +Fk(gnu)g Fp(History)75 324 y(Library)l(.)24 b(It)17 b(should)g(b)q(e)g +(considered)h(a)e(tec)o(hnical)i(guide.)25 b(F)l(or)15 +b(information)i(on)f(the)h(in)o(teractiv)o(e)g(use)75 +379 y(of)e Fk(gnu)g Fp(History)l(,)g(see)g(Chapter)g(1)g([Using)g +(History)g(In)o(teractiv)o(ely],)h(page)f(1.)75 509 y +Fn(2.1)33 b(In)n(tro)r(duction)24 b(to)e(History)137 +607 y Fp(Man)o(y)11 b(programs)f(read)h(input)i(from)d(the)i(user)f(a)g +(line)i(at)e(a)g(time.)19 b(The)12 b Fk(gnu)f Fp(History)g(library)h +(is)g(able)75 661 y(to)i(k)o(eep)g(trac)o(k)g(of)g(those)g(lines,)i +(asso)q(ciate)e(arbitrary)g(data)g(with)g(eac)o(h)h(line,)h(and)e +(utilize)j(information)75 716 y(from)d(previous)i(lines)h(in)f(comp)q +(osing)g(new)f(ones.)137 784 y(The)f(programmer)f(using)h(the)g +(History)g(library)g(has)g(a)o(v)m(ailable)h(functions)g(for)e(remem)o +(b)q(ering)h(lines)75 839 y(on)c(a)g(history)h(list,)g(asso)q(ciating)g +(arbitrary)f(data)f(with)i(a)f(line,)j(remo)o(ving)d(lines)i(from)d +(the)i(list,)h(searc)o(hing)75 894 y(through)17 b(the)h(list)g(for)f(a) +h(line)h(con)o(taining)f(an)g(arbitrary)f(text)g(string,)h(and)g +(referencing)h(an)o(y)e(line)i(in)75 949 y(the)c(list)i(directly)l(.)22 +b(In)16 b(addition,)g(a)f(history)g Fj(expansion)h Fp(function)h(is)e +(a)o(v)m(ailable)i(whic)o(h)g(pro)o(vides)f(for)e(a)75 +1003 y(consisten)o(t)h(user)h(in)o(terface)f(across)g(di\013eren)o(t)g +(programs.)137 1072 y(The)f(user)h(using)f(programs)f(written)h(with)g +(the)g(History)g(library)h(has)f(the)g(b)q(ene\014t)h(of)e(a)h +(consisten)o(t)75 1126 y(user)20 b(in)o(terface)f(with)h(a)f(set)h(of)f +(w)o(ell-kno)o(wn)h(commands)g(for)e(manipulating)k(the)d(text)g(of)g +(previous)75 1181 y(lines)c(and)f(using)h(that)e(text)g(in)i(new)f +(commands.)19 b(The)14 b(basic)h(history)e(manipulation)j(commands)d +(are)75 1236 y(similar)j(to)f(the)g(history)g(substitution)h(pro)o +(vided)g(b)o(y)g Fo(csh)p Fp(.)137 1304 y(If)f(the)g(programmer)f +(desires,)h(he)g(can)g(use)g(the)g(Readline)h(library)l(,)g(whic)o(h)f +(includes)j(some)c(history)75 1359 y(manipulation)j(b)o(y)e(default,)g +(and)h(has)f(the)g(added)h(adv)m(an)o(tage)f(of)f(command)h(line)i +(editing.)137 1427 y(Before)i(declaring)i(an)o(y)d(functions)i(using)g +(an)o(y)f(functionalit)o(y)h(the)f(History)g(library)h(pro)o(vides)f +(in)75 1482 y(other)14 b(co)q(de,)h(an)f(application)i(writer)e(should) +i(include)g(the)f(\014le)g Fo()d +Fp(in)j(an)o(y)f(\014le)75 1537 y(that)d(uses)h(the)h(History)e +(library's)i(features.)18 b(It)12 b(supplies)i(extern)e(declarations)h +(for)e(all)i(of)f(the)g(library's)75 1591 y(public)17 +b(functions)f(and)g(v)m(ariables,)g(and)f(declares)h(all)g(of)f(the)h +(public)h(data)d(structures.)75 1722 y Fn(2.2)33 b(History)22 +b(Storage)137 1819 y Fp(The)16 b(history)f(list)h(is)g(an)f(arra)o(y)f +(of)g(history)i(en)o(tries.)k(A)15 b(history)g(en)o(try)g(is)h +(declared)g(as)f(follo)o(ws:)195 1885 y Fo(typedef)23 +b(void)g(*histdata_t;)195 1988 y(typedef)g(struct)g(_hist_entry)f({)243 +2040 y(char)h(*line;)243 2092 y(histdata_t)f(data;)195 +2144 y(})i(HIST_ENTRY;)137 2212 y Fp(The)16 b(history)f(list)h(itself)g +(migh)o(t)f(therefore)g(b)q(e)h(declared)g(as)195 2277 +y Fo(HIST_ENTRY)22 b(**the_history_list;)137 2345 y Fp(The)16 +b(state)e(of)h(the)g(History)g(library)h(is)g(encapsulated)g(in)o(to)f +(a)g(single)i(structure:)195 2411 y Fo(/*)219 2462 y(*)24 +b(A)f(structure)g(used)g(to)h(pass)f(around)g(the)h(current)f(state)g +(of)g(the)h(history.)219 2514 y(*/)195 2566 y(typedef)f(struct)g +(_hist_state)f({)243 2618 y(HIST_ENTRY)g(**entries;)h(/*)g(Pointer)g +(to)h(the)f(entries)g(themselves.)g(*/)243 2670 y(int)g(offset;)262 +b(/*)23 b(The)h(location)f(pointer)f(within)h(this)h(array.)f(*/)p +eop +%%Page: 6 8 +6 7 bop 75 -58 a Fp(6)1347 b(GNU)15 b(History)g(Library)243 +149 y Fo(int)23 b(length;)262 b(/*)23 b(Number)g(of)h(elements)f +(within)g(this)g(array.)g(*/)243 201 y(int)g(size;)310 +b(/*)23 b(Number)g(of)h(slots)f(allocated)g(to)g(this)h(array.)f(*/)243 +253 y(int)g(flags;)195 305 y(})h(HISTORY_STATE;)137 372 +y Fp(If)16 b(the)f(\015ags)g(mem)o(b)q(er)g(includes)j +Fo(HS_STIFLED)p Fp(,)13 b(the)i(history)h(has)f(b)q(een)h(sti\015ed.)75 +498 y Fn(2.3)33 b(History)22 b(F)-6 b(unctions)137 593 +y Fp(This)13 b(section)g(describ)q(es)h(the)e(calling)i(sequence)g(for) +e(the)g(v)m(arious)h(functions)g(exp)q(orted)f(b)o(y)h(the)f +Fk(gnu)75 648 y Fp(History)j(library)l(.)75 758 y Fi(2.3.1)30 +b(Initializing)20 b(History)h(and)f(State)g(Managemen)n(t)137 +853 y Fp(This)e(section)g(describ)q(es)h(functions)f(used)g(to)e +(initialize)21 b(and)c(manage)g(the)g(state)g(of)g(the)g(History)75 +908 y(library)f(when)g(y)o(ou)f(w)o(an)o(t)f(to)g(use)i(the)f(history)g +(functions)h(in)g(y)o(our)f(program.)1762 1021 y(F)l(unction)-1861 +b Fh(void)20 b Fg(using)p 333 1021 18 3 v 20 w(history)j +Ff(\()p Fo(void)p Ff(\))195 1075 y Fp(Begin)e(a)f(session)g(in)h(whic)o +(h)g(the)f(history)g(functions)g(migh)o(t)g(b)q(e)h(used.)34 +b(This)21 b(initializes)i(the)195 1130 y(in)o(teractiv)o(e)16 +b(v)m(ariables.)1762 1243 y(F)l(unction)-1861 b Fh(HISTORY_STATE)21 +b(*)e Fg(history)p 657 1243 V 21 w(get)p 755 1243 V 21 +w(history)p 951 1243 V 21 w(state)j Ff(\()p Fo(void)p +Ff(\))195 1298 y Fp(Return)15 b(a)g(structure)g(describing)i(the)e +(curren)o(t)g(state)f(of)h(the)g(input)i(history)l(.)1762 +1411 y(F)l(unction)-1861 b Fh(void)20 b Fg(history)p +377 1411 V 20 w(set)p 468 1411 V 21 w(history)p 664 1411 +V 21 w(state)j Ff(\()p Fo(HISTORY_STATE)13 b(*state)p +Ff(\))195 1466 y Fp(Set)i(the)h(state)e(of)h(the)g(history)g(list)h +(according)g(to)e Fj(state)p Fp(.)75 1575 y Fi(2.3.2)30 +b(History)20 b(List)h(Managemen)n(t)137 1671 y Fp(These)11 +b(functions)h(manage)e(individual)k(en)o(tries)d(on)g(the)g(history)f +(list,)i(or)f(set)f(parameters)g(managing)75 1725 y(the)15 +b(list)h(itself.)1762 1838 y(F)l(unction)-1861 b Fh(void)20 +b Fg(add)p 294 1838 V 20 w(history)j Ff(\()p Fo(const)14 +b(char)g(*string)p Ff(\))195 1893 y Fp(Place)i Fj(string)i +Fp(at)d(the)g(end)h(of)e(the)h(history)g(list.)21 b(The)15 +b(asso)q(ciated)g(data)g(\014eld)h(\(if)f(an)o(y\))f(is)i(set)f(to)195 +1948 y Fo(NULL)p Fp(.)1762 2061 y(F)l(unction)-1861 b +Fh(HIST_ENTRY)21 b(*)e Fg(remo)n(v)n(e)p 584 2061 V 20 +w(history)k Ff(\()p Fo(int)14 b(which)p Ff(\))195 2115 +y Fp(Remo)o(v)o(e)22 b(history)g(en)o(try)h(at)f(o\013set)g +Fj(whic)o(h)h Fp(from)f(the)h(history)l(.)43 b(The)23 +b(remo)o(v)o(ed)f(elemen)o(t)h(is)195 2170 y(returned)16 +b(so)e(y)o(ou)h(can)h(free)f(the)g(line,)i(data,)d(and)h(con)o(taining) +h(structure.)1762 2283 y(F)l(unction)-1861 b Fh(HIST_ENTRY)21 +b(*)e Fg(replace)p 580 2283 V 22 w(history)p 777 2283 +V 20 w(en)n(try)24 b Ff(\()p Fo(int)14 b(which,)g(const)h(char)283 +2338 y(*line,)f(histdata_t)g(data)p Ff(\))195 2393 y +Fp(Mak)o(e)f(the)h(history)g(en)o(try)f(at)g(o\013set)g +Fj(whic)o(h)i Fp(ha)o(v)o(e)e Fj(line)18 b Fp(and)c Fj(data)p +Fp(.)19 b(This)14 b(returns)g(the)g(old)g(en)o(try)195 +2448 y(so)19 b(y)o(ou)f(can)i(disp)q(ose)g(of)e(the)i(data.)30 +b(In)20 b(the)f(case)g(of)g(an)g(in)o(v)m(alid)i Fj(whic)o(h)p +Fp(,)g(a)d Fo(NULL)h Fp(p)q(oin)o(ter)g(is)195 2502 y(returned.)1762 +2615 y(F)l(unction)-1861 b Fh(void)20 b Fg(clear)p 320 +2615 V 21 w(history)j Ff(\()p Fo(void)p Ff(\))195 2670 +y Fp(Clear)15 b(the)h(history)f(list)h(b)o(y)f(deleting)i(all)f(the)f +(en)o(tries.)p eop +%%Page: 7 9 +7 8 bop 75 -58 a Fp(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(History)889 b(7)1762 149 y(F)l(unction)-1861 b Fh(void)20 +b Fg(sti\015e)p 320 149 18 3 v 21 w(history)j Ff(\()p +Fo(int)14 b(max)p Ff(\))195 204 y Fp(Sti\015e)i(the)f(history)h(list,)f +(remem)o(b)q(ering)h(only)g(the)f(last)g Fj(max)j Fp(en)o(tries.)1762 +302 y(F)l(unction)-1861 b Fh(int)20 b Fg(unsti\015e)p +358 302 V 21 w(history)i Ff(\()p Fo(void)p Ff(\))195 +357 y Fp(Stop)14 b(sti\015ing)g(the)g(history)l(.)20 +b(This)14 b(returns)f(the)h(previously-set)h(maxim)o(um)f(n)o(um)o(b)q +(er)g(of)f(history)195 411 y(en)o(tries)h(\(as)e(set)i(b)o(y)f +Fo(stifle_history\(\))p Fp(\).)k(The)c(v)m(alue)i(is)f(p)q(ositiv)o(e)g +(if)g(the)g(history)f(w)o(as)f(sti\015ed,)195 466 y(negativ)o(e)j(if)h +(it)f(w)o(asn't.)1762 564 y(F)l(unction)-1861 b Fh(int)20 +b Fg(history)p 351 564 V 20 w(is)p 409 564 V 21 w(sti\015ed)k +Ff(\()p Fo(void)p Ff(\))195 619 y Fp(Returns)15 b(non-zero)g(if)h(the)f +(history)g(is)h(sti\015ed,)g(zero)f(if)g(it)h(is)g(not.)75 +719 y Fi(2.3.3)30 b(Information)19 b(Ab)r(out)i(the)f(History)h(List) +137 811 y Fp(These)13 b(functions)h(return)f(information)g(ab)q(out)f +(the)h(en)o(tire)h(history)e(list)i(or)e(individual)k(list)e(en)o +(tries.)1762 909 y(F)l(unction)-1861 b Fh(HIST_ENTRY)21 +b(**)e Fg(history)p 605 909 V 21 w(list)24 b Ff(\()p +Fo(void)p Ff(\))195 964 y Fp(Return)15 b(a)g Fo(NULL)f +Fp(terminated)i(arra)o(y)e(of)h Fo(HIST_ENTRY)f(*)h Fp(whic)o(h)h(is)f +(the)h(curren)o(t)f(input)h(history)l(.)195 1018 y(Elemen)o(t)g(0)f(of) +f(this)i(list)g(is)g(the)f(b)q(eginning)i(of)e(time.)20 +b(If)c(there)f(is)h(no)f(history)l(,)g(return)g Fo(NULL)p +Fp(.)1762 1116 y(F)l(unction)-1861 b Fh(int)20 b Fg(where)p +325 1116 V 20 w(history)j Ff(\()p Fo(void)p Ff(\))195 +1171 y Fp(Returns)15 b(the)g(o\013set)f(of)h(the)g(curren)o(t)g +(history)g(elemen)o(t.)1762 1268 y(F)l(unction)-1861 +b Fh(HIST_ENTRY)21 b(*)e Fg(curren)n(t)p 587 1268 V 21 +w(history)k Ff(\()p Fo(void)p Ff(\))195 1323 y Fp(Return)12 +b(the)h(history)f(en)o(try)g(at)g(the)g(curren)o(t)h(p)q(osition,)g(as) +f(determined)i(b)o(y)e Fo(where_history\(\))p Fp(.)195 +1378 y(If)j(there)h(is)f(no)h(en)o(try)e(there,)h(return)g(a)g +Fo(NULL)g Fp(p)q(oin)o(ter.)1762 1475 y(F)l(unction)-1861 +b Fh(HIST_ENTRY)21 b(*)e Fg(history)p 579 1475 V 21 w(get)j +Ff(\()p Fo(int)15 b(offset)p Ff(\))195 1530 y Fp(Return)20 +b(the)h(history)g(en)o(try)f(at)h(p)q(osition)g Fj(o\013set)p +Fp(,)g(starting)f(from)g Fo(history_base)f Fp(\(see)i(Sec-)195 +1585 y(tion)15 b(2.4)f([History)g(V)l(ariables],)h(page)g(10\).)j(If)d +(there)g(is)g(no)g(en)o(try)f(there,)h(or)f(if)h Fj(o\013set)g +Fp(is)g(greater)195 1640 y(than)g(the)g(history)g(length,)h(return)f(a) +g Fo(NULL)g Fp(p)q(oin)o(ter.)1762 1737 y(F)l(unction)-1861 +b Fh(int)20 b Fg(history)p 351 1737 V 20 w(total)p 487 +1737 V 22 w(b)n(ytes)j Ff(\()p Fo(void)p Ff(\))195 1792 +y Fp(Return)13 b(the)h(n)o(um)o(b)q(er)g(of)g(b)o(ytes)f(that)g(the)h +(primary)g(history)g(en)o(tries)g(are)g(using.)20 b(This)14 +b(function)195 1847 y(returns)h(the)g(sum)h(of)e(the)i(lengths)f(of)g +(all)h(the)g(lines)g(in)g(the)g(history)l(.)75 1947 y +Fi(2.3.4)30 b(Mo)n(ving)21 b(Around)f(the)h(History)g(List)137 +2040 y Fp(These)16 b(functions)g(allo)o(w)f(the)g(curren)o(t)h(index)g +(in)o(to)f(the)h(history)f(list)h(to)e(b)q(e)i(set)f(or)g(c)o(hanged.) +1762 2137 y(F)l(unction)-1861 b Fh(int)20 b Fg(history)p +351 2137 V 20 w(set)p 442 2137 V 21 w(p)r(os)h Ff(\()p +Fo(int)15 b(pos)p Ff(\))195 2192 y Fp(Set)j(the)h(curren)o(t)f(history) +g(o\013set)g(to)f Fj(p)q(os)p Fp(,)i(an)f(absolute)h(index)h(in)o(to)e +(the)g(list.)30 b(Returns)18 b(1)g(on)195 2247 y(success,)d(0)g(if)h +Fj(p)q(os)h Fp(is)f(less)g(than)f(zero)g(or)g(greater)f(than)h(the)g(n) +o(um)o(b)q(er)h(of)e(history)i(en)o(tries.)1762 2344 +y(F)l(unction)-1861 b Fh(HIST_ENTRY)21 b(*)e Fg(previous)p +615 2344 V 20 w(history)k Ff(\()p Fo(void)p Ff(\))195 +2399 y Fp(Bac)o(k)14 b(up)h(the)g(curren)o(t)f(history)g(o\013set)g(to) +f(the)i(previous)g(history)f(en)o(try)l(,)g(and)h(return)f(a)g(p)q(oin) +o(ter)195 2454 y(to)h(that)f(en)o(try)l(.)20 b(If)15 +b(there)g(is)h(no)f(previous)h(en)o(try)l(,)f(return)g(a)g +Fo(NULL)g Fp(p)q(oin)o(ter.)1762 2552 y(F)l(unction)-1861 +b Fh(HIST_ENTRY)21 b(*)e Fg(next)p 514 2552 V 21 w(history)k +Ff(\()p Fo(void)p Ff(\))195 2606 y Fp(Mo)o(v)o(e)17 b(the)h(curren)o(t) +f(history)h(o\013set)f(forw)o(ard)f(to)h(the)h(next)g(history)g(en)o +(try)l(,)g(and)g(return)f(the)h(a)195 2661 y(p)q(oin)o(ter)e(to)e(that) +h(en)o(try)l(.)k(If)d(there)f(is)h(no)f(next)g(en)o(try)l(,)g(return)g +(a)g Fo(NULL)g Fp(p)q(oin)o(ter.)p eop +%%Page: 8 10 +8 9 bop 75 -58 a Fp(8)1347 b(GNU)15 b(History)g(Library)75 +149 y Fi(2.3.5)30 b(Searc)n(hing)21 b(the)f(History)h(List)137 +245 y Fp(These)14 b(functions)g(allo)o(w)g(searc)o(hing)g(of)e(the)i +(history)f(list)h(for)f(en)o(tries)h(con)o(taining)g(a)f(sp)q(eci\014c) +i(string.)75 300 y(Searc)o(hing)f(ma)o(y)g(b)q(e)g(p)q(erformed)g(b)q +(oth)g(forw)o(ard)e(and)i(bac)o(kw)o(ard)f(from)g(the)h(curren)o(t)g +(history)f(p)q(osition.)75 355 y(The)j(searc)o(h)f(ma)o(y)g(b)q(e)i +Fj(anc)o(hored)p Fp(,)e(meaning)h(that)f(the)h(string)g(m)o(ust)f(matc) +o(h)g(at)g(the)h(b)q(eginning)i(of)d(the)75 410 y(history)g(en)o(try)l +(.)1762 524 y(F)l(unction)-1861 b Fh(int)20 b Fg(history)p +351 524 18 3 v 20 w(searc)n(h)j Ff(\()p Fo(const)14 b(char)h(*string,)f +(int)h(direction)p Ff(\))195 578 y Fp(Searc)o(h)g(the)f(history)g(for)g +Fj(string)p Fp(,)g(starting)g(at)g(the)h(curren)o(t)f(history)g +(o\013set.)19 b(If)c Fj(direction)g Fp(is)g(less)195 +633 y(than)20 b(0,)g(then)h(the)f(searc)o(h)f(is)i(through)f(previous)g +(en)o(tries,)i(otherwise)e(through)f(subsequen)o(t)195 +688 y(en)o(tries.)h(If)c Fj(string)j Fp(is)d(found,)f(then)g(the)h +(curren)o(t)f(history)g(index)h(is)g(set)f(to)g(that)f(history)h(en)o +(try)l(,)195 743 y(and)i(the)g(v)m(alue)h(returned)f(is)g(the)g +(o\013set)e(in)j(the)f(line)h(of)e(the)h(en)o(try)g(where)g +Fj(string)j Fp(w)o(as)c(found.)195 798 y(Otherwise,)g(nothing)f(is)h(c) +o(hanged,)f(and)h(a)e(-1)h(is)h(returned.)1762 912 y(F)l(unction)-1861 +b Fh(int)20 b Fg(history)p 351 912 V 20 w(searc)n(h)p +527 912 V 21 w(pre\014x)i Ff(\()p Fo(const)14 b(char)h(*string,)f(int)h +(direction)p Ff(\))195 966 y Fp(Searc)o(h)20 b(the)h(history)f(for)g +Fj(string)p Fp(,)h(starting)e(at)h(the)g(curren)o(t)h(history)f +(o\013set.)34 b(The)20 b(searc)o(h)g(is)195 1021 y(anc)o(hored:)g(matc) +o(hing)14 b(lines)j(m)o(ust)d(b)q(egin)i(with)f Fj(string)p +Fp(.)20 b(If)15 b Fj(direction)h Fp(is)f(less)g(than)g(0,)f(then)h(the) +195 1076 y(searc)o(h)g(is)i(through)e(previous)h(en)o(tries,)g +(otherwise)g(through)f(subsequen)o(t)h(en)o(tries.)22 +b(If)16 b Fj(string)j Fp(is)195 1131 y(found,)e(then)g(the)f(curren)o +(t)h(history)f(index)i(is)f(set)f(to)g(that)g(en)o(try)l(,)g(and)h(the) +f(return)h(v)m(alue)h(is)f(0.)195 1186 y(Otherwise,)f(nothing)f(is)h(c) +o(hanged,)f(and)h(a)e(-1)h(is)h(returned.)1762 1300 y(F)l(unction)-1861 +b Fh(int)20 b Fg(history)p 351 1300 V 20 w(searc)n(h)p +527 1300 V 21 w(p)r(os)h Ff(\()p Fo(const)14 b(char)h(*string,)f(int)h +(direction,)f(int)283 1355 y(pos)p Ff(\))195 1409 y Fp(Searc)o(h)j(for) +g Fj(string)k Fp(in)d(the)f(history)g(list,)h(starting)e(at)h +Fj(p)q(os)p Fp(,)g(an)g(absolute)h(index)g(in)o(to)f(the)h(list.)195 +1464 y(If)g Fj(direction)i Fp(is)e(negativ)o(e,)h(the)f(searc)o(h)g +(pro)q(ceeds)g(bac)o(kw)o(ard)g(from)f Fj(p)q(os)p Fp(,)h(otherwise)h +(forw)o(ard.)195 1519 y(Returns)j(the)g(absolute)g(index)h(of)f(the)g +(history)g(elemen)o(t)h(where)f Fj(string)k Fp(w)o(as)21 +b(found,)j(or)d(-1)195 1574 y(otherwise.)75 1684 y Fi(2.3.6)30 +b(Managing)20 b(the)g(History)h(File)137 1780 y Fp(The)16 +b(History)g(library)h(can)e(read)h(the)g(history)g(from)f(and)h(write)g +(it)g(to)f(a)h(\014le.)22 b(This)17 b(section)f(do)q(cu-)75 +1835 y(men)o(ts)f(the)g(functions)h(for)f(managing)g(a)g(history)g +(\014le.)1762 1949 y(F)l(unction)-1861 b Fh(int)20 b +Fg(read)p 286 1949 V 20 w(history)i Ff(\()p Fo(const)15 +b(char)f(*filename)p Ff(\))195 2003 y Fp(Add)h(the)g(con)o(ten)o(ts)f +(of)h Fj(\014lename)j Fp(to)c(the)h(history)g(list,)g(a)g(line)h(at)f +(a)f(time.)20 b(If)15 b Fj(\014lename)k Fp(is)c Fo(NULL)p +Fp(,)195 2058 y(then)h(read)f(from)f(`)p Fo(~/.history)p +Fp('.)k(Returns)d(0)f(if)i(successful,)g(or)f Fo(errno)f +Fp(if)i(not.)1762 2172 y(F)l(unction)-1861 b Fh(int)20 +b Fg(read)p 286 2172 V 20 w(history)p 481 2172 V 20 w(range)i +Ff(\()p Fo(const)14 b(char)h(*filename,)f(int)h(from,)f(int)h(to)p +Ff(\))195 2227 y Fp(Read)f(a)f(range)h(of)f(lines)j(from)d +Fj(\014lename)p Fp(,)i(adding)g(them)f(to)f(the)h(history)g(list.)20 +b(Start)13 b(reading)i(at)195 2282 y(line)g Fj(from)d +Fp(and)h(end)h(at)f Fj(to)p Fp(.)18 b(If)c Fj(from)e +Fp(is)i(zero,)f(start)f(at)g(the)h(b)q(eginning.)22 b(If)13 +b Fj(to)i Fp(is)e(less)h(than)f Fj(from)p Fp(,)195 2337 +y(then)i(read)g(un)o(til)i(the)e(end)g(of)g(the)g(\014le.)21 +b(If)15 b Fj(\014lename)k Fp(is)d Fo(NULL)p Fp(,)e(then)h(read)g(from)f +(`)p Fo(~/.history)p Fp('.)195 2392 y(Returns)h(0)g(if)g(successful,)h +(or)f Fo(errno)g Fp(if)g(not.)1762 2506 y(F)l(unction)-1861 +b Fh(int)20 b Fg(write)p 304 2506 V 22 w(history)i Ff(\()p +Fo(const)15 b(char)f(*filename)p Ff(\))195 2560 y Fp(W)l(rite)k(the)f +(curren)o(t)g(history)h(to)f Fj(\014lename)p Fp(,)h(o)o(v)o(erwriting)f +Fj(\014lename)k Fp(if)d(necessary)l(.)27 b(If)18 b Fj(\014lename)195 +2615 y Fp(is)f Fo(NULL)p Fp(,)e(then)h(write)h(the)f(history)g(list)h +(to)e(`)p Fo(~/.history)p Fp('.)21 b(Returns)16 b(0)f(on)h(success,)h +(or)f Fo(errno)195 2670 y Fp(on)f(a)g(read)g(or)g(write)g(error.)p +eop +%%Page: 9 11 +9 10 bop 75 -58 a Fp(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(History)889 b(9)1762 149 y(F)l(unction)-1861 b Fh(int)20 +b Fg(app)r(end)p 360 149 18 3 v 19 w(history)j Ff(\()p +Fo(int)14 b(nelements,)g(const)h(char)f(*filename)p Ff(\))195 +204 y Fp(App)q(end)19 b(the)e(last)g Fj(nelemen)o(ts)k +Fp(of)16 b(the)i(history)f(list)h(to)f Fj(\014lename)p +Fp(.)27 b(If)18 b Fj(\014lename)j Fp(is)d Fo(NULL)p Fp(,)f(then)195 +259 y(app)q(end)f(to)f(`)p Fo(~/.history)p Fp('.)j(Returns)c(0)h(on)g +(success,)h(or)e Fo(errno)h Fp(on)g(a)g(read)g(or)g(write)g(error.)1762 +404 y(F)l(unction)-1861 b Fh(int)20 b Fg(history)p 351 +404 V 20 w(truncate)p 582 404 V 21 w(\014le)k Ff(\()p +Fo(const)14 b(char)h(*filename,)e(int)i(nlines)p Ff(\))195 +459 y Fp(T)l(runcate)k(the)h(history)f(\014le)h Fj(\014lename)p +Fp(,)h(lea)o(ving)f(only)g(the)f(last)g Fj(nlines)k Fp(lines.)34 +b(If)20 b Fj(\014lename)i Fp(is)195 513 y Fo(NULL)p Fp(,)14 +b(then)i(`)p Fo(~/.history)p Fp(')d(is)j(truncated.)j(Returns)c(0)g(on) +g(success,)h(or)e Fo(errno)h Fp(on)g(failure.)75 644 +y Fi(2.3.7)30 b(History)20 b(Expansion)137 750 y Fp(These)c(functions)g +(implemen)o(t)g(history)f(expansion.)1762 895 y(F)l(unction)-1861 +b Fh(int)20 b Fg(history)p 351 895 V 20 w(expand)j Ff(\()p +Fo(char)14 b(*string,)g(char)h(**output)p Ff(\))195 949 +y Fp(Expand)j Fj(string)p Fp(,)f(placing)h(the)g(result)f(in)o(to)g +Fj(output)p Fp(,)h(a)e(p)q(oin)o(ter)i(to)f(a)g(string)g(\(see)g +(Section)h(1.1)195 1004 y([History)d(In)o(teraction],)f(page)h(1\).)20 +b(Returns:)195 1098 y Fo(0)216 b Fp(If)19 b(no)g(expansions)g(to)q(ok)f +(place)i(\(or,)e(if)i(the)e(only)i(c)o(hange)e(in)i(the)f(text)f(w)o +(as)g(the)435 1152 y(remo)o(v)m(al)d(of)g(escap)q(e)h(c)o(haracters)e +(preceding)i(the)f(history)g(expansion)h(c)o(haracter\);)195 +1241 y Fo(1)216 b Fp(if)16 b(expansions)g(did)g(tak)o(e)e(place;)195 +1330 y Fo(-1)192 b Fp(if)16 b(there)f(w)o(as)f(an)h(error)g(in)h +(expansion;)195 1419 y Fo(2)216 b Fp(if)14 b(the)g(returned)g(line)i +(should)f(b)q(e)f(displa)o(y)o(ed,)h(but)f(not)f(executed,)i(as)e(with) +h(the)g Fo(:p)435 1474 y Fp(mo)q(di\014er)i(\(see)f(Section)h(1.1.3)e +([Mo)q(di\014ers],)h(page)g(2\).)195 1568 y(If)g(an)h(error)e(o)q +(curred)i(in)g(expansion,)f(then)h Fj(output)g Fp(con)o(tains)f(a)g +(descriptiv)o(e)i(error)d(message.)1762 1713 y(F)l(unction)-1861 +b Fh(char)20 b(*)f Fg(get)p 324 1713 V 21 w(history)p +520 1713 V 20 w(ev)n(en)n(t)25 b Ff(\()p Fo(const)14 +b(char)h(*string,)f(int)g(*cindex,)g(int)283 1767 y(qchar)p +Ff(\))195 1822 y Fp(Returns)22 b(the)h(text)f(of)h(the)f(history)h(ev)o +(en)o(t)g(b)q(eginning)h(at)f Fj(string)j Fo(+)d Fj(*cindex)p +Fp(.)43 b Fj(*cindex)27 b Fp(is)195 1877 y(mo)q(di\014ed)16 +b(to)e(p)q(oin)o(t)h(to)f(after)g(the)h(ev)o(en)o(t)f(sp)q(eci\014er.) +22 b(A)o(t)14 b(function)h(en)o(try)l(,)g Fj(cindex)k +Fp(p)q(oin)o(ts)c(to)f(the)195 1932 y(index)19 b(in)o(to)f +Fj(string)k Fp(where)c(the)g(history)g(ev)o(en)o(t)g(sp)q +(eci\014cation)h(b)q(egins.)30 b Fj(qc)o(har)21 b Fp(is)d(a)g(c)o +(haracter)195 1987 y(that)13 b(is)h(allo)o(w)o(ed)g(to)e(end)i(the)g +(ev)o(en)o(t)f(sp)q(eci\014cation)j(in)e(addition)g(to)f(the)h +(\\normal")f(terminating)195 2041 y(c)o(haracters.)1762 +2186 y(F)l(unction)-1861 b Fh(char)20 b(**)f Fg(history)p +448 2186 V 21 w(tok)n(enize)25 b Ff(\()p Fo(const)14 +b(char)h(*string)p Ff(\))195 2241 y Fp(Return)g(an)g(arra)o(y)g(of)g +(tok)o(ens)g(parsed)g(out)g(of)g Fj(string)p Fp(,)g(m)o(uc)o(h)h(as)f +(the)g(shell)i(migh)o(t.)k(The)15 b(tok)o(ens)195 2296 +y(are)h(split)h(on)e(the)h(c)o(haracters)g(in)g(the)g +Fj(history)p 1007 2296 14 2 v 17 w(w)o(ord)p 1122 2296 +V 15 w(delimiters)k Fp(v)m(ariable,)d(and)f(shell)i(quoting)195 +2351 y(con)o(v)o(en)o(tions)d(are)g(ob)q(ey)o(ed.)1762 +2496 y(F)l(unction)-1861 b Fh(char)20 b(*)f Fg(history)p +422 2496 18 3 v 21 w(arg)p 524 2496 V 19 w(extract)24 +b Ff(\()p Fo(int)14 b(first,)h(int)g(last,)f(const)g(char)283 +2550 y(*string)p Ff(\))195 2605 y Fp(Extract)19 b(a)h(string)g(segmen)o +(t)g(consisting)h(of)f(the)g Fj(\014rst)h Fp(through)f +Fj(last)h Fp(argumen)o(ts)e(presen)o(t)h(in)195 2660 +y Fj(string)p Fp(.)g(Argumen)o(ts)15 b(are)f(split)j(using)f +Fo(history_tokenize)p Fp(.)p eop +%%Page: 10 12 +10 11 bop 75 -58 a Fp(10)1324 b(GNU)15 b(History)g(Library)75 +149 y Fn(2.4)33 b(History)22 b(V)-6 b(ariables)137 251 +y Fp(This)18 b(section)f(describ)q(es)i(the)e(externally-visible)k(v)m +(ariables)d(exp)q(orted)f(b)o(y)g(the)g Fk(gnu)g Fp(History)g(Li-)75 +306 y(brary)l(.)1773 438 y(V)l(ariable)-1861 b Fh(int)20 +b Fg(history)p 351 438 18 3 v 20 w(base)195 493 y Fp(The)15 +b(logical)i(o\013set)d(of)h(the)g(\014rst)g(en)o(try)g(in)h(the)f +(history)g(list.)1773 625 y(V)l(ariable)-1861 b Fh(int)20 +b Fg(history)p 351 625 V 20 w(length)195 680 y Fp(The)15 +b(n)o(um)o(b)q(er)h(of)f(en)o(tries)g(curren)o(tly)h(stored)f(in)h(the) +f(history)g(list.)1773 812 y(V)l(ariable)-1861 b Fh(int)20 +b Fg(history)p 351 812 V 20 w(max)p 478 812 V 20 w(en)n(tries)195 +867 y Fp(The)j(maxim)o(um)g(n)o(um)o(b)q(er)g(of)g(history)g(en)o +(tries.)43 b(This)24 b(m)o(ust)e(b)q(e)i(c)o(hanged)f(using)h +Fo(stifle_)195 922 y(history\(\))p Fp(.)1773 1054 y(V)l(ariable)-1861 +b Fh(char)20 b Fg(history)p 377 1054 V 20 w(expansion)p +644 1054 V 21 w(c)n(har)195 1109 y Fp(The)e(c)o(haracter)f(that)g(in)o +(tro)q(duces)h(a)f(history)h(ev)o(en)o(t.)27 b(The)18 +b(default)g(is)g(`)p Fo(!)p Fp('.)26 b(Setting)18 b(this)g(to)f(0)195 +1164 y(inhibits)g(history)f(expansion.)1773 1296 y(V)l(ariable)-1861 +b Fh(char)20 b Fg(history)p 377 1296 V 20 w(subst)p 529 +1296 V 20 w(c)n(har)195 1351 y Fp(The)h(c)o(haracter)e(that)h(in)o(v)o +(ok)o(es)g(w)o(ord)g(substitution)h(if)g(found)f(at)g(the)h(start)e(of) +h(a)g(line.)37 b(The)195 1406 y(default)16 b(is)f(`)p +Fo(^)p Fp('.)1773 1538 y(V)l(ariable)-1861 b Fh(char)20 +b Fg(history)p 377 1538 V 20 w(commen)n(t)p 627 1538 +V 19 w(c)n(har)195 1593 y Fp(During)f(tok)o(enization,)h(if)f(this)h(c) +o(haracter)e(is)h(seen)h(as)e(the)h(\014rst)g(c)o(haracter)f(of)g(a)h +(w)o(ord,)g(then)195 1648 y(it)j(and)g(all)g(subsequen)o(t)h(c)o +(haracters)d(up)j(to)e(a)g(newline)i(are)f(ignored,)h(suppressing)g +(history)195 1702 y(expansion)16 b(for)f(the)g(remainder)h(of)f(the)g +(line.)21 b(This)16 b(is)g(disabled)h(b)o(y)e(default.)1773 +1835 y(V)l(ariable)-1861 b Fh(char)20 b(*)f Fg(history)p +422 1835 V 21 w(w)n(ord)p 567 1835 V 20 w(delimiters)195 +1889 y Fp(The)14 b(c)o(haracters)f(that)g(separate)g(tok)o(ens)h(for)f +Fo(history_tokenize\(\))p Fp(.)k(The)d(default)g(v)m(alue)h(is)f +Fo(")195 1944 y(\\t\\n\(\)<>;&|")p Fp(.)1773 2077 y(V)l(ariable)-1861 +b Fh(char)20 b(*)f Fg(history)p 422 2077 V 21 w(no)p +504 2077 V 20 w(expand)p 704 2077 V 20 w(c)n(hars)195 +2131 y Fp(The)c(list)h(of)e(c)o(haracters)g(whic)o(h)i(inhibit)h +(history)e(expansion)h(if)f(found)h(immediately)g(follo)o(wing)195 +2186 y Fj(history)p 336 2186 14 2 v 16 w(expansion)p +547 2186 V 18 w(c)o(har)p Fp(.)j(The)d(default)f(is)h(space,)f(tab,)g +(newline,)h(carriage)f(return,)g(and)h(`)p Fo(=)p Fp('.)1773 +2318 y(V)l(ariable)-1861 b Fh(char)20 b(*)f Fg(history)p +422 2318 18 3 v 21 w(searc)n(h)p 599 2318 V 20 w(delimiter)p +843 2318 V 23 w(c)n(hars)195 2373 y Fp(The)13 b(list)h(of)f(additional) +h(c)o(haracters)e(whic)o(h)i(can)g(delimit)g(a)f(history)g(searc)o(h)g +(string,)g(in)h(addition)195 2428 y(to)h(space,)g(T)l(AB,)g(`)p +Fo(:)p Fp(')f(and)h(`)p Fo(?)p Fp(')g(in)h(the)f(case)g(of)g(a)g +(substring)g(searc)o(h.)20 b(The)c(default)f(is)h(empt)o(y)l(.)1773 +2560 y(V)l(ariable)-1861 b Fh(int)20 b Fg(history)p 351 +2560 V 20 w(quotes)p 533 2560 V 21 w(inhibit)p 717 2560 +V 23 w(expansion)195 2615 y Fp(If)15 b(non-zero,)f(single-quoted)j(w)o +(ords)c(are)i(not)f(scanned)h(for)f(the)h(history)g(expansion)g(c)o +(haracter.)195 2670 y(The)g(default)h(v)m(alue)h(is)e(0.)p +eop +%%Page: 11 13 +11 12 bop 75 -58 a Fp(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(History)867 b(11)1773 149 y(V)l(ariable)-1861 b Fh(rl_linebuf_func_t) +22 b(*)d Fg(history)p 762 149 18 3 v 21 w(inhibit)p 946 +149 V 23 w(expansion)p 1216 149 V 20 w(function)195 204 +y Fp(This)e(should)h(b)q(e)f(set)g(to)f(the)g(address)h(of)f(a)h +(function)g(that)f(tak)o(es)g(t)o(w)o(o)f(argumen)o(ts:)22 +b(a)17 b Fo(char)d(*)195 259 y Fp(\()p Fj(string)t Fp(\))e(and)i(an)f +Fo(int)g Fp(index)i(in)o(to)e(that)f(string)i(\()p Fj(i)r +Fp(\).)19 b(It)14 b(should)g(return)f(a)g(non-zero)h(v)m(alue)g(if)g +(the)195 314 y(history)h(expansion)g(starting)f(at)g +Fj(string[i])i Fp(should)g(not)e(b)q(e)h(p)q(erformed;)g(zero)f(if)h +(the)g(expansion)195 369 y(should)i(b)q(e)g(done.)22 +b(It)16 b(is)h(in)o(tended)g(for)e(use)i(b)o(y)f(applications)h(lik)o +(e)g(Bash)f(that)g(use)g(the)g(history)195 423 y(expansion)g(c)o +(haracter)f(for)f(additional)j(purp)q(oses.)j(By)c(default,)f(this)h(v) +m(ariable)g(is)g(set)f(to)f Fo(NULL)p Fp(.)75 543 y Fn(2.5)33 +b(History)22 b(Programming)h(Example)137 637 y Fp(The)16 +b(follo)o(wing)g(program)e(demonstrates)g(simple)j(use)e(of)g(the)g +Fk(gnu)g Fp(History)g(Library)l(.)195 698 y Fo(#include)23 +b()195 750 y(#include)g()195 +854 y(main)g(\(argc,)g(argv\))314 906 y(int)h(argc;)314 +958 y(char)g(**argv;)195 1010 y({)243 1061 y(char)f(line[1024],)f(*t;) +243 1113 y(int)h(len,)g(done)h(=)g(0;)243 1217 y(line[0])f(=)g(0;)243 +1321 y(using_history)f(\(\);)243 1373 y(while)h(\(!done\))290 +1425 y({)338 1477 y(printf)g(\("history$)g("\);)338 1528 +y(fflush)g(\(stdout\);)338 1580 y(t)h(=)g(fgets)f(\(line,)g(sizeof)g +(\(line\))g(-)h(1,)f(stdin\);)338 1632 y(if)h(\(t)f(&&)h(*t\))386 +1684 y({)434 1736 y(len)f(=)h(strlen)f(\(t\);)434 1788 +y(if)g(\(t[len)g(-)h(1])g(==)f('\\n'\))481 1840 y(t[len)h(-)f(1])h(=)g +('\\0';)386 1892 y(})338 1995 y(if)g(\(!t\))386 2047 +y(strcpy)f(\(line,)g("quit"\);)338 2151 y(if)h(\(line[0]\))386 +2203 y({)434 2255 y(char)f(*expansion;)434 2307 y(int)g(result;)434 +2411 y(result)g(=)g(history_expand)f(\(line,)h(&expansion\);)434 +2462 y(if)g(\(result\))481 2514 y(fprintf)g(\(stderr,)g("\045s\\n",)g +(expansion\);)434 2618 y(if)g(\(result)g(<)h(0)g(||)f(result)g(==)h +(2\))481 2670 y({)p eop +%%Page: 12 14 +12 13 bop 75 -58 a Fp(12)1324 b(GNU)15 b(History)g(Library)529 +149 y Fo(free)23 b(\(expansion\);)529 201 y(continue;)481 +253 y(})434 357 y(add_history)f(\(expansion\);)434 409 +y(strncpy)h(\(line,)g(expansion,)f(sizeof)h(\(line\))g(-)h(1\);)434 +461 y(free)f(\(expansion\);)386 513 y(})338 616 y(if)h(\(strcmp)f +(\(line,)g("quit"\))g(==)g(0\))386 668 y(done)g(=)h(1;)338 +720 y(else)f(if)h(\(strcmp)f(\(line,)g("save"\))g(==)h(0\))386 +772 y(write_history)e(\("history_file"\);)338 824 y(else)h(if)h +(\(strcmp)f(\(line,)g("read"\))g(==)h(0\))386 876 y(read_history)e +(\("history_file"\);)338 928 y(else)h(if)h(\(strcmp)f(\(line,)g +("list"\))g(==)h(0\))386 980 y({)434 1032 y(register)e(HIST_ENTRY)h +(**the_list;)434 1083 y(register)f(int)i(i;)434 1187 +y(the_list)e(=)i(history_list)e(\(\);)434 1239 y(if)h(\(the_list\))481 +1291 y(for)h(\(i)f(=)h(0;)g(the_list[i];)e(i++\))529 +1343 y(printf)h(\("\045d:)g(\045s\\n",)g(i)h(+)g(history_base,)e +(the_list[i]->line\);)386 1395 y(})338 1447 y(else)h(if)h(\(strncmp)f +(\(line,)g("delete",)g(6\))g(==)h(0\))386 1499 y({)434 +1550 y(int)f(which;)434 1602 y(if)g(\(\(sscanf)g(\(line)g(+)h(6,)f +("\045d",)h(&which\)\))e(==)i(1\))481 1654 y({)529 1706 +y(HIST_ENTRY)f(*entry)g(=)g(remove_history)f(\(which\);)529 +1758 y(if)i(\(!entry\))577 1810 y(fprintf)f(\(stderr,)f("No)i(such)f +(entry)g(\045d\\n",)g(which\);)529 1862 y(else)577 1914 +y({)625 1966 y(free)g(\(entry->line\);)625 2017 y(free)g(\(entry\);)577 +2069 y(})481 2121 y(})434 2173 y(else)481 2225 y({)529 +2277 y(fprintf)g(\(stderr,)g("non-numeric)f(arg)h(given)h(to)f +(`delete'\\n"\);)481 2329 y(})386 2381 y(})290 2433 y(})195 +2484 y(})p eop +%%Page: 13 15 +13 14 bop 75 -58 a Fp(App)q(endix)17 b(A:)e(Concept)g(Index)1196 +b(13)75 149 y Fl(App)r(endix)25 b(A)41 b(Concept)27 b(Index)75 +321 y Fn(A)75 383 y Fe(anc)o(hored)14 b(searc)o(h)s Fd(.)8 +b(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)16 +b Fe(8)75 507 y Fn(E)75 568 y Fe(ev)o(en)o(t)d(designators)g +Fd(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)23 b +Fe(1)1012 321 y Fn(H)1012 431 y Fe(history)15 b(ev)o(en)o(ts)d +Fd(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)24 +b Fe(1)1012 500 y(history)15 b(expansion)8 b Fd(.)g(.)e(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)21 b Fe(1)1012 568 y(History)14 b(Searc)o(hing)6 +b Fd(.)j(.)d(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)19 b +Fe(8)p eop +%%Page: 14 16 +14 15 bop 75 -58 a Fp(14)1324 b(GNU)15 b(History)g(Library)p +eop +%%Page: 15 17 +15 16 bop 75 -58 a Fp(App)q(endix)17 b(B:)e(F)l(unction)h(and)g(V)l +(ariable)g(Index)919 b(15)75 149 y Fl(App)r(endix)25 +b(B)41 b(F)-7 b(unction)26 b(and)h(V)-7 b(ariable)26 +b(Index)75 321 y Fn(A)75 382 y Fc(add_histor)o(y)8 b +Fd(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)23 +b Fe(6)75 428 y Fc(append_his)o(to)o(ry)8 b Fd(.)s(.)f(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)21 b Fe(9)75 557 y Fn(C)75 618 +y Fc(clear_hist)o(or)o(y)6 b Fd(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)22 b Fe(6)75 664 y Fc(current_hi)o(st)o(ory)7 +b Fd(.)s(.)f(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)20 b +Fe(7)75 793 y Fn(G)75 854 y Fc(get_histor)o(y_)o(eve)o(nt)5 +b Fd(.)t(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)19 b Fe(9)75 +984 y Fn(H)75 1044 y Fc(history_ar)o(g_)o(ext)o(ra)o(ct)5 +b Fd(.)s(.)h(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)18 b Fe(9)75 1090 y Fc(history_ba)o(se) +6 b Fd(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)22 +b Fe(10)75 1136 y Fc(history_co)o(mm)o(ent)o(_c)o(har)s +Fd(.)s(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)16 b Fe(10)75 1182 y Fc(history_ex)o(pa)o(nd)8 +b Fd(.)s(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)21 +b Fe(9)75 1227 y Fc(history_ex)o(pa)o(nsi)o(on)o(_ch)o(ar)8 +b Fd(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)24 b Fe(10)75 1273 y Fc(history_ge)o(t)8 +b Fd(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)23 +b Fe(7)75 1319 y Fc(history_ge)o(t_)o(his)o(to)o(ry_)o(sta)o(te)6 +b Fd(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)22 b Fe(6)75 1364 y Fc(history_in)o(hi)o(bit)o(_e)o(xpa)o(nsi)o(on) +o(_fu)o(nc)o(tio)o(n)9 b Fd(.)d(.)g(.)g(.)g(.)g(.)h(.)24 +b Fe(11)75 1410 y Fc(history_is)o(_s)o(tif)o(le)o(d)6 +b Fd(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)18 b Fe(7)75 1456 +y Fc(history_le)o(ng)o(th)8 b Fd(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)21 b Fe(10)75 1501 y Fc(history_li)o(st)6 b Fd(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)23 b Fe(7)75 +1547 y Fc(history_ma)o(x_)o(ent)o(ri)o(es)t Fd(.)s(.)6 +b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)17 b Fe(10)75 1593 y Fc(history_no)o(_e)o(xpa)o(nd)o +(_ch)o(ars)7 b Fd(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)23 b Fe(10)75 1638 y Fc(history_qu)o(ot)o(es_)o +(in)o(hib)o(it_)o(ex)o(pan)o(si)o(on)t Fd(.)s(.)6 b(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)17 b Fe(10)75 1684 y Fc(history_se)o(ar)o(ch)8 +b Fd(.)s(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)21 +b Fe(8)75 1730 y Fc(history_se)o(ar)o(ch_)o(de)o(lim)o(ite)o(r_)o(cha)o +(rs)5 b Fd(.)s(.)h(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)18 +b Fe(10)75 1776 y Fc(history_se)o(ar)o(ch_)o(po)o(s)6 +b Fd(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)18 b Fe(8)75 1821 +y Fc(history_se)o(ar)o(ch_)o(pr)o(efi)o(x)s Fd(.)t(.)6 +b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)16 b Fe(8)75 1867 y Fc(history_se)o(t_)o(his)o(to)o(ry_) +o(sta)o(te)6 b Fd(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)22 b Fe(6)75 1913 y Fc(history_se)o(t_)o(pos)7 +b Fd(.)s(.)f(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)20 b +Fe(7)1012 321 y Fc(history_sub)o(st)o(_ch)o(ar)t Fd(.)t(.)6 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)19 b Fe(10)1012 368 y Fc(history_tok)o(en)o(ize) +6 b Fd(.)t(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)20 b Fe(9)1012 +414 y Fc(history_tot)o(al)o(_by)o(te)o(s)5 b Fd(.)s(.)h(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)18 b Fe(7)1012 460 y Fc(history_tru)o(nc)o(ate)o(_f)o(ile)s +Fd(.)s(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)17 b Fe(9)1012 507 y Fc(history_wor)o(d_)o(del) +o(im)o(ite)o(rs)7 b Fd(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)24 b Fe(10)1012 640 y Fn(N)1012 +702 y Fc(next_histor)o(y)7 b Fd(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)g(.)h(.)f(.)23 b Fe(7)1012 836 y Fn(P)1012 898 y +Fc(previous_hi)o(st)o(ory)6 b Fd(.)t(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)20 b Fe(7)1012 1031 y Fn(R)1012 1094 y Fc(read_histor)o(y)7 +b Fd(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)23 +b Fe(8)1012 1140 y Fc(read_histor)o(y_)o(ran)o(ge)5 b +Fd(.)s(.)h(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)19 b Fe(8)1012 1186 +y Fc(remove_hist)o(or)o(y)9 b Fd(.)s(.)d(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)22 b Fe(6)1012 1233 y Fc(replace_his)o(to)o(ry_)o(en)o(try)s +Fd(.)s(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)17 b Fe(6)1012 1366 y Fn(S)1012 +1429 y Fc(stifle_hist)o(or)o(y)9 b Fd(.)s(.)d(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)22 b Fe(7)1012 1562 y Fn(U)1012 1624 +y Fc(unstifle_hi)o(st)o(ory)6 b Fd(.)t(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)20 b Fe(7)1012 1671 y Fc(using_histo)o(ry)6 b Fd(.)g(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 b Fe(6)1012 1804 +y Fn(W)1012 1866 y Fc(where_histo)o(ry)6 b Fd(.)g(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 b Fe(7)1012 1913 y Fc(write_histo)o(ry)6 +b Fd(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 +b Fe(8)p eop +%%Page: 16 18 +16 17 bop 75 -58 a Fp(16)1324 b(GNU)15 b(History)g(Library)p +eop +%%Page: -1 19 +-1 18 bop 1862 -58 a Fp(i)75 149 y Fl(T)-7 b(able)27 +b(of)f(Con)n(ten)n(ts)75 320 y Fn(1)67 b(Using)22 b(History)h(In)n +(teractiv)n(ely)9 b Fb(.)k(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)h(.)31 b Fn(1)224 389 y Fp(1.1)45 b(History)15 +b(Expansion)5 b Fa(.)j(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)19 b Fp(1)374 444 y(1.1.1)44 +b(Ev)o(en)o(t)14 b(Designators)e Fa(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)26 b Fp(1)374 499 y(1.1.2)44 b(W)l(ord)15 +b(Designators)5 b Fa(.)h(.)i(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)19 b Fp(2)374 553 y(1.1.3)44 b(Mo)q(di\014ers)t Fa(.)8 +b(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)19 b Fp(2)75 675 y Fn(2)67 b(Programming)23 +b(with)g(GNU)f(History)16 b Fb(.)10 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)38 b Fn(5)224 743 y Fp(2.1)45 b(In)o(tro)q(duction)16 +b(to)f(History)10 b Fa(.)d(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)24 b Fp(5)224 798 y(2.2)45 b(History)15 +b(Storage)c Fa(.)d(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)26 b Fp(5)224 853 +y(2.3)45 b(History)15 b(F)l(unctions)d Fa(.)c(.)f(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)26 +b Fp(6)374 907 y(2.3.1)44 b(Initializing)18 b(History)d(and)h(State)e +(Managemen)o(t)g Fa(.)7 b(.)h(.)g(.)f(.)h(.)f(.)29 b +Fp(6)374 962 y(2.3.2)44 b(History)15 b(List)h(Managemen)o(t)d +Fa(.)7 b(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)29 b Fp(6)374 1017 y(2.3.3)44 +b(Information)15 b(Ab)q(out)g(the)h(History)f(List)c +Fa(.)d(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)26 +b Fp(7)374 1072 y(2.3.4)44 b(Mo)o(ving)15 b(Around)g(the)g(History)g +(List)c Fa(.)d(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)25 b Fp(7)374 1127 y(2.3.5)44 b(Searc)o(hing)16 +b(the)f(History)g(List)7 b Fa(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)22 +b Fp(8)374 1181 y(2.3.6)44 b(Managing)15 b(the)g(History)g(File)6 +b Fa(.)i(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)20 b Fp(8)374 1236 y(2.3.7)44 +b(History)15 b(Expansion)9 b Fa(.)f(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)24 b Fp(9)224 1291 y(2.4)45 b(History)15 b(V)l(ariables)6 +b Fa(.)i(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)21 b Fp(10)224 1346 y(2.5)45 b(History)15 +b(Programming)f(Example)7 b Fa(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)22 +b Fp(11)75 1467 y Fn(App)r(endix)i(A)67 b(Concept)22 +b(Index)17 b Fb(.)10 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)38 b Fn(13)75 1602 y(App)r(endix)24 b(B)67 +b(F)-6 b(unction)25 b(and)e(V)-6 b(ariable)24 b(Index)16 +b Fb(.)10 b(.)g(.)g(.)38 b Fn(15)p eop +%%Page: -2 20 +-2 19 bop 75 -58 a Fp(ii)1346 b(GNU)15 b(History)g(Library)p +eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/readline-doc-4.3/doc/history_3.ps b/readline-doc-4.3/doc/history_3.ps new file mode 100644 index 0000000..f5231a5 --- /dev/null +++ b/readline-doc-4.3/doc/history_3.ps @@ -0,0 +1,800 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.16.1 +%%CreationDate: Mon Mar 18 10:17:27 2002 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%DocumentSuppliedResources: procset grops 1.16 1 +%%Pages: 7 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.16 1 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/MANUAL{ +statusdict begin/manualfeed true store end +}bind def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 +def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron +/scaron/zcaron/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent +/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen +/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon +/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O +/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex +/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y +/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft +/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl +/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen +/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft +/logicalnot/minus/registered/macron/degree/plusminus/twosuperior +/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior +/ordmasculine/guilsinglright/onequarter/onehalf/threequarters +/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE +/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex +/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn +/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla +/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis +/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash +/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def +/Times-Italic@0 ENC0/Times-Italic RE/Times-Bold@0 ENC0/Times-Bold RE +/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E/F1 10.95/Times-Bold@0 SF -.219(NA)72 84 S(ME) +.219 E F0(history \255 GNU History Library)108 96 Q F1(COPYRIGHT)72 +112.8 Q F0(The GNU History Library is Cop)108 124.8 Q +(yright \251 1989-2002 by the Free Softw)-.1 E(are F)-.1 E +(oundation, Inc.)-.15 E F1(DESCRIPTION)72 141.6 Q F0(Man)108 153.6 Q +2.81(yp)-.15 G .31(rograms read input from the user a line at a time.) +-2.81 F .309(The GNU History library is able to k)5.309 F .309 +(eep track of)-.1 F .024(those lines, associate arbitrary data with eac\ +h line, and utilize information from pre)108 165.6 R .024 +(vious lines in composing)-.25 F(ne)108 177.6 Q 2.5(wo)-.25 G(nes.)-2.5 +E F1(HIST)72 199.2 Q(OR)-.197 E 2.738(YE)-.383 G(XP)-2.738 E(ANSION)-.81 +E F0 .823(The history library supports a history e)108 211.2 R .822 +(xpansion feature that is identical to the history e)-.15 F .822 +(xpansion in)-.15 F/F2 10/Times-Bold@0 SF(bash.)3.322 E F0 +(This section describes what syntax features are a)108 223.2 Q -.25(va) +-.2 G(ilable.).25 E 1.305(History e)108 240 R 1.305 +(xpansions introduce w)-.15 F 1.306(ords from the history list into the\ + input stream, making it easy to repeat)-.1 F .21 +(commands, insert the ar)108 252 R .21(guments to a pre)-.18 F .209 +(vious command into the current input line, or \214x errors in pre)-.25 +F(vious)-.25 E(commands quickly)108 264 Q(.)-.65 E 1.296(History e)108 +280.8 R 1.297(xpansion is usually performed immediately after a complet\ +e line is read.)-.15 F 1.297(It tak)6.297 F 1.297(es place in tw)-.1 F +(o)-.1 E 2.855(parts. The)108 292.8 R .354(\214rst is to determine whic\ +h line from the history list to use during substitution.)2.855 F .354 +(The second is to)5.354 F .116 +(select portions of that line for inclusion into the current one.)108 +304.8 R .117(The line selected from the history is the)5.116 F/F3 10 +/Times-Italic@0 SF -.15(ev)2.617 G(ent).15 E F0(,)A .846 +(and the portions of that line that are acted upon are)108 316.8 R F3 +(wor)3.346 E(ds)-.37 E F0 5.846(.V)C(arious)-6.956 E F3(modi\214er)3.346 +E(s)-.1 E F0 .846(are a)3.346 F -.25(va)-.2 G .845(ilable to manipulate) +.25 F .304(the selected w)108 328.8 R 2.804(ords. The)-.1 F .304 +(line is brok)2.804 F .304(en into w)-.1 F .304(ords in the same f)-.1 F +.304(ashion as)-.1 F F2(bash)2.804 E F0 .305 +(does when reading input, so)2.804 F .539(that se)108 340.8 R -.15(ve) +-.25 G .539(ral w).15 F .539(ords that w)-.1 F .539 +(ould otherwise be separated are considered one w)-.1 F .538 +(ord when surrounded by quotes)-.1 F .307(\(see the description of)108 +352.8 R F2(history_tok)2.807 E(enize\(\))-.1 E F0(belo)2.807 E 2.807 +(w\). History)-.25 F -.15(ex)2.807 G .307 +(pansions are introduced by the appearance of).15 F .52(the history e) +108 364.8 R .52(xpansion character)-.15 F 3.02(,w)-.4 G .52(hich is) +-3.02 F F2(!)3.853 E F0 .52(by def)3.853 F 3.02(ault. Only)-.1 F .52 +(backslash \()3.02 F F2(\\).833 E F0 3.02(\)a).833 G .52 +(nd single quotes can quote the)-3.02 F(history e)108 376.8 Q +(xpansion character)-.15 E(.)-.55 E F2(Ev)87 393.6 Q(ent Designators)-.1 +E F0(An e)108 405.6 Q -.15(ve)-.25 G(nt designator is a reference to a \ +command line entry in the history list.).15 E F2(!)108 422.4 Q F0 +(Start a history substitution, e)32.67 E(xcept when follo)-.15 E +(wed by a)-.25 E F2(blank)2.5 E F0 2.5(,n)C -.25(ew)-2.5 G +(line, = or \(.).25 E F2(!)108 434.4 Q F3(n)A F0(Refer to command line) +27.67 E F3(n)2.5 E F0(.).24 E F2<21ad>108 446.4 Q F3(n)A F0 +(Refer to the current command line minus)21.97 E F3(n)2.5 E F0(.).24 E +F2(!!)108 458.4 Q F0(Refer to the pre)29.34 E(vious command.)-.25 E +(This is a synon)5 E(ym for `!\2551'.)-.15 E F2(!)108 470.4 Q F3(string) +A F0(Refer to the most recent command starting with)9.33 E F3(string)2.5 +E F0(.).22 E F2(!?)108 482.4 Q F3(string)A F2([?])A F0 1.057 +(Refer to the most recent command containing)144 494.4 R F3(string)3.557 +E F0 6.057(.T).22 G 1.057(he trailing)-6.057 F F2(?)3.557 E F0 1.057 +(may be omitted if)3.557 F F3(string)3.557 E F0(is)3.557 E(follo)144 +506.4 Q(wed immediately by a ne)-.25 E(wline.)-.25 E/F4 12/Times-Bold@0 +SF(^)108 523.4 Q F3(string1)-5 I F4(^)5 I F3(string2)-5 I F4(^)5 I F0 +2.66(Quick substitution.)144 530.4 R 2.66 +(Repeat the last command, replacing)7.66 F F3(string1)5.16 E F0(with) +5.16 E F3(string2)5.16 E F0 7.66(.E).02 G(qui)-7.66 E -.25(va)-.25 G +2.66(lent to).25 F -.74(``)144 542.4 S(!!:s/).74 E F3(string1)A F0(/)A +F3(string2)A F0(/')A 2.5('\()-.74 G(see)-2.5 E F2(Modi\214ers)2.5 E F0 +(belo)2.5 E(w\).)-.25 E F2(!#)108 554.4 Q F0 +(The entire command line typed so f)27.67 E(ar)-.1 E(.)-.55 E F2 -.75 +(Wo)87 571.2 S(rd Designators).75 E F0 -.8(Wo)108 583.2 S 1.313 +(rd designators are used to select desired w).8 F 1.314(ords from the e) +-.1 F -.15(ve)-.25 G 3.814(nt. A).15 F F2(:)3.814 E F0 1.314 +(separates the e)3.814 F -.15(ve)-.25 G 1.314(nt speci\214cation).15 F +.53(from the w)108 595.2 R .529(ord designator)-.1 F 5.529(.I)-.55 G +3.029(tm)-5.529 G .529(ay be omitted if the w)-3.029 F .529 +(ord designator be)-.1 F .529(gins with a)-.15 F F2(^)3.029 E F0(,)A F2 +($)3.029 E F0(,)A F2(*)3.029 E F0(,)A F23.029 E F0 3.029(,o)C(r) +-3.029 E F2(%)3.029 E F0 5.529(.W)C(ords)-6.329 E 1.3 +(are numbered from the be)108 607.2 R 1.3 +(ginning of the line, with the \214rst w)-.15 F 1.301 +(ord being denoted by 0 \(zero\).)-.1 F -.8(Wo)6.301 G 1.301(rds are).8 +F(inserted into the current line separated by single spaces.)108 619.2 Q +F2 2.5(0\()108 636 S(zer)-2.5 E(o\))-.18 E F0(The zeroth w)144 648 Q 2.5 +(ord. F)-.1 F(or the shell, this is the command w)-.15 E(ord.)-.1 E F3 +(n)108 660 Q F0(The)31 E F3(n)2.5 E F0(th w)A(ord.)-.1 E F2(^)108 672 Q +F0(The \214rst ar)32.67 E 2.5(gument. That)-.18 F(is, w)2.5 E(ord 1.)-.1 +E F2($)108 684 Q F0(The last ar)31 E(gument.)-.18 E F2(%)108 696 Q F0 +(The w)26 E(ord matched by the most recent `?)-.1 E F3(string)A F0 +(?' search.)A F3(x)108 708 Q F2A F3(y)A F0 2.5(Ar)21.42 G(ange of w) +-2.5 E(ords; `\255)-.1 E F3(y)A F0 2.5('a)C(bbre)-2.5 E(viates `0\255) +-.25 E F3(y)A F0('.)A(GNU History 4.3)72 768 Q(2002 January 31)131.79 E +(1)195.95 E EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E/F1 10/Times-Bold@0 SF(*)108 84 Q F0 .316 +(All of the w)31 F .316(ords b)-.1 F .316(ut the zeroth.)-.2 F .315 +(This is a synon)5.315 F .315(ym for `)-.15 F/F2 10/Times-Italic@0 SF +(1\255$)A F0 2.815('. It)B .315(is not an error to use)2.815 F F1(*) +2.815 E F0 .315(if there is)2.815 F(just one w)144 96 Q(ord in the e)-.1 +E -.15(ve)-.25 G(nt; the empty string is returned in that case.).15 E F1 +(x*)108 108 Q F0(Abbre)26 E(viates)-.25 E F2(x\255$)2.5 E F0(.)A F1 +<78ad>108 120 Q F0(Abbre)25.3 E(viates)-.25 E F2(x\255$)2.5 E F0(lik)2.5 +E(e)-.1 E F1(x*)2.5 E F0 2.5(,b)C(ut omits the last w)-2.7 E(ord.)-.1 E +(If a w)108 136.8 Q(ord designator is supplied without an e)-.1 E -.15 +(ve)-.25 G(nt speci\214cation, the pre).15 E +(vious command is used as the e)-.25 E -.15(ve)-.25 G(nt.).15 E F1 +(Modi\214ers)87 153.6 Q F0 .183(After the optional w)108 165.6 R .183 +(ord designator)-.1 F 2.683(,t)-.4 G .184 +(here may appear a sequence of one or more of the follo)-2.683 F .184 +(wing modi\214ers,)-.25 F(each preceded by a `:'.)108 177.6 Q F1(h)108 +194.4 Q F0(Remo)30.44 E .3 -.15(ve a t)-.15 H +(railing \214le name component, lea).15 E(ving only the head.)-.2 E F1 +(t)108 206.4 Q F0(Remo)32.67 E .3 -.15(ve a)-.15 H +(ll leading \214le name components, lea).15 E(ving the tail.)-.2 E F1(r) +108 218.4 Q F0(Remo)31.56 E .3 -.15(ve a t)-.15 H(railing suf).15 E +(\214x of the form)-.25 E F2(.xxx)2.5 E F0 2.5(,l)C(ea)-2.5 E +(ving the basename.)-.2 E F1(e)108 230.4 Q F0(Remo)31.56 E .3 -.15(ve a) +-.15 H(ll b).15 E(ut the trailing suf)-.2 E(\214x.)-.25 E F1(p)108 242.4 +Q F0(Print the ne)30.44 E 2.5(wc)-.25 G(ommand b)-2.5 E(ut do not e)-.2 +E -.15(xe)-.15 G(cute it.).15 E F1(q)108 254.4 Q F0 +(Quote the substituted w)30.44 E(ords, escaping further substitutions.) +-.1 E F1(x)108 266.4 Q F0(Quote the substituted w)31 E(ords as with)-.1 +E F1(q)2.5 E F0 2.5(,b)C(ut break into w)-2.7 E(ords at)-.1 E F1(blanks) +2.5 E F0(and ne)2.5 E(wlines.)-.25 E F1(s/)108 278.4 Q F2(old)A F1(/)A +F2(ne)A(w)-.15 E F1(/)A F0(Substitute)144 290.4 Q F2(ne)2.814 E(w)-.15 E +F0 .314(for the \214rst occurrence of)2.814 F F2(old)2.814 E F0 .314 +(in the e)2.814 F -.15(ve)-.25 G .314(nt line.).15 F(An)5.314 E 2.814 +(yd)-.15 G .314(elimiter can be used in place)-2.814 F .616(of /.)144 +302.4 R .617 +(The \214nal delimiter is optional if it is the last character of the e) +5.616 F -.15(ve)-.25 G .617(nt line.).15 F .617(The delimiter may)5.617 +F .75(be quoted in)144 314.4 R F2(old)3.25 E F0(and)3.25 E F2(ne)3.25 E +(w)-.15 E F0 .75(with a single backslash.)3.25 F .749(If & appears in) +5.75 F F2(ne)3.249 E(w)-.15 E F0 3.249(,i).31 G 3.249(ti)-3.249 G 3.249 +(sr)-3.249 G .749(eplaced by)-3.249 F F2(old)3.249 E F0 5.749(.A).77 G +.369(single backslash will quote the &.)144 326.4 R(If)5.369 E F2(old) +2.869 E F0 .37(is null, it is set to the last)2.869 F F2(old)2.87 E F0 +.37(substituted, or)2.87 F 2.87(,i)-.4 G 2.87(fn)-2.87 G 2.87(op)-2.87 G +(re)-2.87 E(vi-)-.25 E(ous history substitutions took place, the last) +144 338.4 Q F2(string)2.5 E F0(in a)2.5 E F1(!?)2.5 E F2(string)A F1 +([?])A F0(search.)5 E F1(&)108 350.4 Q F0(Repeat the pre)27.67 E +(vious substitution.)-.25 E F1(g)108 362.4 Q F0 .398 +(Cause changes to be applied o)31 F -.15(ve)-.15 G 2.898(rt).15 G .398 +(he entire e)-2.898 F -.15(ve)-.25 G .398(nt line.).15 F .397 +(This is used in conjunction with `)5.398 F F1(:s)A F0 2.897('\()C +(e.g.,)-2.897 E(`)144 374.4 Q F1(:gs/)A F2(old)A F1(/)A F2(ne)A(w)-.15 E +F1(/)A F0 1.218('\) or `)B F1(:&)A F0 3.718('. If)B 1.218(used with `) +3.718 F F1(:s)A F0 1.218(', an)B 3.718(yd)-.15 G 1.219 +(elimiter can be used in place of /, and the \214nal)-3.718 F +(delimiter is optional if it is the last character of the e)144 386.4 Q +-.15(ve)-.25 G(nt line.).15 E/F3 10.95/Times-Bold@0 SF(PR)72 403.2 Q +(OGRAMMING WITH HIST)-.329 E(OR)-.197 E 2.738(YF)-.383 G(UNCTIONS)-2.738 +E F0(This section describes ho)108 415.2 Q 2.5(wt)-.25 G 2.5(ou)-2.5 G +(se the History library in other programs.)-2.5 E F1(Intr)87 432 Q +(oduction to History)-.18 E F0 .797 +(The programmer using the History library has a)108 444 R -.25(va)-.2 G +.796(ilable functions for remembering lines on a history list,).25 F +.307(associating arbitrary data with a line, remo)108 456 R .308 +(ving lines from the list, searching through the list for a line con-) +-.15 F .303(taining an arbitrary te)108 468 R .303 +(xt string, and referencing an)-.15 F 2.803(yl)-.15 G .303 +(ine in the list directly)-2.803 F 5.303(.I)-.65 G 2.803(na)-5.303 G +.303(ddition, a history)-2.803 F F2 -.2(ex)2.802 G(pansion).2 E F0 +(function is a)108 480 Q -.25(va)-.2 G(ilable which pro).25 E +(vides for a consistent user interf)-.15 E(ace across dif)-.1 E +(ferent programs.)-.25 E .059(The user using programs written with the \ +History library has the bene\214t of a consistent user interf)108 496.8 +R .059(ace with a)-.1 F .918(set of well-kno)108 508.8 R .917 +(wn commands for manipulating the te)-.25 F .917(xt of pre)-.15 F .917 +(vious lines and using that te)-.25 F .917(xt in ne)-.15 F 3.417(wc)-.25 +G(om-)-3.417 E 4.183(mands. The)108 520.8 R 1.684(basic history manipul\ +ation commands are identical to the history substitution pro)4.183 F +1.684(vided by)-.15 F F1(bash)108 532.8 Q F0(.)A .904 +(If the programmer desires, he can use the Readline library)108 549.6 R +3.403(,w)-.65 G .903(hich includes some history manipulation by)-3.403 F +(def)108 561.6 Q(ault, and has the added adv)-.1 E +(antage of command line editing.)-.25 E .39(Before declaring an)108 +578.4 R 2.89(yf)-.15 G .39(unctions using an)-2.89 F 2.89(yf)-.15 G .39 +(unctionality the History library pro)-2.89 F .39 +(vides in other code, an appli-)-.15 F .067 +(cation writer should include the \214le)108 590.4 R F2()-.55 E F0 .067(in an)4.233 F 2.566<798c>-.15 +G .066(le that uses the History library')-2.566 F 2.566(sf)-.55 G +(eatures.)-2.566 E .538(It supplies e)108 602.4 R .538 +(xtern declarations for all of the library')-.15 F 3.038(sp)-.55 G .538 +(ublic functions and v)-3.038 F .539(ariables, and declares all of the) +-.25 F(public data structures.)108 614.4 Q F1(History Storage)87 643.2 Q +F0(The history list is an array of history entries.)108 655.2 Q 2.5(Ah)5 +G(istory entry is declared as follo)-2.5 E(ws:)-.25 E F2(typedef void *) +108 672 Q F1(histdata_t;)2.5 E F0(typedef struct _hist_entry {)108 688.8 +Q(char *line;)113 700.8 Q(histdata_t data;)113 712.8 Q 2.5(}H)108 724.8 +S(IST_ENTR)-2.5 E -.92(Y;)-.65 G(GNU History 4.3)72 768 Q +(2002 January 31)131.79 E(2)195.95 E EP +%%Page: 3 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E +(The history list itself might therefore be declared as)108 84 Q/F1 10 +/Times-Italic@0 SF(HIST_ENTR)108 100.8 Q 2.5(Y*)-.18 G(*)-2.5 E/F2 10 +/Times-Bold@0 SF(the_history_list;)2.5 E F0(The state of the History li\ +brary is encapsulated into a single structure:)108 117.6 Q(/*)108 134.4 +Q 2.5(*As)110.5 146.4 S +(tructure used to pass around the current state of the history)-2.5 E(.) +-.65 E(*/)110.5 158.4 Q(typedef struct _hist_state {)108 170.4 Q +(HIST_ENTR)113 182.4 Q 2.5(Y*)-.65 G +(*entries; /* Pointer to the entries themselv)-2.5 E(es. */)-.15 E +(int of)113 194.4 Q 25(fset; /*)-.25 F +(The location pointer within this array)2.5 E 2.5(.*)-.65 G(/)-2.5 E +(int length;)113 206.4 Q(/* Number of elements within this array)27.5 E +2.5(.*)-.65 G(/)-2.5 E(int size;)113 218.4 Q +(/* Number of slots allocated to this array)32.5 E 2.5(.*)-.65 G(/)-2.5 +E(int \215ags;)113 230.4 Q 2.5(}H)108 242.4 S(IST)-2.5 E(OR)-.18 E(Y_ST) +-.65 E -1.11(AT)-.93 G(E;)1.11 E(If the \215ags member includes)108 +259.2 Q F2(HS_STIFLED)2.5 E F0 2.5(,t)C(he history has been sti\215ed.) +-2.5 E/F3 10.95/Times-Bold@0 SF(History Functions)72 276 Q F0 +(This section describes the calling sequence for the v)108 288 Q +(arious functions e)-.25 E(xported by the GNU History library)-.15 E(.) +-.65 E F2(Initializing History and State Management)87 304.8 Q F0 1.274 +(This section describes functions used to initialize and manage the sta\ +te of the History library when you)108 316.8 R -.1(wa)108 328.8 S +(nt to use the history functions in your program.).1 E F1(void)108 352.8 +Q F2(using_history)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E(Be)108 +364.8 Q(gin a session in which the history functions might be used.)-.15 +E(This initializes the interacti)5 E .3 -.15(ve v)-.25 H(ariables.)-.1 E +F1(HIST)108 388.8 Q(OR)-.18 E(Y_ST)-.18 E -.37(AT)-.5 G 2.5(E*).37 G F2 +(history_get_history_state)A F0(\()4.166 E F1(void)A F0(\))1.666 E +(Return a structure describing the current state of the input history) +108 400.8 Q(.)-.65 E F1(void)108 424.8 Q F2(history_set_history_state) +2.5 E F0(\()4.166 E F1(HIST)A(OR)-.18 E(Y_ST)-.18 E -.37(AT)-.5 G 2.5 +(E*).37 G(state)-2.5 E F0(\))1.666 E +(Set the state of the history list according to)108 436.8 Q F1(state)2.5 +E F0(.)A F2(History List Management)87 465.6 Q F0 +(These functions manage indi)108 477.6 Q(vidual entries on the history \ +list, or set parameters managing the list itself.)-.25 E F1(void)108 +501.6 Q F2(add_history)2.5 E F0(\()4.166 E F1(const c)A(har *string)-.15 +E F0(\))1.666 E(Place)108 513.6 Q F1(string)2.5 E F0 +(at the end of the history list.)2.5 E +(The associated data \214eld \(if an)5 E(y\) is set to)-.15 E F2(NULL) +2.5 E F0(.)A F1(HIST_ENTR)108 537.6 Q 2.5(Y*)-.18 G F2 -.18(re)C(mo).18 +E -.1(ve)-.1 G(_history).1 E F0(\()4.166 E F1(int whic)A(h)-.15 E F0(\)) +1.666 E(Remo)108 549.6 Q .352 -.15(ve h)-.15 H .052(istory entry at of) +.15 F(fset)-.25 E F1(whic)2.553 E(h)-.15 E F0 .053(from the history) +2.553 F 5.053(.T)-.65 G .053(he remo)-5.053 F -.15(ve)-.15 G 2.553(de) +.15 G .053(lement is returned so you can free the)-2.553 F +(line, data, and containing structure.)108 561.6 Q F1(HIST_ENTR)108 +585.6 Q 2.5(Y*)-.18 G F2 -.18(re)C(place_history_entry).18 E F0(\()4.166 +E F1(int whic)A -.834(h, const)-.15 F -.15(ch)2.5 G(ar *line).15 E 1.666 +(,h)-.1 G(istdata_t data)-1.666 E F0(\))3.332 E(Mak)108 597.6 Q 2.868 +(et)-.1 G .368(he history entry at of)-2.868 F(fset)-.25 E F1(whic)2.868 +E(h)-.15 E F0(ha)2.868 E -.15(ve)-.2 G F1(line)3.018 E F0(and)2.868 E F1 +(data)2.868 E F0 5.367(.T)C .367 +(his returns the old entry so you can dispose of)-5.367 F(the data.)108 +609.6 Q(In the case of an in)5 E -.25(va)-.4 G(lid).25 E F1(whic)2.5 E +(h)-.15 E F0 2.5(,a)C F2(NULL)A F0(pointer is returned.)2.5 E F1(void) +108 633.6 Q F2(clear_history)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E +(Clear the history list by deleting all the entries.)108 645.6 Q F1 +(void)108 669.6 Q F2(sti\215e_history)2.5 E F0(\()4.166 E F1(int max)A +F0(\))1.666 E(Sti\215e the history list, remembering only the last)108 +681.6 Q F1(max)2.5 E F0(entries.)2.5 E F1(int)108 705.6 Q F2 +(unsti\215e_history)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E .46 +(Stop sti\215ing the history)108 717.6 R 5.46(.T)-.65 G .46 +(his returns the pre)-5.46 F .46 +(viously-set maximum number of history entries \(as set by)-.25 F F2 +(sti-)2.96 E(\215e_history\(\))108 729.6 Q F0 2.5(\). history)B -.1(wa) +2.5 G 2.5(ss).1 G 2.5(ti\215ed. The)-2.5 F -.25(va)2.5 G(lue is positi) +.25 E .3 -.15(ve i)-.25 H 2.5(ft).15 G(he history w)-2.5 E +(as sti\215ed, ne)-.1 E -.05(ga)-.15 G(ti).05 E .3 -.15(ve i)-.25 H 2.5 +(fi).15 G 2.5(tw)-2.5 G(asn')-2.6 E(t.)-.18 E(GNU History 4.3)72 768 Q +(2002 January 31)131.79 E(3)195.95 E EP +%%Page: 4 4 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E/F1 10/Times-Italic@0 SF(int)108 84 Q/F2 10 +/Times-Bold@0 SF(history_is_sti\215ed)2.5 E F0(\()4.166 E F1(void)A F0 +(\))1.666 E +(Returns non-zero if the history is sti\215ed, zero if it is not.)108 96 +Q F2(Inf)87 124.8 Q(ormation About the History List)-.25 E F0(These fun\ +ctions return information about the entire history list or indi)108 +136.8 Q(vidual list entries.)-.25 E F1(HIST_ENTR)108 160.8 Q 2.5(Y*)-.18 +G(*)-2.5 E F2(history_list)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E +.708(Return a)108 172.8 R F2(NULL)3.208 E F0 .708(terminated array of) +3.208 F F1(HIST_ENTR)3.208 E 3.208(Y*)-.18 G F0 .708 +(which is the current input history)B 5.707(.E)-.65 G .707 +(lement 0 of this)-5.707 F(list is the be)108 184.8 Q(ginning of time.) +-.15 E(If there is no history)5 E 2.5(,r)-.65 G(eturn)-2.5 E F2(NULL)2.5 +E F0(.)A F1(int)108 208.8 Q F2(wher)2.5 E(e_history)-.18 E F0(\()4.166 E +F1(void)A F0(\))1.666 E(Returns the of)108 220.8 Q +(fset of the current history element.)-.25 E F1(HIST_ENTR)108 244.8 Q +2.5(Y*)-.18 G F2(curr)A(ent_history)-.18 E F0(\()4.166 E F1(void)A F0 +(\))1.666 E 1.373 +(Return the history entry at the current position, as determined by)108 +256.8 R F2(wher)3.873 E(e_history\(\))-.18 E F0 6.373(.I)C 3.873(ft) +-6.373 G 1.374(here is no entry)-3.873 F(there, return a)108 268.8 Q F2 +(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F1(HIST_ENTR)108 292.8 Q 2.5(Y*) +-.18 G F2(history_get)A F0(\()4.166 E F1(int of)A(fset)-.18 E F0(\)) +1.666 E .288(Return the history entry at position)108 304.8 R F1(of) +2.787 E(fset)-.18 E F0 2.787(,s)C .287(tarting from)-2.787 F F2 +(history_base)2.787 E F0 5.287(.I)C 2.787(ft)-5.287 G .287 +(here is no entry there, or if)-2.787 F F1(of)2.787 E(fset)-.18 E F0 +(is greater than the history length, return a)108 316.8 Q F2(NULL)2.5 E +F0(pointer)2.5 E(.)-.55 E F1(int)108 340.8 Q F2(history_total_bytes)2.5 +E F0(\()4.166 E F1(void)A F0(\))1.666 E .391 +(Return the number of bytes that the primary history entries are using.) +108 352.8 R .392(This function returns the sum of the)5.392 F +(lengths of all the lines in the history)108 364.8 Q(.)-.65 E F2(Mo)87 +393.6 Q(ving Ar)-.1 E(ound the History List)-.18 E F0 +(These functions allo)108 405.6 Q 2.5(wt)-.25 G(he current inde)-2.5 E +2.5(xi)-.15 G(nto the history list to be set or changed.)-2.5 E F1(int) +108 429.6 Q F2(history_set_pos)2.5 E F0(\()4.166 E F1(int pos)A F0(\)) +1.666 E .79(Set the current history of)108 441.6 R .79(fset to)-.25 F F1 +(pos)3.29 E F0 3.29(,a)C 3.29(na)-3.29 G .79(bsolute inde)-3.29 F 3.29 +(xi)-.15 G .79(nto the list.)-3.29 F .79(Returns 1 on success, 0 if)5.79 +F F1(pos)3.29 E F0 .79(is less)3.29 F +(than zero or greater than the number of history entries.)108 453.6 Q F1 +(HIST_ENTR)108 477.6 Q 2.5(Y*)-.18 G F2(pr)A -.15(ev)-.18 G +(ious_history).15 E F0(\()4.166 E F1(void)A F0(\))1.666 E .207 +(Back up the current history of)108 489.6 R .207(fset to the pre)-.25 F +.207(vious history entry)-.25 F 2.708(,a)-.65 G .208 +(nd return a pointer to that entry)-2.708 F 5.208(.I)-.65 G 2.708(ft) +-5.208 G .208(here is)-2.708 F(no pre)108 501.6 Q(vious entry)-.25 E 2.5 +(,r)-.65 G(eturn a)-2.5 E F2(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F1 +(HIST_ENTR)108 525.6 Q 2.5(Y*)-.18 G F2(next_history)A F0(\()4.166 E F1 +(void)A F0(\))1.666 E(Mo)108 537.6 Q 1.047 -.15(ve t)-.15 H .747 +(he current history of).15 F .747(fset forw)-.25 F .746(ard to the ne) +-.1 F .746(xt history entry)-.15 F 3.246(,a)-.65 G .746 +(nd return the a pointer to that entry)-3.246 F 5.746(.I)-.65 G(f)-5.746 +E(there is no ne)108 549.6 Q(xt entry)-.15 E 2.5(,r)-.65 G(eturn a)-2.5 +E F2(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F2(Sear)87 578.4 Q +(ching the History List)-.18 E F0 .005(These functions allo)108 590.4 R +2.505(ws)-.25 G .006(earching of the history list for entries containin\ +g a speci\214c string.)-2.505 F .006(Searching may be)5.006 F 1.452 +(performed both forw)108 602.4 R 1.452(ard and backw)-.1 F 1.451 +(ard from the current history position.)-.1 F 1.451(The search may be) +6.451 F F1(anc)3.951 E(hor)-.15 E(ed)-.37 E F0(,)A +(meaning that the string must match at the be)108 614.4 Q +(ginning of the history entry)-.15 E(.)-.65 E F1(int)108 638.4 Q F2 +(history_sear)2.5 E(ch)-.18 E F0(\()4.166 E F1(const c)A(har *string) +-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E(ection)-.37 E F0(\))1.666 E .155 +(Search the history for)108 650.4 R F1(string)2.655 E F0 2.656(,s)C .156 +(tarting at the current history of)-2.656 F 2.656(fset. If)-.25 F F1 +(dir)2.656 E(ection)-.37 E F0 .156(is less than 0, then the search)2.656 +F .802(is through pre)108 662.4 R .802 +(vious entries, otherwise through subsequent entries.)-.25 F(If)5.801 E +F1(string)3.301 E F0 .801(is found, then the current his-)3.301 F .064 +(tory inde)108 674.4 R 2.564(xi)-.15 G 2.564(ss)-2.564 G .064 +(et to that history entry)-2.564 F 2.564(,a)-.65 G .064(nd the v)-2.564 +F .064(alue returned is the of)-.25 F .064 +(fset in the line of the entry where)-.25 F F1(string)2.565 E F0 -.1(wa) +108 686.4 S 2.5(sf).1 G 2.5(ound. Otherwise,)-2.5 F +(nothing is changed, and a -1 is returned.)2.5 E F1(int)108 710.4 Q F2 +(history_sear)2.5 E(ch_pr)-.18 E(e\214x)-.18 E F0(\()4.166 E F1(const c) +A(har *string)-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E(ection)-.37 E F0(\)) +1.666 E .684(Search the history for)108 722.4 R F1(string)3.183 E F0 +3.183(,s)C .683(tarting at the current history of)-3.183 F 3.183 +(fset. The)-.25 F .683(search is anchored: matching lines)3.183 F +(GNU History 4.3)72 768 Q(2002 January 31)131.79 E(4)195.95 E EP +%%Page: 5 5 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E 1.063(must be)108 84 R 1.063(gin with)-.15 F/F1 +10/Times-Italic@0 SF(string)3.563 E F0 6.063(.I)C(f)-6.063 E F1(dir) +3.563 E(ection)-.37 E F0 1.064 +(is less than 0, then the search is through pre)3.563 F 1.064 +(vious entries, otherwise)-.25 F 1.115(through subsequent entries.)108 +96 R(If)6.115 E F1(string)3.615 E F0 1.115 +(is found, then the current history inde)3.615 F 3.614(xi)-.15 G 3.614 +(ss)-3.614 G 1.114(et to that entry)-3.614 F 3.614(,a)-.65 G 1.114 +(nd the)-3.614 F(return v)108 108 Q(alue is 0.)-.25 E +(Otherwise, nothing is changed, and a -1 is returned.)5 E F1(int)108 132 +Q/F2 10/Times-Bold@0 SF(history_sear)2.5 E(ch_pos)-.18 E F0(\()4.166 E +F1(const c)A(har *string)-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E -.834 +(ection, int)-.37 F(pos)2.5 E F0(\))3.332 E .603(Search for)108 144 R F1 +(string)3.103 E F0 .603(in the history list, starting at)3.103 F F1(pos) +3.104 E F0 3.104(,a)C 3.104(na)-3.104 G .604(bsolute inde)-3.104 F 3.104 +(xi)-.15 G .604(nto the list.)-3.104 F(If)5.604 E F1(dir)3.104 E(ection) +-.37 E F0 .604(is ne)3.104 F -.05(ga)-.15 G(ti).05 E -.15(ve)-.25 G(,) +.15 E .608(the search proceeds backw)108 156 R .608(ard from)-.1 F F1 +(pos)3.108 E F0 3.108(,o)C .608(therwise forw)-3.108 F 3.108 +(ard. Returns)-.1 F .608(the absolute inde)3.108 F 3.108(xo)-.15 G 3.108 +(ft)-3.108 G .608(he history ele-)-3.108 F(ment where)108 168 Q F1 +(string)2.5 E F0 -.1(wa)2.5 G 2.5(sf).1 G(ound, or -1 otherwise.)-2.5 E +F2(Managing the History File)87 196.8 Q F0 .035(The History library can\ + read the history from and write it to a \214le.)108 208.8 R .036 +(This section documents the functions for)5.035 F +(managing a history \214le.)108 220.8 Q F1(int)108 244.8 Q F2 -.18(re) +2.5 G(ad_history).18 E F0(\()4.166 E F1(const c)A(har *\214lename)-.15 E +F0(\))1.666 E .151(Add the contents of)108 256.8 R F1(\214lename)2.651 E +F0 .151(to the history list, a line at a time.)2.651 F(If)5.15 E F1 +(\214lename)2.65 E F0(is)2.65 E F2(NULL)2.65 E F0 2.65(,t)C .15 +(hen read from)-2.65 F F1(~/.his-)2.65 E(tory)108 268.8 Q F0 5(.R)C +(eturns 0 if successful, or)-5 E F2(err)2.5 E(no)-.15 E F0(if not.)2.5 E +F1(int)108 292.8 Q F2 -.18(re)2.5 G(ad_history_range).18 E F0(\()4.166 E +F1(const c)A(har *\214lename)-.15 E 1.666(,i)-.1 G(nt fr)-1.666 E -.834 +(om, int)-.45 F(to)2.5 E F0(\))3.332 E .052(Read a range of lines from) +108 304.8 R F1(\214lename)2.553 E F0 2.553(,a)C .053 +(dding them to the history list.)-2.553 F .053(Start reading at line) +5.053 F F1(fr)2.553 E(om)-.45 E F0 .053(and end at)2.553 F F1(to)2.553 E +F0(.)A(If)108 316.8 Q F1(fr)2.889 E(om)-.45 E F0 .389 +(is zero, start at the be)2.889 F 2.889(ginning. If)-.15 F F1(to)2.889 E +F0 .389(is less than)2.889 F F1(fr)2.889 E(om)-.45 E F0 2.889(,t)C .388 +(hen read until the end of the \214le.)-2.889 F(If)5.388 E F1 +(\214lename)2.888 E F0(is)108 328.8 Q F2(NULL)2.5 E F0 2.5(,t)C +(hen read from)-2.5 E F1(~/.history)2.5 E F0 5(.R)C +(eturns 0 if successful, or)-5 E F2(err)2.5 E(no)-.15 E F0(if not.)2.5 E +F1(int)108 352.8 Q F2(write_history)2.5 E F0(\()4.166 E F1(const c)A +(har *\214lename)-.15 E F0(\))1.666 E .961(Write the current history to) +108 364.8 R F1(\214lename)3.461 E F0 3.461(,o)C -.15(ve)-3.611 G +(rwriting).15 E F1(\214lename)3.461 E F0 .961(if necessary)3.461 F 5.961 +(.I)-.65 G(f)-5.961 E F1(\214lename)3.462 E F0(is)3.462 E F2(NULL)3.462 +E F0 3.462(,t)C .962(hen write)-3.462 F(the history list to)108 376.8 Q +F1(~/.history)2.5 E F0 5(.R)C(eturns 0 on success, or)-5 E F2(err)2.5 E +(no)-.15 E F0(on a read or write error)2.5 E(.)-.55 E F1(int)108 412.8 Q +F2(append_history)2.5 E F0(\()4.166 E F1(int nelements,)A(const c)1.666 +E(har *\214lename)-.15 E F0(\))1.666 E .839(Append the last)108 424.8 R +F1(nelements)3.339 E F0 .839(of the history list to)3.339 F F1 +(\214lename)3.339 E F0 5.839(.I)C(f)-5.839 E F1(\214lename)3.339 E F0 +(is)3.339 E F2(NULL)3.339 E F0 3.339(,t)C .838(hen append to)-3.339 F F1 +(~/.history)3.338 E F0(.)A(Returns 0 on success, or)108 436.8 Q F2(err) +2.5 E(no)-.15 E F0(on a read or write error)2.5 E(.)-.55 E F1(int)108 +460.8 Q F2(history_truncate_\214le)2.5 E F0(\()4.166 E F1(const c)A +(har *\214lename)-.15 E 1.666(,i)-.1 G(nt nlines)-1.666 E F0(\))1.666 E +-.35(Tr)108 472.8 S .38(uncate the history \214le).35 F F1(\214lename) +2.88 E F0 2.88(,l)C(ea)-2.88 E .38(ving only the last)-.2 F F1(nlines) +2.881 E F0 2.881(lines. If)2.881 F F1(\214lename)2.881 E F0(is)2.881 E +F2(NULL)2.881 E F0 2.881(,t)C(hen)-2.881 E F1(~/.history)2.881 E F0(is) +2.881 E 2.5(truncated. Returns)108 484.8 R 2.5(0o)2.5 G 2.5(ns)-2.5 G +(uccess, or)-2.5 E F2(err)2.5 E(no)-.15 E F0(on f)2.5 E(ailure.)-.1 E F2 +(History Expansion)87 513.6 Q F0(These functions implement history e)108 +525.6 Q(xpansion.)-.15 E F1(int)108 549.6 Q F2(history_expand)2.5 E F0 +(\()4.166 E F1 -.15(ch)C(ar *string).15 E 1.666(,c)-.1 G(har **output) +-1.816 E F0(\))1.666 E(Expand)108 561.6 Q F1(string)2.5 E F0 2.5(,p)C +(lacing the result into)-2.5 E F1(output)2.5 E F0 2.5(,ap)C +(ointer to a string.)-2.5 E(Returns:)5 E 31(0I)144 573.6 S 3.066(fn)-31 +G 3.066(oe)-3.066 G .566(xpansions took place \(or)-3.216 F 3.065(,i)-.4 +G 3.065(ft)-3.065 G .565(he only change in the te)-3.065 F .565(xt w) +-.15 F .565(as the remo)-.1 F -.25(va)-.15 G 3.065(lo).25 G 3.065(fe) +-3.065 G(scape)-3.065 E(characters preceding the history e)180 585.6 Q +(xpansion character\);)-.15 E 31(1i)144 597.6 S 2.5(fe)-31 G +(xpansions did tak)-2.65 E 2.5(ep)-.1 G(lace;)-2.5 E 25.17(-1 if)144 +609.6 R(there w)2.5 E(as an error in e)-.1 E(xpansion;)-.15 E 31(2i)144 +621.6 S 2.5(ft)-31 G(he returned line should be displayed, b)-2.5 E +(ut not e)-.2 E -.15(xe)-.15 G(cuted, as with the).15 E F2(:p)2.5 E F0 +(modi\214er)2.5 E(.)-.55 E(If an error ocurred in e)108 633.6 Q +(xpansion, then)-.15 E F1(output)2.5 E F0(contains a descripti)2.5 E .3 +-.15(ve e)-.25 H(rror message.).15 E F1 -.15(ch)108 657.6 S(ar *).15 E +F2(get_history_e)2.5 E -.1(ve)-.15 G(nt).1 E F0(\()4.166 E F1(const c)A +(har *string)-.15 E 1.666(,i)-.1 G(nt *cinde)-1.666 E -.834(x, int)-.2 F +(qc)2.5 E(har)-.15 E F0(\))3.332 E .262(Returns the te)108 669.6 R .262 +(xt of the history e)-.15 F -.15(ve)-.25 G .262(nt be).15 F .263 +(ginning at)-.15 F F1(string)2.763 E F0(+)2.763 E F1(*cinde)2.763 E(x) +-.2 E F0(.)A F1(*cinde)5.263 E(x)-.2 E F0 .263 +(is modi\214ed to point to after the)2.763 F -2.15 -.25(ev e)108 681.6 T +.71(nt speci\214er).25 F 5.71(.A)-.55 G 3.21(tf)-5.71 G .71 +(unction entry)-3.21 F(,)-.65 E F1(cinde)3.21 E(x)-.2 E F0 .709 +(points to the inde)3.21 F 3.209(xi)-.15 G(nto)-3.209 E F1(string)3.209 +E F0 .709(where the history e)3.209 F -.15(ve)-.25 G .709 +(nt speci\214ca-).15 F .527(tion be)108 693.6 R(gins.)-.15 E F1(qc)5.527 +E(har)-.15 E F0 .527(is a character that is allo)3.027 F .527 +(wed to end the e)-.25 F -.15(ve)-.25 G .528 +(nt speci\214cation in addition to the `).15 F(`normal')-.74 E(')-.74 E +(terminating characters.)108 705.6 Q F1 -.15(ch)108 729.6 S(ar **).15 E +F2(history_tok)2.5 E(enize)-.1 E F0(\()4.166 E F1(const c)A(har *string) +-.15 E F0(\))1.666 E(GNU History 4.3)72 768 Q(2002 January 31)131.79 E +(5)195.95 E EP +%%Page: 6 6 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E .239(Return an array of tok)108 84 R .239 +(ens parsed out of)-.1 F/F1 10/Times-Italic@0 SF(string)2.739 E F0 2.739 +(,m)C .238(uch as the shell might.)-2.739 F .238(The tok)5.238 F .238 +(ens are split on the charac-)-.1 F(ters in the)108 96 Q/F2 10 +/Times-Bold@0 SF(history_w)2.5 E(ord_delimiters)-.1 E F0 -.25(va)2.5 G +(riable, and shell quoting con).25 E -.15(ve)-.4 G(ntions are obe).15 E +(yed.)-.15 E F1 -.15(ch)108 120 S(ar *).15 E F2(history_ar)2.5 E +(g_extract)-.1 E F0(\()4.166 E F1(int \214r)A -.834(st, int)-.1 F -.834 +(last, const)2.5 F -.15(ch)2.5 G(ar *string).15 E F0(\))3.332 E .025 +(Extract a string se)108 132 R .025(gment consisting of the)-.15 F F1 +<8c72>2.526 E(st)-.1 E F0(through)2.526 E F1(last)2.526 E F0(ar)2.526 E +.026(guments present in)-.18 F F1(string)2.526 E F0 5.026(.A)C -.18(rg) +-5.026 G .026(uments are split).18 F(using)108 144 Q F2(history_tok)2.5 +E(enize\(\))-.1 E F0(.)A F2(History V)87 172.8 Q(ariables)-.92 E F0 +(This section describes the e)108 184.8 Q(xternally-visible v)-.15 E +(ariables e)-.25 E(xported by the GNU History Library)-.15 E(.)-.65 E F1 +(int)108 208.8 Q F2(history_base)2.5 E F0(The logical of)108 220.8 Q +(fset of the \214rst entry in the history list.)-.25 E F1(int)108 244.8 +Q F2(history_length)2.5 E F0 +(The number of entries currently stored in the history list.)108 256.8 Q +F1(int)108 280.8 Q F2(history_max_entries)2.5 E F0 +(The maximum number of history entries.)108 292.8 Q +(This must be changed using)5 E F2(sti\215e_history\(\))2.5 E F0(.)A F1 +-.15(ch)108 316.8 S(ar).15 E F2(history_expansion_char)2.5 E F0 +(The character that introduces a history e)108 328.8 Q -.15(ve)-.25 G +2.5(nt. The).15 F(def)2.5 E(ault is)-.1 E F2(!)2.5 E F0 5(.S)C +(etting this to 0 inhibits history e)-5 E(xpansion.)-.15 E F1 -.15(ch) +108 352.8 S(ar).15 E F2(history_subst_char)2.5 E F0 +(The character that in)108 364.8 Q -.2(vo)-.4 G -.1(ke).2 G 2.5(sw).1 G +(ord substitution if found at the start of a line.)-2.6 E(The def)5 E +(ault is)-.1 E F2(^)2.5 E F0(.)A F1 -.15(ch)108 388.8 S(ar).15 E F2 +(history_comment_char)2.5 E F0 .117(During tok)108 400.8 R .117 +(enization, if this character is seen as the \214rst character of a w) +-.1 F .117(ord, then it and all subsequent char)-.1 F(-)-.2 E .276 +(acters up to a ne)108 412.8 R .276 +(wline are ignored, suppressing history e)-.25 F .276 +(xpansion for the remainder of the line.)-.15 F .277(This is dis-)5.276 +F(abled by def)108 424.8 Q(ault.)-.1 E F1 -.15(ch)108 448.8 S(ar *).15 E +F2(history_w)2.5 E(ord_delimiters)-.1 E F0 +(The characters that separate tok)108 460.8 Q(ens for)-.1 E F2 +(history_tok)2.5 E(enize\(\))-.1 E F0 5(.T)C(he def)-5 E(ault v)-.1 E +(alue is)-.25 E F2 2.5("\\)2.5 G(t\\n\(\)<>;&|")-2.5 E F0(.)A F1 -.15 +(ch)108 484.8 S(ar *).15 E F2(history_no_expand_chars)2.5 E F0 2.054 +(The list of characters which inhibit history e)108 496.8 R 2.054 +(xpansion if found immediately follo)-.15 F(wing)-.25 E F2 +(history_expan-)4.554 E(sion_char)108 508.8 Q F0 5(.T)C(he def)-5 E +(ault is space, tab, ne)-.1 E(wline,)-.25 E F2(\\r)2.5 E F0 2.5(,a)C(nd) +-2.5 E F2(=)2.5 E F0(.)A F1 -.15(ch)108 532.8 S(ar *).15 E F2 +(history_sear)2.5 E(ch_delimiter_chars)-.18 E F0 .401(The list of addit\ +ional characters which can delimit a history search string, in addition\ + to space, tab,)108 544.8 R F1(:)2.901 E F0(and)2.901 E F1(?)2.902 E F0 +(in the case of a substring search.)108 556.8 Q(The def)5 E +(ault is empty)-.1 E(.)-.65 E F1(int)108 580.8 Q F2 +(history_quotes_inhibit_expansion)2.5 E F0 .625 +(If non-zero, single-quoted w)108 592.8 R .625 +(ords are not scanned for the history e)-.1 F .624(xpansion character) +-.15 F 5.624(.T)-.55 G .624(he def)-5.624 F .624(ault v)-.1 F .624 +(alue is)-.25 F(0.)108 604.8 Q F1(rl_lineb)108 628.8 Q(uf_func_t *)-.2 E +F2(history_inhibit_expansion_function)2.5 E F0 .347 +(This should be set to the address of a function that tak)108 640.8 R +.348(es tw)-.1 F 2.848(oa)-.1 G -.18(rg)-2.848 G .348(uments: a).18 F F2 +.348(char *)2.848 F F0(\()2.848 E F1(string)A F0 2.848(\)a)C .348(nd an) +-2.848 F F2(int)2.848 E F0(inde)2.848 E(x)-.15 E .228 +(into that string \()108 652.8 R F1(i)A F0 2.728(\). It)B .227 +(should return a non-zero v)2.727 F .227(alue if the history e)-.25 F +.227(xpansion starting at)-.15 F F1(string[i])2.727 E F0 .227 +(should not)2.727 F .019(be performed; zero if the e)108 664.8 R .019 +(xpansion should be done.)-.15 F .019 +(It is intended for use by applications lik)5.019 F(e)-.1 E F2(bash) +2.519 E F0 .019(that use)2.519 F(the history e)108 676.8 Q +(xpansion character for additional purposes.)-.15 E(By def)5 E +(ault, this v)-.1 E(ariable is set to)-.25 E F2(NULL)2.5 E F0(.)A/F3 +10.95/Times-Bold@0 SF(FILES)72 693.6 Q F1(~/.history)109.666 705.6 Q F0 +(Def)144 717.6 Q(ault \214lename for reading and writing sa)-.1 E -.15 +(ve)-.2 G 2.5(dh).15 G(istory)-2.5 E(GNU History 4.3)72 768 Q +(2002 January 31)131.79 E(6)195.95 E EP +%%Page: 7 7 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 357.18(Y\(3\) HIST)-.65 F +(OR)-.18 E(Y\(3\))-.65 E/F1 10.95/Times-Bold@0 SF(SEE ALSO)72 84 Q/F2 10 +/Times-Italic@0 SF(The Gnu Readline Libr)108 96 Q(ary)-.15 E F0 2.5(,B)C +(rian F)-2.5 E(ox and Chet Rame)-.15 E(y)-.15 E F2(The Gnu History Libr) +108 108 Q(ary)-.15 E F0 2.5(,B)C(rian F)-2.5 E(ox and Chet Rame)-.15 E +(y)-.15 E F2(bash)108 120 Q F0(\(1\))A F2 -.37(re)108 132 S(adline).37 E +F0(\(3\))A F1 -.548(AU)72 148.8 S(THORS).548 E F0(Brian F)108 160.8 Q +(ox, Free Softw)-.15 E(are F)-.1 E(oundation)-.15 E(bfox@gnu.or)108 +172.8 Q(g)-.18 E(Chet Rame)108 189.6 Q 1.3 -.65(y, C)-.15 H(ase W).65 E +(estern Reserv)-.8 E 2.5(eU)-.15 G(ni)-2.5 E -.15(ve)-.25 G(rsity).15 E +(chet@ins.CWR)108 201.6 Q(U.Edu)-.4 E F1 -.11(BU)72 218.4 S 2.738(GR).11 +G(EPOR)-2.738 E(TS)-.438 E F0 .16(If you \214nd a b)108 230.4 R .16 +(ug in the)-.2 F/F3 10/Times-Bold@0 SF(history)2.66 E F0(library)2.66 E +2.66(,y)-.65 G .16(ou should report it.)-2.66 F .16 +(But \214rst, you should mak)5.16 F 2.66(es)-.1 G .16 +(ure that it really is)-2.66 F 2.5(ab)108 242.4 S +(ug, and that it appears in the latest v)-2.7 E(ersion of the)-.15 E F3 +(history)2.5 E F0(library that you ha)2.5 E -.15(ve)-.2 G(.).15 E .704 +(Once you ha)108 259.2 R 1.004 -.15(ve d)-.2 H .704(etermined that a b) +.15 F .704(ug actually e)-.2 F .704(xists, mail a b)-.15 F .705 +(ug report to)-.2 F F2 -.2(bu)3.205 G(g\255r).2 E(eadline)-.37 E F0(@)A +F2(gnu.or)A(g)-.37 E F0 5.705(.I)C 3.205(fy)-5.705 G(ou)-3.205 E(ha)108 +271.2 Q 1.81 -.15(ve a \214)-.2 H 1.51 +(x, you are welcome to mail that as well!).15 F 1.509 +(Suggestions and `philosophical' b)6.509 F 1.509(ug reports may be)-.2 F +(mailed to)108 283.2 Q F2 -.2(bu)2.5 G(g-r).2 E(eadline)-.37 E F0(@)A F2 +(gnu.or)A(g)-.37 E F0(or posted to the Usenet ne)2.5 E(wsgroup)-.25 E F3 +(gnu.bash.b)2.5 E(ug)-.2 E F0(.)A(Comments and b)108 300 Q +(ug reports concerning this manual page should be directed to)-.2 E F2 +-.15(ch)2.5 G(et@ins.CWR).15 E -.25(U.)-.4 G(Edu).25 E F0(.).25 E +(GNU History 4.3)72 768 Q(2002 January 31)131.79 E(7)195.95 E EP +%%Trailer +end +%%EOF diff --git a/readline-doc-4.3/doc/readline.0 b/readline-doc-4.3/doc/readline.0 new file mode 100644 index 0000000..87beeac --- /dev/null +++ b/readline-doc-4.3/doc/readline.0 @@ -0,0 +1,997 @@ +READLINE(3) READLINE(3) + + + +NNAAMMEE + readline - get a line from a user with editing + +SSYYNNOOPPSSIISS + ##iinncclluuddee <> + ##iinncclluuddee <> + ##iinncclluuddee <> + + _c_h_a_r _* + rreeaaddlliinnee (_c_o_n_s_t _c_h_a_r _*_p_r_o_m_p_t); + +CCOOPPYYRRIIGGHHTT + Readline is Copyright (C) 1989-2002 by the Free Software + Foundation, Inc. + +DDEESSCCRRIIPPTTIIOONN + rreeaaddlliinnee will read a line from the terminal and return it, + using pprroommpptt as a prompt. If pprroommpptt is NNUULLLL or the empty + string, no prompt is issued. The line returned is allo- + cated with _m_a_l_l_o_c(3); the caller must free it when fin- + ished. The line returned has the final newline removed, + so only the text of the line remains. + + rreeaaddlliinnee offers editing capabilities while the user is + entering the line. By default, the line editing commands + are similar to those of emacs. A vi-style line editing + interface is also available. + + This manual page describes only the most basic use of + rreeaaddlliinnee. Much more functionality is available; see _T_h_e + _G_N_U _R_e_a_d_l_i_n_e _L_i_b_r_a_r_y and _T_h_e _G_N_U _H_i_s_t_o_r_y _L_i_b_r_a_r_y for addi- + tional information. + +RREETTUURRNN VVAALLUUEE + rreeaaddlliinnee returns the text of the line read. A blank line + returns the empty string. If EEOOFF is encountered while + reading a line, and the line is empty, NNUULLLL is returned. + If an EEOOFF is read with a non-empty line, it is treated as + a newline. + +NNOOTTAATTIIOONN + An emacs-style notation is used to denote keystrokes. + Control keys are denoted by C-_k_e_y, e.g., C-n means Con- + trol-N. Similarly, _m_e_t_a keys are denoted by M-_k_e_y, so M-x + means Meta-X. (On keyboards without a _m_e_t_a key, M-_x means + ESC _x, i.e., press the Escape key then the _x key. This + makes ESC the _m_e_t_a _p_r_e_f_i_x. The combination M-C-_x means + ESC-Control-_x, or press the Escape key then hold the Con- + trol key while pressing the _x key.) + + Readline commands may be given numeric _a_r_g_u_m_e_n_t_s, which + normally act as a repeat count. Sometimes, however, it is + the sign of the argument that is significant. Passing a + negative argument to a command that acts in the forward + direction (e.g., kkiillll--lliinnee) causes that command to act in + a backward direction. Commands whose behavior with argu- + ments deviates from this are noted. + + When a command is described as _k_i_l_l_i_n_g text, the text + deleted is saved for possible future retrieval (_y_a_n_k_i_n_g). + The killed text is saved in a _k_i_l_l _r_i_n_g. Consecutive + kills cause the text to be accumulated into one unit, + which can be yanked all at once. Commands which do not + kill text separate the chunks of text on the kill ring. + +IINNIITTIIAALLIIZZAATTIIOONN FFIILLEE + Readline is customized by putting commands in an initial- + ization file (the _i_n_p_u_t_r_c file). The name of this file is + taken from the value of the IINNPPUUTTRRCC environment variable. + If that variable is unset, the default is _~_/_._i_n_p_u_t_r_c. + When a program which uses the readline library starts up, + the init file is read, and the key bindings and variables + are set. There are only a few basic constructs allowed in + the readline init file. Blank lines are ignored. Lines + beginning with a ## are comments. Lines beginning with a $$ + indicate conditional constructs. Other lines denote key + bindings and variable settings. Each program using this + library may add its own commands and bindings. + + For example, placing + + M-Control-u: universal-argument + or + C-Meta-u: universal-argument + + into the _i_n_p_u_t_r_c would make M-C-u execute the readline + command _u_n_i_v_e_r_s_a_l_-_a_r_g_u_m_e_n_t. + + The following symbolic character names are recognized + while processing key bindings: _D_E_L, _E_S_C, _E_S_C_A_P_E, _L_F_D, _N_E_W_- + _L_I_N_E, _R_E_T, _R_E_T_U_R_N, _R_U_B_O_U_T, _S_P_A_C_E, _S_P_C, and _T_A_B. + + In addition to command names, readline allows keys to be + bound to a string that is inserted when the key is pressed + (a _m_a_c_r_o). + + + KKeeyy BBiinnddiinnggss + The syntax for controlling key bindings in the _i_n_p_u_t_r_c + file is simple. All that is required is the name of the + command or the text of a macro and a key sequence to which + it should be bound. The name may be specified in one of + two ways: as a symbolic key name, possibly with _M_e_t_a_- or + _C_o_n_t_r_o_l_- prefixes, or as a key sequence. + + When using the form kkeeyynnaammee:_f_u_n_c_t_i_o_n_-_n_a_m_e or _m_a_c_r_o, _k_e_y_- + _n_a_m_e is the name of a key spelled out in English. For + example: + + Control-u: universal-argument + Meta-Rubout: backward-kill-word + Control-o: "> output" + + In the above example, _C_-_u is bound to the function uunniivveerr-- + ssaall--aarrgguummeenntt, _M_-_D_E_L is bound to the function bbaacckk-- + wwaarrdd--kkiillll--wwoorrdd, and _C_-_o is bound to run the macro + expressed on the right hand side (that is, to insert the + text ``> output'' into the line). + + In the second form, ""kkeeyysseeqq"":_f_u_n_c_t_i_o_n_-_n_a_m_e or _m_a_c_r_o, kkeeyy-- + sseeqq differs from kkeeyynnaammee above in that strings denoting an + entire key sequence may be specified by placing the + sequence within double quotes. Some GNU Emacs style key + escapes can be used, as in the following example, but the + symbolic character names are not recognized. + + "\C-u": universal-argument + "\C-x\C-r": re-read-init-file + "\e[11~": "Function Key 1" + + In this example, _C_-_u is again bound to the function uunnii-- + vveerrssaall--aarrgguummeenntt. _C_-_x _C_-_r is bound to the function + rree--rreeaadd--iinniitt--ffiillee, and _E_S_C _[ _1 _1 _~ is bound to insert the + text ``Function Key 1''. + + The full set of GNU Emacs style escape sequences available + when specifying key sequences is + \\CC-- control prefix + \\MM-- meta prefix + \\ee an escape character + \\\\ backslash + \\"" literal ", a double quote + \\'' literal ', a single quote + + In addition to the GNU Emacs style escape sequences, a + second set of backslash escapes is available: + \\aa alert (bell) + \\bb backspace + \\dd delete + \\ff form feed + \\nn newline + \\rr carriage return + \\tt horizontal tab + \\vv vertical tab + \\_n_n_n the eight-bit character whose value is the + octal value _n_n_n (one to three digits) + \\xx_H_H the eight-bit character whose value is the + hexadecimal value _H_H (one or two hex digits) + + When entering the text of a macro, single or double quotes + should 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. Back- + slash will quote any other character in the macro text, + including " and '. + + BBaasshh allows the current readline key bindings to be dis- + played or modified with the bbiinndd builtin command. The + editing mode may be switched during interactive use by + using the --oo option to the sseett builtin command. Other + programs using this library provide similar mechanisms. + The _i_n_p_u_t_r_c file may be edited and re-read if a program + does not provide any other means to incorporate new bind- + ings. + + VVaarriiaabblleess + Readline has variables that can be used to further cus- + tomize its behavior. A variable may be set in the _i_n_p_u_t_r_c + file with a statement of the form + + sseett _v_a_r_i_a_b_l_e_-_n_a_m_e _v_a_l_u_e + + Except where noted, readline variables can take the values + OOnn or OOffff (without regard to case). The variables and + their default values are: + + bbeellll--ssttyyllee ((aauuddiibbllee)) + Controls what happens when readline wants to ring + the terminal bell. If set to nnoonnee, readline never + rings the bell. If set to vviissiibbllee, readline uses a + visible bell if one is available. If set to aauuddii-- + bbllee, readline attempts to ring the terminal's bell. + ccoommmmeenntt--bbeeggiinn ((````##'''')) + The string that is inserted in vvii mode when the + iinnsseerrtt--ccoommmmeenntt command is executed. This command + is bound to MM--## in emacs mode and to ## in vi com- + mand mode. + ccoommpplleettiioonn--iiggnnoorree--ccaassee ((OOffff)) + If set to OOnn, readline performs filename matching + and completion in a case-insensitive fashion. + ccoommpplleettiioonn--qquueerryy--iitteemmss ((110000)) + This determines when the user is queried about + viewing the number of possible completions gener- + ated by the ppoossssiibbllee--ccoommpplleettiioonnss command. 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 vari- + able, the user is asked whether or not he wishes to + view them; otherwise they are simply listed on the + terminal. + ccoonnvveerrtt--mmeettaa ((OOnn)) + If set to OOnn, readline will convert characters with + the eighth bit set to an ASCII key sequence by + stripping the eighth bit and prefixing it with an + escape character (in effect, using escape as the + _m_e_t_a _p_r_e_f_i_x). + ddiissaabbllee--ccoommpplleettiioonn ((OOffff)) + If set to OOnn, readline will inhibit word comple- + tion. Completion characters will be inserted into + the line as if they had been mapped to sseellff--iinnsseerrtt. + eeddiittiinngg--mmooddee ((eemmaaccss)) + Controls whether readline begins with a set of key + bindings similar to emacs or vi. eeddiittiinngg--mmooddee can + be set to either eemmaaccss or vvii. + eennaabbllee--kkeeyyppaadd ((OOffff)) + When set to OOnn, readline will try to enable the + application keypad when it is called. Some systems + need this to enable the arrow keys. + eexxppaanndd--ttiillddee ((OOffff)) + If set to oonn, tilde expansion is performed when + readline attempts word completion. + hhiissttoorryy--pprreesseerrvvee--ppooiinntt + If set to oonn, the history code attempts to place + point at the same location on each history line + retrived with pprreevviioouuss--hhiissttoorryy or nneexxtt--hhiissttoorryy. + hhoorriizzoonnttaall--ssccrroollll--mmooddee ((OOffff)) + When set to OOnn, makes readline use a single line + for display, scrolling the input horizontally on a + single screen line when it becomes longer than the + screen width rather than wrapping to a new line. + iinnppuutt--mmeettaa ((OOffff)) + If set to OOnn, readline will enable eight-bit input + (that is, it will not clear the eighth bit in the + characters it reads), regardless of what the termi- + nal claims it can support. The name mmeettaa--ffllaagg is a + synonym for this variable. + iisseeaarrcchh--tteerrmmiinnaattoorrss ((````CC--[[ CC--JJ'''')) + The string of characters that should terminate an + incremental search without subsequently executing + the character as a command. If this variable has + not been given a value, the characters _E_S_C and _C_-_J + will terminate an incremental search. + kkeeyymmaapp ((eemmaaccss)) + Set the current readline keymap. The set of legal + keymap names is _e_m_a_c_s_, _e_m_a_c_s_-_s_t_a_n_d_a_r_d_, _e_m_a_c_s_-_m_e_t_a_, + _e_m_a_c_s_-_c_t_l_x_, _v_i_, _v_i_-_m_o_v_e_, _v_i_-_c_o_m_m_a_n_d, and _v_i_-_i_n_s_e_r_t. + _v_i is equivalent to _v_i_-_c_o_m_m_a_n_d; _e_m_a_c_s is equivalent + to _e_m_a_c_s_-_s_t_a_n_d_a_r_d. The default value is _e_m_a_c_s. + The value of eeddiittiinngg--mmooddee also affects the default + keymap. + mmaarrkk--ddiirreeccttoorriieess ((OOnn)) + If set to OOnn, completed directory names have a + slash appended. + mmaarrkk--mmooddiiffiieedd--lliinneess ((OOffff)) + If set to OOnn, history lines that have been modified + are displayed with a preceding asterisk (**). + mmaarrkk--ssyymmlliinnkkeedd--ddiirreeccttoorriieess ((OOffff)) + If set to OOnn, completed names which are symbolic + links to directories have a slash appended (subject + to the value of mmaarrkk--ddiirreeccttoorriieess). + mmaattcchh--hhiiddddeenn--ffiilleess ((OOnn)) + This variable, when set to OOnn, causes readline to + match files whose names begin with a `.' (hidden + files) when performing filename completion, unless + the leading `.' is supplied by the user in the + filename to be completed. + oouuttppuutt--mmeettaa ((OOffff)) + If set to OOnn, readline will display characters with + the eighth bit set directly rather than as a meta- + prefixed escape sequence. + ppaaggee--ccoommpplleettiioonnss ((OOnn)) + If set to OOnn, readline uses an internal _m_o_r_e-like + pager to display a screenful of possible comple- + tions at a time. + pprriinntt--ccoommpplleettiioonnss--hhoorriizzoonnttaallllyy ((OOffff)) + If set to OOnn, readline will display completions + with matches sorted horizontally in alphabetical + order, rather than down the screen. + sshhooww--aallll--iiff--aammbbiigguuoouuss ((OOffff)) + This alters the default behavior of the completion + functions. If set to oonn, words which have more + than one possible completion cause the matches to + be listed immediately instead of ringing the bell. + vviissiibbllee--ssttaattss ((OOffff)) + If set to OOnn, a character denoting a file's type as + reported by _s_t_a_t(2) is appended to the filename + when listing possible completions. + + CCoonnddiittiioonnaall CCoonnssttrruuccttss + 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 per- + formed as the result of tests. There are four parser + directives used. + + $$iiff The $$iiff 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. + + mmooddee The mmooddee== form of the $$iiff directive is used + to test whether readline is in emacs or vi + mode. This may be used in conjunction with + the sseett kkeeyymmaapp command, for instance, to set + bindings in the _e_m_a_c_s_-_s_t_a_n_d_a_r_d and _e_m_a_c_s_- + _c_t_l_x keymaps only if readline is starting + out in emacs mode. + + tteerrmm The tteerrmm== form may be used to include termi- + nal-specific key bindings, perhaps to bind + the key sequences output by the terminal's + function keys. The word on the right side + of the == is tested against the full name of + the terminal and the portion of the terminal + name before the first --. This allows _s_u_n to + match both _s_u_n and _s_u_n_-_c_m_d, for instance. + + aapppplliiccaattiioonn + The aapppplliiccaattiioonn construct is used to include + application-specific settings. Each program + using the readline library sets the _a_p_p_l_i_c_a_- + _t_i_o_n _n_a_m_e, and an initialization file can + test for a particular value. This could be + used to bind key sequences to functions use- + ful for a specific program. For instance, + the following command adds a key sequence + that quotes the current or previous word in + Bash: + + $$iiff Bash + # Quote the current or previous word + "\C-xq": "\eb\"\ef\"" + $$eennddiiff + + $$eennddiiff This command, as seen in the previous example, ter- + minates an $$iiff command. + + $$eellssee Commands in this branch of the $$iiff directive are + executed if the test fails. + + $$iinncclluuddee + This directive takes a single filename as an argu- + ment and reads commands and bindings from that + file. For example, the following directive would + read _/_e_t_c_/_i_n_p_u_t_r_c: + + $$iinncclluuddee _/_e_t_c_/_i_n_p_u_t_r_c + +SSEEAARRCCHHIINNGG + Readline provides commands for searching through the com- + mand history for lines containing a specified string. + There are two search modes: _i_n_c_r_e_m_e_n_t_a_l and _n_o_n_-_i_n_c_r_e_m_e_n_- + _t_a_l. + + 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 his- + tory for a particular string, type CC--rr. Typing CC--ss + searches forward through the history. The characters pre- + sent in the value of the iisseeaarrcchh--tteerrmmiinnaattoorrss variable are + used to terminate an incremental search. If that variable + has not been assigned a value the _E_s_c_a_p_e and CC--JJ charac- + ters will terminate an incremental search. CC--GG 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 + CC--ss or CC--rr as appropriate. This will search backward or + forward in the history for the next line matching the + search string typed so far. Any other key sequence bound + to a readline command will terminate the search and exe- + cute that command. For instance, a newline will terminate + the search and accept the line, thereby executing the com- + mand from the history list. A movement command will ter- + minate the search, make the last line found the current + line, and begin editing. + + 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. + +EEDDIITTIINNGG CCOOMMMMAANNDDSS + The following is a list of the names of the commands and + the default key sequences to which they are bound. Com- + mand names without an accompanying key sequence are + unbound by default. + + In the following descriptions, _p_o_i_n_t refers to the current + cursor position, and _m_a_r_k refers to a cursor position + saved by the sseett--mmaarrkk command. The text between the point + and mark is referred to as the _r_e_g_i_o_n. + + CCoommmmaannddss ffoorr MMoovviinngg + bbeeggiinnnniinngg--ooff--lliinnee ((CC--aa)) + Move to the start of the current line. + eenndd--ooff--lliinnee ((CC--ee)) + Move to the end of the line. + ffoorrwwaarrdd--cchhaarr ((CC--ff)) + Move forward a character. + bbaacckkwwaarrdd--cchhaarr ((CC--bb)) + Move back a character. + ffoorrwwaarrdd--wwoorrdd ((MM--ff)) + Move forward to the end of the next word. Words + are composed of alphanumeric characters (letters + and digits). + bbaacckkwwaarrdd--wwoorrdd ((MM--bb)) + Move back to the start of the current or previous + word. Words are composed of alphanumeric charac- + ters (letters and digits). + cclleeaarr--ssccrreeeenn ((CC--ll)) + Clear the screen leaving the current line at the + top of the screen. With an argument, refresh the + current line without clearing the screen. + rreeddrraaww--ccuurrrreenntt--lliinnee + Refresh the current line. + + CCoommmmaannddss ffoorr MMaanniippuullaattiinngg tthhee HHiissttoorryy + aacccceepptt--lliinnee ((NNeewwlliinnee,, RReettuurrnn)) + 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 aadddd__hhiissttoorryy(()). + If the line is a modified history line, the history + line is restored to its original state. + pprreevviioouuss--hhiissttoorryy ((CC--pp)) + Fetch the previous command from the history list, + moving back in the list. + nneexxtt--hhiissttoorryy ((CC--nn)) + Fetch the next command from the history list, mov- + ing forward in the list. + bbeeggiinnnniinngg--ooff--hhiissttoorryy ((MM--<<)) + Move to the first line in the history. + eenndd--ooff--hhiissttoorryy ((MM-->>)) + Move to the end of the input history, i.e., the + line currently being entered. + rreevveerrssee--sseeaarrcchh--hhiissttoorryy ((CC--rr)) + Search backward starting at the current line and + moving `up' through the history as necessary. This + is an incremental search. + ffoorrwwaarrdd--sseeaarrcchh--hhiissttoorryy ((CC--ss)) + Search forward starting at the current line and + moving `down' through the history as necessary. + This is an incremental search. + nnoonn--iinnccrreemmeennttaall--rreevveerrssee--sseeaarrcchh--hhiissttoorryy ((MM--pp)) + Search backward through the history starting at the + current line using a non-incremental search for a + string supplied by the user. + nnoonn--iinnccrreemmeennttaall--ffoorrwwaarrdd--sseeaarrcchh--hhiissttoorryy ((MM--nn)) + Search forward through the history using a non- + incremental search for a string supplied by the + user. + hhiissttoorryy--sseeaarrcchh--ffoorrwwaarrdd + Search forward through the history for the string + of characters between the start of the current line + and the current cursor position (the _p_o_i_n_t). This + is a non-incremental search. + hhiissttoorryy--sseeaarrcchh--bbaacckkwwaarrdd + 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. + yyaannkk--nntthh--aarrgg ((MM--CC--yy)) + Insert the first argument to the previous command + (usually the second word on the previous line) at + point. With an argument _n, insert the _nth word + from the previous command (the words in the previ- + ous command begin with word 0). A negative argu- + ment inserts the _nth word from the end of the pre- + vious command. + yyaannkk--llaasstt--aarrgg ((MM--..,, MM--__)) + Insert the last argument to the previous command + (the last word of the previous history entry). + With an argument, behave exactly like yyaannkk--nntthh--aarrgg. + Successive calls to yyaannkk--llaasstt--aarrgg move back through + the history list, inserting the last argument of + each line in turn. + + CCoommmmaannddss ffoorr CChhaannggiinngg TTeexxtt + ddeelleettee--cchhaarr ((CC--dd)) + 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 ddeelleettee--cchhaarr, then return EEOOFF. + bbaacckkwwaarrdd--ddeelleettee--cchhaarr ((RRuubboouutt)) + Delete the character behind the cursor. When given + a numeric argument, save the deleted text on the + kill ring. + ffoorrwwaarrdd--bbaacckkwwaarrdd--ddeelleettee--cchhaarr + 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. + qquuootteedd--iinnsseerrtt ((CC--qq,, CC--vv)) + Add the next character that you type to the line + verbatim. This is how to insert characters like + CC--qq, for example. + ttaabb--iinnsseerrtt ((MM--TTAABB)) + Insert a tab character. + sseellff--iinnsseerrtt ((aa,, bb,, AA,, 11,, !!,, ......)) + Insert the character typed. + ttrraannssppoossee--cchhaarrss ((CC--tt)) + Drag the character before point forward over the + character at point, moving point forward as well. + If point is at the end of the line, then this + transposes the two characters before point. Nega- + tive arguments have no effect. + ttrraannssppoossee--wwoorrddss ((MM--tt)) + Drag the word before point past the word after + point, moving point over that word as well. If + point is at the end of the line, this transposes + the last two words on the line. + uuppccaassee--wwoorrdd ((MM--uu)) + Uppercase the current (or following) word. With a + negative argument, uppercase the previous word, but + do not move point. + ddoowwnnccaassee--wwoorrdd ((MM--ll)) + Lowercase the current (or following) word. With a + negative argument, lowercase the previous word, but + do not move point. + ccaappiittaalliizzee--wwoorrdd ((MM--cc)) + Capitalize the current (or following) word. With a + negative argument, capitalize the previous word, + but do not move point. + oovveerrwwrriittee--mmooddee + 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 eemmaaccss + mode; vvii mode does overwrite differently. Each + call to _r_e_a_d_l_i_n_e_(_) starts in insert mode. In over- + write mode, characters bound to sseellff--iinnsseerrtt replace + the text at point rather than pushing the text to + the right. Characters bound to bbaacckk-- + wwaarrdd--ddeelleettee--cchhaarr replace the character before point + with a space. By default, this command is unbound. + + KKiilllliinngg aanndd YYaannkkiinngg + kkiillll--lliinnee ((CC--kk)) + Kill the text from point to the end of the line. + bbaacckkwwaarrdd--kkiillll--lliinnee ((CC--xx RRuubboouutt)) + Kill backward to the beginning of the line. + uunniixx--lliinnee--ddiissccaarrdd ((CC--uu)) + Kill backward from point to the beginning of the + line. The killed text is saved on the kill-ring. + kkiillll--wwhhoollee--lliinnee + Kill all characters on the current line, no matter + where point is. + kkiillll--wwoorrdd ((MM--dd)) + Kill from point 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 ffoorr-- + wwaarrdd--wwoorrdd. + bbaacckkwwaarrdd--kkiillll--wwoorrdd ((MM--RRuubboouutt)) + Kill the word behind point. Word boundaries are + the same as those used by bbaacckkwwaarrdd--wwoorrdd. + uunniixx--wwoorrdd--rruubboouutt ((CC--ww)) + Kill the word behind point, using white space as a + word boundary. The killed text is saved on the + kill-ring. + ddeelleettee--hhoorriizzoonnttaall--ssppaaccee ((MM--\\)) + Delete all spaces and tabs around point. + kkiillll--rreeggiioonn + Kill the text between the point and _m_a_r_k (saved + cursor position). This text is referred to as the + _r_e_g_i_o_n. + ccooppyy--rreeggiioonn--aass--kkiillll + Copy the text in the region to the kill buffer. + ccooppyy--bbaacckkwwaarrdd--wwoorrdd + Copy the word before point to the kill buffer. The + word boundaries are the same as bbaacckkwwaarrdd--wwoorrdd. + ccooppyy--ffoorrwwaarrdd--wwoorrdd + Copy the word following point to the kill buffer. + The word boundaries are the same as ffoorrwwaarrdd--wwoorrdd. + yyaannkk ((CC--yy)) + Yank the top of the kill ring into the buffer at + point. + yyaannkk--ppoopp ((MM--yy)) + Rotate the kill ring, and yank the new top. Only + works following yyaannkk or yyaannkk--ppoopp. + + NNuummeerriicc AArrgguummeennttss + ddiiggiitt--aarrgguummeenntt ((MM--00,, MM--11,, ......,, MM----)) + Add this digit to the argument already accumulat- + ing, or start a new argument. M-- starts a nega- + tive argument. + uunniivveerrssaall--aarrgguummeenntt + 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 uunniivveerrssaall--aarrgguummeenntt again ends the + numeric argument, but is otherwise ignored. As a + special case, if this command is immediately fol- + lowed 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 ini- + tially one, so executing this function the first + time makes the argument count four, a second time + makes the argument count sixteen, and so on. + + CCoommpplleettiinngg + ccoommpplleettee ((TTAABB)) + Attempt to perform completion on the text before + point. The actual completion performed is applica- + tion-specific. BBaasshh, for instance, attempts com- + pletion treating the text as a variable (if the + text begins with $$), username (if the text begins + with ~~), hostname (if the text begins with @@), or + command (including aliases and functions) in turn. + If none of these produces a match, filename comple- + tion is attempted. GGddbb, on the other hand, allows + completion of program functions and variables, and + only attempts filename completion under certain + circumstances. + ppoossssiibbllee--ccoommpplleettiioonnss ((MM--??)) + List the possible completions of the text before + point. + iinnsseerrtt--ccoommpplleettiioonnss ((MM--**)) + Insert all completions of the text before point + that would have been generated by ppoossssiibbllee--ccoommppllee-- + ttiioonnss. + mmeennuu--ccoommpplleettee + Similar to ccoommpplleettee, but replaces the word to be + completed with a single match from the list of pos- + sible completions. Repeated execution of mmeennuu--ccoomm-- + pplleettee steps through the list of possible comple- + tions, inserting each match in turn. At the end of + the list of completions, the bell is rung (subject + to the setting of 00aanndd tthhee oorriiggiinnaall tteexxtt iiss + rreessttoorreedd.. AAnn aarrgguummeenntt ooff _n mmoovveess _n ppoossiittiioonnss ffoorr-- + wwaarrdd iinn tthhee lliisstt ooff mmaattcchheess;; aa nneeggaattiivvee aarrgguummeenntt + mmaayy bbee uusseedd ttoo mmoovvee bbaacckkwwaarrdd tthhrroouugghh tthhee lliisstt.. + TThhiiss ccoommmmaanndd iiss iinntteennddeedd ttoo bbee bboouunndd ttoo TTAABB,, bbuutt iiss + uunnbboouunndd bbyy ddeeffaauulltt.. + ddeelleettee--cchhaarr--oorr--lliisstt + Deletes the character under the cursor if not at + the beginning or end of the line (like ddeelleettee-- + cchhaarr). If at the end of the line, behaves identi- + cally to ppoossssiibbllee--ccoommpplleettiioonnss. + + KKeeyybbooaarrdd MMaaccrrooss + ssttaarrtt--kkbbdd--mmaaccrroo ((CC--xx (()) + Begin saving the characters typed into the current + keyboard macro. + eenndd--kkbbdd--mmaaccrroo ((CC--xx )))) + Stop saving the characters typed into the current + keyboard macro and store the definition. + ccaallll--llaasstt--kkbbdd--mmaaccrroo ((CC--xx ee)) + Re-execute the last keyboard macro defined, by mak- + ing the characters in the macro appear as if typed + at the keyboard. + + MMiisscceellllaanneeoouuss + rree--rreeaadd--iinniitt--ffiillee ((CC--xx CC--rr)) + Read in the contents of the _i_n_p_u_t_r_c file, and + incorporate any bindings or variable assignments + found there. + aabboorrtt ((CC--gg)) + Abort the current editing command and ring the ter- + minal's bell (subject to the setting of + bbeellll--ssttyyllee). + ddoo--uuppppeerrccaassee--vveerrssiioonn ((MM--aa,, MM--bb,, MM--_x,, ......)) + If the metafied character _x is lowercase, run the + command that is bound to the corresponding upper- + case character. + pprreeffiixx--mmeettaa ((EESSCC)) + Metafy the next character typed. EESSCC ff is equiva- + lent to MMeettaa--ff. + uunnddoo ((CC--__,, CC--xx CC--uu)) + Incremental undo, separately remembered for each + line. + rreevveerrtt--lliinnee ((MM--rr)) + Undo all changes made to this line. This is like + executing the uunnddoo command enough times to return + the line to its initial state. + ttiillddee--eexxppaanndd ((MM--&&)) + Perform tilde expansion on the current word. + sseett--mmaarrkk ((CC--@@,, MM--<>)) + Set the mark to the point. If a numeric argument + is supplied, the mark is set to that position. + eexxcchhaannggee--ppooiinntt--aanndd--mmaarrkk ((CC--xx CC--xx)) + 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. + cchhaarraacctteerr--sseeaarrcchh ((CC--]])) + A character is read and point is moved to the next + occurrence of that character. A negative count + searches for previous occurrences. + cchhaarraacctteerr--sseeaarrcchh--bbaacckkwwaarrdd ((MM--CC--]])) + A character is read and point is moved to the pre- + vious occurrence of that character. A negative + count searches for subsequent occurrences. + iinnsseerrtt--ccoommmmeenntt ((MM--##)) + Without a numeric argument, the value of the read- + line ccoommmmeenntt--bbeeggiinn variable is inserted at the + beginning of the current line. If a numeric argu- + ment is supplied, this command acts as a toggle: + if the characters at the beginning of the line do + not match the value of ccoommmmeenntt--bbeeggiinn, the value is + inserted, otherwise the characters in ccoommmmeenntt--bbeeggiinn + are deleted from the beginning of the line. In + either case, the line is accepted as if a newline + had been typed. The default value of ccoommmmeenntt--bbeeggiinn + makes 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. + dduummpp--ffuunnccttiioonnss + 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 _i_n_p_u_t_r_c + file. + dduummpp--vvaarriiaabblleess + Print all of the settable variables and their val- + ues 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 _i_n_p_u_t_r_c + file. + dduummpp--mmaaccrrooss + Print all of the readline key sequences bound to + macros and the strings they ouput. If a numeric + argument is supplied, the output is formatted in + such a way that it can be made part of an _i_n_p_u_t_r_c + file. + eemmaaccss--eeddiittiinngg--mmooddee ((CC--ee)) + When in vvii command mode, this causes a switch to + eemmaaccss editing mode. + vvii--eeddiittiinngg--mmooddee ((MM--CC--jj)) + When in eemmaaccss editing mode, this causes a switch to + vvii editing mode. + +DDEEFFAAUULLTT KKEEYY BBIINNDDIINNGGSS + The following is a list of the default emacs and vi bind- + ings. Characters with the eighth bit set are written as + M-, and are referred to as _m_e_t_a_f_i_e_d characters. + The printable ASCII characters not mentioned in the list + of emacs standard bindings are bound to the sseellff--iinnsseerrtt + function, which just inserts the given character into the + input line. In vi insertion mode, all characters not + specifically mentioned are bound to sseellff--iinnsseerrtt. Charac- + ters assigned to signal generation by _s_t_t_y(1) or the ter- + minal driver, such as C-Z or C-C, retain that function. + Upper and lower case metafied characters are bound to the + same function in the emacs mode meta keymap. The remain- + ing characters are unbound, which causes readline to ring + the bell (subject to the setting of the bbeellll--ssttyyllee vari- + able). + + EEmmaaccss MMooddee + Emacs Standard bindings + + "C-@" set-mark + "C-A" beginning-of-line + "C-B" backward-char + "C-D" delete-char + "C-E" end-of-line + "C-F" forward-char + "C-G" abort + "C-H" backward-delete-char + "C-I" complete + "C-J" accept-line + "C-K" kill-line + "C-L" clear-screen + "C-M" accept-line + "C-N" next-history + "C-P" previous-history + "C-Q" quoted-insert + "C-R" reverse-search-history + "C-S" forward-search-history + "C-T" transpose-chars + "C-U" unix-line-discard + "C-V" quoted-insert + "C-W" unix-word-rubout + "C-Y" yank + "C-]" character-search + "C-_" undo + " " to "/" self-insert + "0" to "9" self-insert + ":" to "~" self-insert + "C-?" backward-delete-char + + Emacs Meta bindings + + "M-C-G" abort + "M-C-H" backward-kill-word + "M-C-I" tab-insert + "M-C-J" vi-editing-mode + "M-C-M" vi-editing-mode + "M-C-R" revert-line + "M-C-Y" yank-nth-arg + "M-C-[" complete + "M-C-]" character-search-backward + "M-space" set-mark + "M-#" insert-comment + "M-&" tilde-expand + "M-*" insert-completions + "M--" digit-argument + "M-." yank-last-arg + "M-0" digit-argument + "M-1" digit-argument + "M-2" digit-argument + "M-3" digit-argument + "M-4" digit-argument + "M-5" digit-argument + "M-6" digit-argument + "M-7" digit-argument + "M-8" digit-argument + "M-9" digit-argument + "M-<" beginning-of-history + "M-=" possible-completions + "M->" end-of-history + "M-?" possible-completions + "M-B" backward-word + "M-C" capitalize-word + "M-D" kill-word + "M-F" forward-word + "M-L" downcase-word + "M-N" non-incremental-forward-search-history + "M-P" non-incremental-reverse-search-history + "M-R" revert-line + "M-T" transpose-words + "M-U" upcase-word + "M-Y" yank-pop + "M-\" delete-horizontal-space + "M-~" tilde-expand + "M-C-?" backward-kill-word + "M-_" yank-last-arg + + Emacs Control-X bindings + + "C-XC-G" abort + "C-XC-R" re-read-init-file + "C-XC-U" undo + "C-XC-X" exchange-point-and-mark + "C-X(" start-kbd-macro + "C-X)" end-kbd-macro + "C-XE" call-last-kbd-macro + "C-XC-?" backward-kill-line + + + VVII MMooddee bbiinnddiinnggss + VI Insert Mode functions + + "C-D" vi-eof-maybe + "C-H" backward-delete-char + "C-I" complete + "C-J" accept-line + "C-M" accept-line + "C-R" reverse-search-history + "C-S" forward-search-history + "C-T" transpose-chars + "C-U" unix-line-discard + "C-V" quoted-insert + "C-W" unix-word-rubout + "C-Y" yank + "C-[" vi-movement-mode + "C-_" undo + " " to "~" self-insert + "C-?" backward-delete-char + + VI Command Mode functions + + "C-D" vi-eof-maybe + "C-E" emacs-editing-mode + "C-G" abort + "C-H" backward-char + "C-J" accept-line + "C-K" kill-line + "C-L" clear-screen + "C-M" accept-line + "C-N" next-history + "C-P" previous-history + "C-Q" quoted-insert + "C-R" reverse-search-history + "C-S" forward-search-history + "C-T" transpose-chars + "C-U" unix-line-discard + "C-V" quoted-insert + "C-W" unix-word-rubout + "C-Y" yank + "C-_" vi-undo + " " forward-char + "#" insert-comment + "$" end-of-line + "%" vi-match + "&" vi-tilde-expand + "*" vi-complete + "+" next-history + "," vi-char-search + "-" previous-history + "." vi-redo + "/" vi-search + "0" beginning-of-line + "1" to "9" vi-arg-digit + ";" vi-char-search + "=" vi-complete + "?" vi-search + "A" vi-append-eol + "B" vi-prev-word + "C" vi-change-to + "D" vi-delete-to + "E" vi-end-word + "F" vi-char-search + "G" vi-fetch-history + "I" vi-insert-beg + "N" vi-search-again + "P" vi-put + "R" vi-replace + "S" vi-subst + "T" vi-char-search + "U" revert-line + "W" vi-next-word + "X" backward-delete-char + "Y" vi-yank-to + "\" vi-complete + "^" vi-first-print + "_" vi-yank-arg + "`" vi-goto-mark + "a" vi-append-mode + "b" vi-prev-word + "c" vi-change-to + "d" vi-delete-to + "e" vi-end-word + "f" vi-char-search + "h" backward-char + "i" vi-insertion-mode + "j" next-history + "k" prev-history + "l" forward-char + "m" vi-set-mark + "n" vi-search-again + "p" vi-put + "r" vi-change-char + "s" vi-subst + "t" vi-char-search + "u" vi-undo + "w" vi-next-word + "x" vi-delete + "y" vi-yank-to + "|" vi-column + "~" vi-change-case + +SSEEEE AALLSSOO + _T_h_e _G_n_u _R_e_a_d_l_i_n_e _L_i_b_r_a_r_y, Brian Fox and Chet Ramey + _T_h_e _G_n_u _H_i_s_t_o_r_y _L_i_b_r_a_r_y, Brian Fox and Chet Ramey + _b_a_s_h(1) + +FFIILLEESS + _~_/_._i_n_p_u_t_r_c + Individual rreeaaddlliinnee initialization file + +AAUUTTHHOORRSS + Brian Fox, Free Software Foundation + bfox@gnu.org + + Chet Ramey, Case Western Reserve University + chet@ins.CWRU.Edu + +BBUUGG RREEPPOORRTTSS + If you find a bug in rreeaaddlliinnee,, you should report it. But + first, you should make sure that it really is a bug, and + that it appears in the latest version of the rreeaaddlliinnee + library that you have. + + Once you have determined that a bug actually exists, mail + a bug report to _b_u_g_-_r_e_a_d_l_i_n_e@_g_n_u_._o_r_g. If you have a fix, + you are welcome to mail that as well! Suggestions and + `philosophical' bug reports may be mailed to _b_u_g_-_r_e_a_d_- + _l_i_n_e@_g_n_u_._o_r_g or posted to the Usenet newsgroup + ggnnuu..bbaasshh..bbuugg. + + Comments and bug reports concerning this manual page + should be directed to _c_h_e_t_@_i_n_s_._C_W_R_U_._E_d_u. + +BBUUGGSS + It's too big and too slow. + + + +GNU Readline 4.3 2002 January 22 READLINE(3) diff --git a/readline-doc-4.3/doc/readline.dvi b/readline-doc-4.3/doc/readline.dvi new file mode 100644 index 0000000..3c1c30f Binary files /dev/null and b/readline-doc-4.3/doc/readline.dvi differ diff --git a/readline-doc-4.3/doc/readline.html b/readline-doc-4.3/doc/readline.html new file mode 100644 index 0000000..42485f5 --- /dev/null +++ b/readline-doc-4.3/doc/readline.html @@ -0,0 +1,5908 @@ + + + + + +GNU Readline Library: + + + + + + + + + + + + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    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. +

    + +

    + + + + +
    1. Command Line Editing  GNU Readline User's Manual.
    2. 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.
    +

    + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    + +

    1. Command Line Editing

    + +

    + +This chapter describes the basic features of the GNU +command line editing interface. +

    + +

    + + + + + +
    1.1 Introduction to Line Editing  Notation used in this text.
    1.2 Readline Interaction  The minimum set of commands for editing a line.
    1.3 Readline Init File  Customizing Readline from a user's view.
    1.4 Bindable Readline Commands  A description of most of the Readline commands + available for binding
    1.5 Readline vi Mode  A short description of how to make Readline + behave like the vi editor.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1 Introduction to Line Editing

    + +

    + +The following paragraphs describe the notation used to represent +keystrokes. +

    + +The text C-k is read as `Control-K' and describes the character +produced when the k key is pressed while the Control key +is depressed. +

    + +The text M-k is read as `Meta-K' and describes the character +produced when the Meta key (if you have one) is depressed, and the k +key is pressed. +The Meta key is labeled ALT on many keyboards. +On keyboards with two keys labeled ALT (usually to either side of +the space bar), the ALT on the left side is generally set to +work as a Meta key. +The 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 ALT key, or another key working as +a Meta key, the identical keystroke can be generated by typing ESC +first, and then typing k. +Either process is known as metafying the k key. +

    + +The text M-C-k is read as `Meta-Control-k' and describes the +character produced by metafying C-k. +

    + +In addition, several keys have their own names. Specifically, +DEL, ESC, LFD, SPC, RET, and TAB all +stand for themselves when seen in this text, or in an init file +(see section 1.3 Readline Init File). +If your keyboard lacks a LFD key, typing C-j will +produce the desired character. +The RET key may be labeled Return or Enter on +some keyboards. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2 Readline Interaction

    + +

    + +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 RET. You do not have to be at the +end of the line to press RET; the entire line is accepted +regardless of the location of the cursor within the line. +

    + +

    + + + + + +
    1.2.1 Readline Bare Essentials  The least you need to know about Readline.
    1.2.2 Readline Movement Commands  Moving about the input line.
    1.2.3 Readline Killing Commands  How to delete text, and how to get it back!
    1.2.4 Readline Arguments  Giving numeric arguments to commands.
    1.2.5 Searching for Commands in the History  Searching through previous lines.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.1 Readline Bare Essentials

    + +

    + +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 C-b to move the cursor to the left, and then +correct your mistake. Afterwards, you can move the cursor to the right +with 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. +

    + +

    +
    C-b +
    Move back one character. +
    C-f +
    Move forward one character. +
    DEL or Backspace +
    Delete the character to the left of the cursor. +
    C-d +
    Delete the character underneath the cursor. +
    Printing characters +
    Insert the character into the line at the cursor. +
    C-_ or C-x C-u +
    Undo the last editing command. You can undo all the way back to an +empty line. +
    +

    + +(Depending on your configuration, the Backspace key be set to +delete the character to the left of the cursor and the DEL key set +to delete the character underneath the cursor, like C-d, rather +than the character to the left of the cursor.) +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.2 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 C-b, C-f, +C-d, and DEL. Here are some commands for moving more rapidly +about the line. +

    + +

    +
    C-a +
    Move to the start of the line. +
    C-e +
    Move to the end of the line. +
    M-f +
    Move forward a word, where a word is composed of letters and digits. +
    M-b +
    Move backward a word. +
    C-l +
    Clear the screen, reprinting the current line at the top. +
    +

    + +Notice how C-f moves forward a character, while M-f moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.3 Readline Killing Commands

    + +

    + + + +

    + +Killing text means to delete the text from the line, but to save +it away for later use, usually by 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 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. + +

    + +Here is the list of commands for killing text. +

    + +

    +
    C-k +
    Kill the text from the current cursor position to the end of the line. +

    + +

    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 M-f. +

    + +

    M-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 M-b. +

    + +

    C-w +
    Kill from the cursor to the previous whitespace. This is different than +M-DEL because the word boundaries differ. +

    + +

    +

    + +Here is how to yank the text back into the line. Yanking +means to copy the most-recently-killed text from the kill buffer. +

    + +

    +
    C-y +
    Yank the most recently killed text back into the buffer at the cursor. +

    + +

    M-y +
    Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is C-y or M-y. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.4 Readline Arguments

    + +

    + +You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the 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 `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 (`-'), 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 C-d command an argument of 10, you could type `M-1 0 C-d', +which will delete the next ten characters on the input line. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.5 Searching for Commands in the History

    + +

    + +Readline provides commands for searching through the command history +for lines containing a specified string. +There are two search modes: incremental and 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 +C-r. Typing C-s searches forward through the history. +The characters present in the value of the isearch-terminators variable +are used to terminate an incremental search. +If that variable has not been assigned a value, the ESC and +C-J characters will terminate an incremental search. +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 C-r or +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 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 +C-rs 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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3 Readline Init File

    + +

    + +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 inputrc file, conventionally in his home directory. +The name of this +file is taken from the value of the environment variable INPUTRC. If +that variable is unset, the default is `~/.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 C-x C-r command re-reads this init file, thus +incorporating any changes that you might have made to it. +

    + +

    + +
    1.3.1 Readline Init File Syntax  Syntax for the commands in the inputrc file.
    + +
    + + +
    1.3.2 Conditional Init Constructs  Conditional key bindings in the inputrc file.
    + +
    + + +
    1.3.3 Sample Init File  An example inputrc file.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.1 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 `#' are comments. +Lines beginning with a `$' indicate conditional +constructs (see section 1.3.2 Conditional Init Constructs). Other lines +denote variable settings and key bindings. +

    + +

    +
    Variable Settings +
    You can modify the run-time behavior of Readline by +altering the values of variables in Readline +using the set command within the init file. +The syntax is simple: +

    + +
     
    set variable value
    +

    + +Here, for example, is how to +change from the default Emacs-like key binding to use +vi line editing commands: +

    + +
     
    set editing-mode vi
    +

    + +Variable names and values, where appropriate, are recognized without regard +to case. +

    + +A great deal of run-time behavior is changeable with the following +variables. +

    + + +

    + +
    bell-style +
    +Controls what happens when Readline wants to ring the terminal bell. +If set to `none', Readline never rings the bell. If set to +`visible', Readline uses a visible bell if one is available. +If set to `audible' (the default), Readline attempts to ring +the terminal's bell. +

    + +

    comment-begin +
    +The string to insert at the beginning of the line when the +insert-comment command is executed. The default value +is "#". +

    + +

    completion-ignore-case +
    If set to `on', Readline performs filename matching and completion +in a case-insensitive fashion. +The default value is `off'. +

    + +

    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 100. +

    + +

    convert-meta +
    +If set to `on', Readline will convert characters with the +eighth bit set to an ASCII key sequence by stripping the eighth +bit and prefixing an ESC character, converting them to a +meta-prefixed key sequence. The default value is `on'. +

    + +

    disable-completion +
    +If set to `On', Readline will inhibit word completion. +Completion characters will be inserted into the line as if they had +been mapped to self-insert. The default is `off'. +

    + +

    editing-mode +
    +The 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 `emacs' or `vi'. +

    + +

    enable-keypad +
    +When set to `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 `off'. +

    + +

    expand-tilde +
    +If set to `on', tilde expansion is performed when Readline +attempts word completion. The default is `off'. +

    + + +If set to `on', the history code attempts to place point at the +same location on each history line retrived with previous-history +or next-history. +

    + +

    horizontal-scroll-mode +
    +This variable can be set to either `on' or `off'. Setting it +to `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 `off'. +

    + +

    input-meta +
    + +If set to `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 `off'. The name meta-flag is a +synonym for this variable. +

    + +

    isearch-terminators +
    +The string of characters that should terminate an incremental search without +subsequently executing the character as a command (see section 1.2.5 Searching for Commands in the History). +If this variable has not been given a value, the characters ESC and +C-J will terminate an incremental search. +

    + +

    keymap +
    +Sets Readline's idea of the current keymap for key binding commands. +Acceptable keymap names are +emacs, +emacs-standard, +emacs-meta, +emacs-ctlx, +vi, +vi-move, +vi-command, and +vi-insert. +vi is equivalent to vi-command; emacs is +equivalent to emacs-standard. The default value is emacs. +The value of the editing-mode variable also affects the +default keymap. +

    + +

    mark-directories +
    If set to `on', completed directory names have a slash +appended. The default is `on'. +

    + +

    mark-modified-lines +
    +This variable, when set to `on', causes Readline to display an +asterisk (`*') at the start of history lines which have been modified. +This variable is `off' by default. +

    + +

    mark-symlinked-directories +
    +If set to `on', completed names which are symbolic links +to directories have a slash appended (subject to the value of +mark-directories). +The default is `off'. +

    + +

    match-hidden-files +
    +This variable, when set to `on', causes Readline to match files whose +names begin with a `.' (hidden files) when performing filename +completion, unless the leading `.' is +supplied by the user in the filename to be completed. +This variable is `on' by default. +

    + +

    output-meta +
    +If set to `on', Readline will display characters with the +eighth bit set directly rather than as a meta-prefixed escape +sequence. The default is `off'. +

    + +

    page-completions +
    +If set to `on', Readline uses an internal more-like pager +to display a screenful of possible completions at a time. +This variable is `on' by default. +

    + +

    print-completions-horizontally +
    If set to `on', Readline will display completions with matches +sorted horizontally in alphabetical order, rather than down the screen. +The default is `off'. +

    + +

    show-all-if-ambiguous +
    +This alters the default behavior of the completion functions. If +set to `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 `off'. +

    + +

    visible-stats +
    +If set to `on', a character denoting a file's type +is appended to the filename when listing possible +completions. The default is `off'. +

    + +

    +

    + +

    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 macro). +

    + +

    +
    keyname: function-name or macro +
    keyname is the name of a key spelled out in English. For example: +
     
    Control-u: universal-argument
    +Meta-Rubout: backward-kill-word
    +Control-o: "> output"
    +

    + +In the above example, C-u is bound to the function +universal-argument, +M-DEL is bound to the function backward-kill-word, and +C-o is bound to run the macro +expressed on the right hand side (that is, to insert the text +`> output' into the line). +

    + +A number of symbolic character names are recognized while +processing this key binding syntax: +DEL, +ESC, +ESCAPE, +LFD, +NEWLINE, +RET, +RETURN, +RUBOUT, +SPACE, +SPC, +and +TAB. +

    + +

    "keyseq": function-name or macro +
    keyseq differs from keyname above in that strings +denoting an entire key sequence can be specified, by placing +the key sequence in double quotes. Some GNU Emacs style key +escapes can be used, as in the following example, but the +special character names are not recognized. +

    + +
     
    "\C-u": universal-argument
    +"\C-x\C-r": re-read-init-file
    +"\e[11~": "Function Key 1"
    +

    + +In the above example, C-u is again bound to the function +universal-argument (just as it was in the first example), +`C-x C-r' is bound to the function re-read-init-file, +and `ESC [ 1 1 ~' is bound to insert +the text `Function Key 1'. +

    + +

    +

    + +The following GNU Emacs style escape sequences are available when +specifying key sequences: +

    + +

    +
    \C- +
    control prefix +
    \M- +
    meta prefix +
    \e +
    an escape character +
    \\ +
    backslash +
    \" +
    ", a double quotation mark +
    \' +
    ', a single quote or apostrophe +
    +

    + +In addition to the GNU Emacs style escape sequences, a second +set of backslash escapes is available: +

    + +

    +
    \a +
    alert (bell) +
    \b +
    backspace +
    \d +
    delete +
    \f +
    form feed +
    \n +
    newline +
    \r +
    carriage return +
    \t +
    horizontal tab +
    \v +
    vertical tab +
    \nnn +
    the eight-bit character whose value is the octal value nnn +(one to three digits) +
    \xHH +
    the eight-bit character whose value is the hexadecimal value HH +(one or two hex digits) +
    +

    + +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 `"' and `''. +For example, the following binding will make `C-x \' +insert a single `\' into the line: +
     
    "\C-x\\": "\\"
    +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.2 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. +

    + +

    +
    $if +
    The $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. +

    + +

    +
    mode +
    The mode= form of the $if directive is used to test +whether Readline is in emacs or vi mode. +This may be used in conjunction +with the `set keymap' command, for instance, to set bindings in +the emacs-standard and emacs-ctlx keymaps only if +Readline is starting out in emacs mode. +

    + +

    term +
    The 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 +`=' is tested against both the full name of the terminal and +the portion of the terminal name before the first `-'. This +allows sun to match both sun and sun-cmd, +for instance. +

    + +

    application +
    The application construct is used to include +application-specific settings. Each program using the Readline +library sets the 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: +
     
    $if Bash
    +# Quote the current or previous word
    +"\C-xq": "\eb\"\ef\""
    +$endif
    +
    +

    + +

    $endif +
    This command, as seen in the previous example, terminates an +$if command. +

    + +

    $else +
    Commands in this branch of the $if directive are executed if +the test fails. +

    + +

    $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 `/etc/inputrc': +
     
    $include /etc/inputrc
    +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.3 Sample Init File

    + +

    + +Here is an example of an inputrc file. This illustrates key +binding, variable assignment, and conditional syntax. +

    + +
     
    # 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
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4 Bindable Readline Commands

    + +

    + +

    + + + + + + + + +
    1.4.1 Commands For Moving  Moving about the line.
    1.4.2 Commands For Manipulating The History  Getting at previous lines.
    1.4.3 Commands For Changing Text  Commands for changing text.
    1.4.4 Killing And Yanking  Commands for killing and yanking.
    1.4.5 Specifying Numeric Arguments  Specifying numeric arguments, repeat counts.
    1.4.6 Letting Readline Type For You  Getting Readline to do the typing for you.
    1.4.7 Keyboard Macros  Saving and re-executing typed characters
    1.4.8 Some Miscellaneous Commands  Other miscellaneous commands.
    +

    + +This section describes Readline commands that may be bound to key +sequences. +Command names without an accompanying key sequence are unbound by default. +

    + +In the following descriptions, point refers to the current cursor +position, and mark refers to a cursor position saved by the +set-mark command. +The text between the point and mark is referred to as the region. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.1 Commands For Moving

    + +
    + +
    beginning-of-line (C-a) +
    +Move to the start of the current line. +

    + + +

    end-of-line (C-e) +
    +Move to the end of the line. +

    + + +

    forward-char (C-f) +
    +Move forward a character. +

    + + +

    backward-char (C-b) +
    +Move back a character. +

    + + +

    forward-word (M-f) +
    +Move forward to the end of the next word. Words are composed of +letters and digits. +

    + + +

    backward-word (M-b) +
    +Move back to the start of the current or previous word. Words are +composed of letters and digits. +

    + + +

    clear-screen (C-l) +
    +Clear the screen and redraw the current line, +leaving the current line at the top of the screen. +

    + + +

    redraw-current-line () +
    +Refresh the current line. By default, this is unbound. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.2 Commands For Manipulating The History

    + +

    + +

    + +
    accept-line (Newline or Return) +
    +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 +add_history(). +If this line is a modified history line, the history line is restored +to its original state. +

    + + +

    previous-history (C-p) +
    +Move `back' through the history list, fetching the previous command. +

    + + +

    next-history (C-n) +
    +Move `forward' through the history list, fetching the next command. +

    + + +

    beginning-of-history (M-<) +
    +Move to the first line in the history. +

    + + +

    end-of-history (M->) +
    +Move to the end of the input history, i.e., the line currently +being entered. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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 n, +insert the nth word from the previous command (the words +in the previous command begin with word 0). A negative argument +inserts the nth word from the end of the previous command. +

    + + +

    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 yank-nth-arg. +Successive calls to yank-last-arg move back through the history +list, inserting the last argument of each line in turn. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.3 Commands For Changing Text

    + +

    + +

    + +
    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 delete-char, then +return EOF. +

    + + +

    backward-delete-char (Rubout) +
    +Delete the character behind the cursor. A numeric argument means +to kill the characters instead of deleting them. +

    + + +

    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. +

    + + +

    quoted-insert (C-q or C-v) +
    +Add the next character typed to the line verbatim. This is +how to insert key sequences like C-q, for example. +

    + + +

    tab-insert (M-TAB) +
    +Insert a tab character. +

    + + +

    self-insert (a, b, A, 1, !, ...) +
    +Insert yourself. +

    + + +

    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. +

    + + +

    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. +

    + + +

    upcase-word (M-u) +
    +Uppercase the current (or following) word. With a negative argument, +uppercase the previous word, but do not move the cursor. +

    + + +

    downcase-word (M-l) +
    +Lowercase the current (or following) word. With a negative argument, +lowercase the previous word, but do not move the cursor. +

    + + +

    capitalize-word (M-c) +
    +Capitalize the current (or following) word. With a negative argument, +capitalize the previous word, but do not move the cursor. +

    + + +

    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 +emacs mode; vi mode does overwrite differently. +Each call to readline() starts in insert mode. +

    + +In overwrite mode, characters bound to self-insert replace +the text at point rather than pushing the text to the right. +Characters bound to backward-delete-char replace the character +before point with a space. +

    + +By default, this command is unbound. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.4 Killing And Yanking

    + +

    + +

    + + +
    kill-line (C-k) +
    +Kill the text from point to the end of the line. +

    + + +

    backward-kill-line (C-x Rubout) +
    +Kill backward to the beginning of the line. +

    + + +

    unix-line-discard (C-u) +
    +Kill backward from the cursor to the beginning of the current line. +

    + + +

    kill-whole-line () +
    +Kill all characters on the current line, no matter where point is. +By default, this is unbound. +

    + + +

    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 forward-word. +

    + + +

    backward-kill-word (M-DEL) +
    +Kill the word behind point. +Word boundaries are the same as backward-word. +

    + + +

    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. +

    + + +

    delete-horizontal-space () +
    +Delete all spaces and tabs around point. By default, this is unbound. +

    + + +

    kill-region () +
    +Kill the text in the current region. +By default, this command is unbound. +

    + + +

    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. +

    + + +

    copy-backward-word () +
    +Copy the word before point to the kill buffer. +The word boundaries are the same as backward-word. +By default, this command is unbound. +

    + + +

    copy-forward-word () +
    +Copy the word following point to the kill buffer. +The word boundaries are the same as forward-word. +By default, this command is unbound. +

    + + +

    yank (C-y) +
    +Yank the top of the kill ring into the buffer at point. +

    + + +

    yank-pop (M-y) +
    +Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is yank or yank-pop. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.5 Specifying Numeric Arguments

    + +
    + + +
    digit-argument (M-0, M-1, ... M--) +
    +Add this digit to the argument already accumulating, or start a new +argument. M-- starts a negative argument. +

    + + +

    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 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. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.6 Letting Readline Type For You

    + +

    + +

    + +
    complete (TAB) +
    +Attempt to perform completion on the text before point. +The actual completion performed is application-specific. +The default is filename completion. +

    + + +

    possible-completions (M-?) +
    +List the possible completions of the text before point. +

    + + +

    insert-completions (M-*) +
    +Insert all completions of the text before point that would have +been generated by possible-completions. +

    + + +

    menu-complete () +
    +Similar to complete, but replaces the word to be completed +with a single match from the list of possible completions. +Repeated execution of 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 bell-style) +and the original text is restored. +An argument of n moves 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 TAB, but is unbound +by default. +

    + + +

    delete-char-or-list () +
    +Deletes the character under the cursor if not at the beginning or +end of the line (like delete-char). +If at the end of the line, behaves identically to +possible-completions. +This command is unbound by default. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.7 Keyboard Macros

    + +
    + + +
    start-kbd-macro (C-x () +
    +Begin saving the characters typed into the current keyboard macro. +

    + + +

    end-kbd-macro (C-x )) +
    +Stop saving the characters typed into the current keyboard macro +and save the definition. +

    + + +

    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. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.8 Some Miscellaneous Commands

    + +
    + + +
    re-read-init-file (C-x C-r) +
    +Read in the contents of the inputrc file, and incorporate +any bindings or variable assignments found there. +

    + + +

    abort (C-g) +
    +Abort the current editing command and +ring the terminal's bell (subject to the setting of +bell-style). +

    + + +

    do-uppercase-version (M-a, M-b, M-x, ...) +
    +If the metafied character x is lowercase, run the command +that is bound to the corresponding uppercase character. +

    + + +

    prefix-meta (ESC) +
    +Metafy the next character typed. This is for keyboards +without a meta key. Typing `ESC f' is equivalent to typing +M-f. +

    + + +

    undo (C-_ or C-x C-u) +
    +Incremental undo, separately remembered for each line. +

    + + +

    revert-line (M-r) +
    +Undo all changes made to this line. This is like executing the undo +command enough times to get back to the beginning. +

    + + +

    tilde-expand (M-~) +
    +Perform tilde expansion on the current word. +

    + + +

    set-mark (C-@) +
    +Set the mark to the point. If a +numeric argument is supplied, the mark is set to that position. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    insert-comment (M-#) +
    +Without a numeric argument, the value of the 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 comment-begin, the value is inserted, otherwise +the characters in comment-begin are deleted from the beginning of +the line. +In either case, the line is accepted as if a newline had been typed. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    emacs-editing-mode (C-e) +
    +When in vi command mode, this causes a switch to emacs +editing mode. +

    + + +

    vi-editing-mode (M-C-j) +
    +When in emacs editing mode, this causes a switch to vi +editing mode. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.5 Readline vi Mode

    + +

    + +While the Readline library does not have a full set of vi +editing functions, it does contain enough to allow simple editing +of the line. The Readline vi mode behaves as specified in +the POSIX 1003.2 standard. +

    + +In order to switch interactively between emacs and vi +editing modes, use the command M-C-j (bound to emacs-editing-mode +when in vi mode and to vi-editing-mode in emacs mode). +The Readline default is emacs mode. +

    + +When you enter a line in vi mode, you are already placed in +`insertion' mode, as if you had typed an `i'. Pressing ESC +switches you into `command' mode, where you can edit the text of the +line with the standard vi movement keys, move to previous +history lines with `k' and subsequent lines with `j', and +so forth. +

    + +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. +

    + +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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2. Programming with GNU Readline

    + +

    + +This chapter describes the interface between the GNU Readline Library and +other programs. If you are a programmer, and you wish to include the +features found in GNU Readline +such as completion, line editing, and interactive history manipulation +in your own programs, this section is for you. +

    + +

    + + + + + + +
    2.1 Basic Behavior  Using the default behavior of Readline.
    2.2 Custom Functions  Adding your own functions to Readline.
    2.3 Readline Variables  Variables accessible to custom + functions.
    2.4 Readline Convenience Functions  Functions which Readline supplies to + aid in writing your own custom + functions.
    2.5 Readline Signal Handling  How Readline behaves when it receives signals.
    2.6 Custom Completers  Supplanting or supplementing Readline's + completion functions.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.1 Basic Behavior

    + +

    + +Many programs provide a command line interface, such as mail, +ftp, and 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 +gets() or fgets(). +

    + + + +

    + +The function readline() prints a prompt prompt +and then reads and returns a single line of text from the user. +If prompt is NULL or the empty string, no prompt is displayed. +The line readline returns is allocated with malloc(); +the caller should free() the line when it has finished with it. +The declaration for readline in ANSI C is +

    + +
     
    char *readline (const char *prompt);
    +

    + +So, one might say +
     
    char *line = readline ("Enter a line: ");
    +
    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 readline encounters an EOF while reading the line, and the +line is empty at that point, then (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 +C-p for example), you must call add_history() to save the +line away in a history list of such lines. +

    + +
     
    add_history (line);
    +

    + +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 gets() library +function, and has the advantage of no static buffer to overflow: +

    + +
     
    /* 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);
    +}
    +

    + +This function gives the user the default behaviour of TAB +completion: completion on file names. If you do not want Readline to +complete on filenames, you can change the binding of the TAB key +with rl_bind_key(). +

    + +
     
    int rl_bind_key (int key, rl_command_func_t *function);
    +

    + +rl_bind_key() takes two arguments: key is the character that +you want to bind, and function is the address of the function to +call when key is pressed. Binding TAB to rl_insert() +makes TAB insert itself. +rl_bind_key() returns non-zero if key is not a valid +ASCII character code (between 0 and 255). +

    + +Thus, to disable the default TAB behavior, the following suffices: +
     
    rl_bind_key ('\t', rl_insert);
    +

    + +This code should be executed once at the start of your program; you +might write a function called initialize_readline() which +performs this and other desired initializations, such as installing +custom completers (see section 2.6 Custom Completers). +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.2 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 <readline/readline.h> +in any file that uses Readline's features. Since some of the definitions +in readline.h use the stdio library, the file +<stdio.h> should be included before readline.h. +

    + +readline.h defines a C preprocessor variable that should +be treated as an integer, 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 0xMMmm. MM is the two-digit major +version number; mm is the two-digit minor version number. +For Readline 4.2, for example, the value of +RL_READLINE_VERSION would be 0x0402. +

    + +

    + + +
    2.2.1 Readline Typedefs  C declarations to make code readable.
    2.2.2 Writing a New Function  Variables and calling conventions.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.2.1 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 func as a pointer +to a function which takes two int arguments and returns an +int (this is the type of all of the Readline bindable functions). +Instead of the classic C declaration +

    + +int (*func)(); +

    + +or the ANSI-C style declaration +

    + +int (*func)(int, int); +

    + +we may write +

    + +rl_command_func_t *func; +

    + +The full list of function pointer types available is +

    + +

    +
    typedef int rl_command_func_t (int, int); +

    + +

    typedef char *rl_compentry_func_t (const char *, int); +

    + +

    typedef char **rl_completion_func_t (const char *, int, int); +

    + +

    typedef char *rl_quote_func_t (char *, int, char *); +

    + +

    typedef char *rl_dequote_func_t (char *, int); +

    + +

    typedef int rl_compignore_func_t (char **); +

    + +

    typedef void rl_compdisp_func_t (char **, int, int); +

    + +

    typedef int rl_hook_func_t (void); +

    + +

    typedef int rl_getc_func_t (FILE *); +

    + +

    typedef int rl_linebuf_func_t (char *, int); +

    + +

    typedef int rl_intfunc_t (int); +
    #define rl_ivoidfunc_t rl_hook_func_t +
    typedef int rl_icpfunc_t (char *); +
    typedef int rl_icppfunc_t (char **); +

    + +

    typedef void rl_voidfunc_t (void); +
    typedef void rl_vintfunc_t (int); +
    typedef void rl_vcpfunc_t (char *); +
    typedef void rl_vcppfunc_t (char **); +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.2.2 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 foo looks like +

    + +
     
    int foo (int count, int key)
    +

    + +where count is the numeric argument (or 1 if defaulted) and +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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.3 Readline Variables

    + +

    + +These variables are available to function writers. +

    + + +

    +
    Variable: char * rl_line_buffer +
    This is the line gathered so far. You are welcome to modify the +contents of the line, but see 2.4.5 Allowing Undoing. The +function rl_extend_line_buffer is available to increase +the memory allocated to rl_line_buffer. +
    +

    + + +

    +
    Variable: int rl_point +
    The offset of the current cursor position in rl_line_buffer +(the point). +
    +

    + + +

    +
    Variable: int rl_end +
    The number of characters present in rl_line_buffer. When +rl_point is at the end of the line, rl_point and +rl_end are equal. +
    +

    + + +

    +
    Variable: int rl_mark +
    The mark (saved position) in the current line. If set, the mark +and point define a region. +
    +

    + + +

    +
    Variable: int rl_done +
    Setting this to a non-zero value causes Readline to return the current +line immediately. +
    +

    + + +

    +
    Variable: int rl_num_chars_to_read +
    Setting this to a positive value before calling readline() causes +Readline to return after accepting that many characters, rather +than reading up to a character bound to accept-line. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: char * rl_prompt +
    The prompt Readline uses. This is set from the argument to +readline(), and should not be assigned to directly. +The rl_set_prompt() function (see section 2.4.6 Redisplay) may +be used to modify the prompt string after calling readline(). +
    +

    + + +

    +
    Variable: int rl_already_prompted +
    If an application wishes to display the prompt itself, rather than have +Readline do it the first time 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 readline() so +the redisplay functions can update the display properly. +The calling application is responsible for managing the value; Readline +never sets it. +
    +

    + + +

    +
    Variable: const char * rl_library_version +
    The version number of this revision of the library. +
    +

    + + +

    +
    Variable: int rl_readline_version +
    An integer encoding the current version of the library. The encoding is +of the form 0xMMmm, where MM is the two-digit major version +number, and mm is the two-digit minor version number. +For example, for Readline-4.2, rl_readline_version would have the +value 0x0402. +
    +

    + + +

    +
    Variable: int rl_gnu_readline_p +
    Always set to 1, denoting that this is GNU readline rather than some +emulation. +
    +

    + + +

    +
    Variable: 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 TERM environment variable +the first time it is called. +
    +

    + + +

    +
    Variable: 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 +(see section 1.3.2 Conditional Init Constructs). +
    +

    + + +

    +
    Variable: FILE * rl_instream +
    The stdio stream from which Readline reads input. +If NULL, Readline defaults to stdin. +
    +

    + + +

    +
    Variable: FILE * rl_outstream +
    The stdio stream to which Readline performs output. +If NULL, Readline defaults to stdout. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: rl_hook_func_t * rl_startup_hook +
    If non-zero, this is the address of a function to call just +before readline prints the first prompt. +
    +

    + + +

    +
    Variable: 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 readline +starts reading input characters. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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 +rl_getc, the default Readline character input function +(see section 2.4.8 Character Input). +
    +

    + + +

    +
    Variable: 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 rl_redisplay, the default Readline +redisplay function (see section 2.4.6 Redisplay). +
    +

    + + +

    +
    Variable: 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 +int flag that says whether or not to use eight-bit characters. +By default, this is set to rl_prep_terminal +(see section 2.4.9 Terminal Management). +
    +

    + + +

    +
    Variable: 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 +rl_prep_term_function. +By default, this is set to rl_deprep_terminal +(see section 2.4.9 Terminal Management). +
    +

    + + +

    +
    Variable: Keymap rl_executing_keymap +
    This variable is set to the keymap (see section 2.4.2 Selecting a Keymap) in which the +currently executing readline function was found. +
    +

    + + +

    +
    Variable: Keymap rl_binding_keymap +
    This variable is set to the keymap (see section 2.4.2 Selecting a Keymap) in which the +last key binding occurred. +
    +

    + + +

    +
    Variable: char * rl_executing_macro +
    This variable is set to the text of any currently-executing macro. +
    +

    + + +

    +
    Variable: int rl_readline_state +
    A variable with bit values that encapsulate the current Readline state. +A bit is set with the RL_SETSTATE macro, and unset with the +RL_UNSETSTATE macro. Use the RL_ISSTATE macro to test +whether a particular state bit is set. Current state bits include: +

    + +

    +
    RL_STATE_NONE +
    Readline has not yet been called, nor has it begun to intialize. +
    RL_STATE_INITIALIZING +
    Readline is initializing its internal data structures. +
    RL_STATE_INITIALIZED +
    Readline has completed its initialization. +
    RL_STATE_TERMPREPPED +
    Readline has modified the terminal modes to do its own input and redisplay. +
    RL_STATE_READCMD +
    Readline is reading a command from the keyboard. +
    RL_STATE_METANEXT +
    Readline is reading more input after reading the meta-prefix character. +
    RL_STATE_DISPATCHING +
    Readline is dispatching to a command. +
    RL_STATE_MOREINPUT +
    Readline is reading more input while executing an editing command. +
    RL_STATE_ISEARCH +
    Readline is performing an incremental history search. +
    RL_STATE_NSEARCH +
    Readline is performing a non-incremental history search. +
    RL_STATE_SEARCH +
    Readline is searching backward or forward through the history for a string. +
    RL_STATE_NUMERICARG +
    Readline is reading a numeric argument. +
    RL_STATE_MACROINPUT +
    Readline is currently getting its input from a previously-defined keyboard +macro. +
    RL_STATE_MACRODEF +
    Readline is currently reading characters defining a keyboard macro. +
    RL_STATE_OVERWRITE +
    Readline is in overwrite mode. +
    RL_STATE_COMPLETING +
    Readline is performing word completion. +
    RL_STATE_SIGHANDLER +
    Readline is currently executing the readline signal handler. +
    RL_STATE_UNDOING +
    Readline is performing an undo. +
    RL_STATE_DONE +
    Readline has read a key sequence bound to accept-line +and is about to return the line to the caller. +
    +

    + +

    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: int rl_editing_mode +
    Set to a value denoting Readline's current editing mode. A value of +1 means Readline is currently in emacs mode; 0 +means that vi mode is active. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4 Readline Convenience Functions

    + +

    + +

    + + + + + + + + + + + + + +
    2.4.1 Naming a Function  How to give a function you write a name.
    2.4.2 Selecting a Keymap  Making keymaps.
    2.4.3 Binding Keys  Changing Keymaps.
    2.4.4 Associating Function Names and Bindings  Translate function names to + key sequences.
    2.4.5 Allowing Undoing  How to make your functions undoable.
    2.4.6 Redisplay  Functions to control line display.
    2.4.7 Modifying Text  Functions to modify rl_line_buffer.
    2.4.8 Character Input  Functions to read keyboard input.
    2.4.9 Terminal Management  Functions to manage terminal settings.
    2.4.10 Utility Functions  Generally useful functions and hooks.
    2.4.11 Miscellaneous Functions  Functions that don't fall into any category.
    2.4.12 Alternate Interface  Using Readline in a `callback' fashion.
    2.4.13 A Readline Example  An example Readline function.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.1 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 +

    + +
     
    Meta-Rubout:	backward-kill-word
    +

    + +This binds the keystroke Meta-Rubout to the function +descriptively named 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: +

    + + +

    +
    Function: int rl_add_defun (const char *name, rl_command_func_t *function, int key) +
    Add name to the list of named functions. Make function be +the function that gets called. If key is not -1, then bind it to +function using rl_bind_key(). +
    +

    + +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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.2 Selecting a Keymap

    + +

    + +Key bindings take place on a 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. +

    + + +

    +
    Function: Keymap rl_make_bare_keymap (void) +
    Returns a new, empty keymap. The space for the keymap is allocated with +malloc(); the caller should free it by calling +rl_discard_keymap() when done. +
    +

    + + +

    +
    Function: Keymap rl_copy_keymap (Keymap map) +
    Return a new keymap which is a copy of map. +
    +

    + + +

    +
    Function: 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. +
    +

    + + +

    +
    Function: void rl_discard_keymap (Keymap keymap) +
    Free the storage associated with keymap. +
    +

    + +Readline has several internal keymaps. These functions allow you to +change which keymap is active. +

    + + +

    +
    Function: Keymap rl_get_keymap (void) +
    Returns the currently active keymap. +
    +

    + + +

    +
    Function: void rl_set_keymap (Keymap keymap) +
    Makes keymap the currently active keymap. +
    +

    + + +

    +
    Function: Keymap rl_get_keymap_by_name (const char *name) +
    Return the keymap matching name. name is one which would +be supplied in a set keymap inputrc line (see section 1.3 Readline Init File). +
    +

    + + +

    +
    Function: char * rl_get_keymap_name (Keymap keymap) +
    Return the name matching keymap. name is one which would +be supplied in a set keymap inputrc line (see section 1.3 Readline Init File). +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.3 Binding Keys

    + +

    + +Key sequences are associate with functions through the keymap. +Readline has several internal keymaps: emacs_standard_keymap, +emacs_meta_keymap, emacs_ctlx_keymap, +vi_movement_keymap, and vi_insertion_keymap. +emacs_standard_keymap is the default, and the examples in +this manual assume that. +

    + +Since 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 readline() will be overridden. +An alternate mechanism is to install custom key bindings in an +initialization function assigned to the rl_startup_hook variable +(see section 2.3 Readline Variables). +

    + +These functions manage key bindings. +

    + + +

    +
    Function: int rl_bind_key (int key, rl_command_func_t *function) +
    Binds key to function in the currently active keymap. +Returns non-zero in the case of an invalid key. +
    +

    + + +

    +
    Function: int rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map) +
    Bind key to function in map. Returns non-zero in the case +of an invalid key. +
    +

    + + +

    +
    Function: int rl_unbind_key (int key) +
    Bind key to the null function in the currently active keymap. +Returns non-zero in case of error. +
    +

    + + +

    +
    Function: int rl_unbind_key_in_map (int key, Keymap map) +
    Bind key to the null function in map. +Returns non-zero in case of error. +
    +

    + + +

    +
    Function: int rl_unbind_function_in_map (rl_command_func_t *function, Keymap map) +
    Unbind all keys that execute function in map. +
    +

    + + +

    +
    Function: int rl_unbind_command_in_map (const char *command, Keymap map) +
    Unbind all keys that are bound to command in map. +
    +

    + + +

    +
    Function: int rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map) +
    Bind the key sequence represented by the string keyseq to the function +function. This makes new keymaps as +necessary. The initial keymap in which to do bindings is map. +
    +

    + + +

    +
    Function: int rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) +
    Bind the key sequence represented by the string keyseq to the arbitrary +pointer data. type says what kind of data is pointed to by +data; this can be a function (ISFUNC), a macro +(ISMACR), or a keymap (ISKMAP). This makes new keymaps as +necessary. The initial keymap in which to do bindings is map. +
    +

    + + +

    +
    Function: int rl_parse_and_bind (char *line) +
    Parse line as if it had been read from the inputrc file and +perform any key bindings and variable assignments found +(see section 1.3 Readline Init File). +
    +

    + + +

    +
    Function: int rl_read_init_file (const char *filename) +
    Read keybindings and variable assignments from filename +(see section 1.3 Readline Init File). +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.4 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. +

    + + +

    +
    Function: rl_command_func_t * rl_named_function (const char *name) +
    Return the function with name name. +
    +

    + + +

    +
    Function: rl_command_func_t * rl_function_of_keyseq (const char *keyseq, Keymap map, int *type) +
    Return the function invoked by keyseq in keymap map. +If map is NULL, the current keymap is used. If type is +not NULL, the type of the object is returned in the int variable +it points to (one of ISFUNC, ISKMAP, or ISMACR). +
    +

    + + +

    +
    Function: char ** rl_invoking_keyseqs (rl_command_func_t *function) +
    Return an array of strings representing the key sequences used to +invoke function in the current keymap. +
    +

    + + +

    +
    Function: 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 function in the keymap map. +
    +

    + + +

    +
    Function: void rl_function_dumper (int readable) +
    Print the readline function names and the key sequences currently +bound to them to rl_outstream. If readable is non-zero, +the list is formatted in such a way that it can be made part of an +inputrc file and re-read. +
    +

    + + +

    +
    Function: void rl_list_funmap_names (void) +
    Print the names of all bindable Readline functions to rl_outstream. +
    +

    + + +

    +
    Function: 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 free() the array when you are done, but not the pointers. +
    +

    + + +

    +
    Function: int rl_add_funmap_entry (const char *name, rl_command_func_t *function) +
    Add name to the list of bindable Readline command names, and make +function the function to be called when name is invoked. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.5 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 rl_insert_text() or 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 rl_begin_undo_group() and +rl_end_undo_group(). +

    + +The types of events that can be undone are: +

    + +
     
    enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; 
    +

    + +Notice that UNDO_DELETE means to insert some text, and +UNDO_INSERT means to delete some text. That is, the undo code +tells what to undo, not how to undo it. UNDO_BEGIN and +UNDO_END are tags added by rl_begin_undo_group() and +rl_end_undo_group(). +

    + + +

    +
    Function: int rl_begin_undo_group (void) +
    Begins saving undo information in a group construct. The undo +information usually comes from calls to rl_insert_text() and +rl_delete_text(), but could be the result of calls to +rl_add_undo(). +
    +

    + + +

    +
    Function: int rl_end_undo_group (void) +
    Closes the current undo group started with rl_begin_undo_group +(). There should be one call to rl_end_undo_group() +for each call to rl_begin_undo_group(). +
    +

    + + +

    +
    Function: void rl_add_undo (enum undo_code what, int start, int end, char *text) +
    Remember how to undo an event (according to what). The affected +text runs from start to end, and encompasses text. +
    +

    + + +

    +
    Function: void rl_free_undo_list (void) +
    Free the existing undo list. +
    +

    + + +

    +
    Function: int rl_do_undo (void) +
    Undo the first thing on the undo list. Returns 0 if there was +nothing to undo, non-zero if something was undone. +
    +

    + +Finally, if you neither insert nor delete text, but directly modify the +existing text (e.g., change its case), call rl_modifying() +once, just before you modify the text. You must supply the indices of +the text range that you are going to modify. +

    + + +

    +
    Function: int rl_modifying (int start, int end) +
    Tell Readline to save the text between start and end as a +single undo unit. It is assumed that you will subsequently modify +that text. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.6 Redisplay

    + +

    + + +

    +
    Function: void rl_redisplay (void) +
    Change what's displayed on the screen to reflect the current contents +of rl_line_buffer. +
    +

    + + +

    +
    Function: int rl_forced_update_display (void) +
    Force the line to be updated and redisplayed, whether or not +Readline thinks the screen display is correct. +
    +

    + + +

    +
    Function: int rl_on_new_line (void) +
    Tell the update functions that we have moved onto a new (empty) line, +usually after ouputting a newline. +
    +

    + + +

    +
    Function: int rl_on_new_line_with_prompt (void) +
    Tell the update functions that we have moved onto a new line, with +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 rl_already_prompted. +
    +

    + + +

    +
    Function: int rl_reset_line_state (void) +
    Reset the display state to a clean state and redisplay the current line +starting on a new line. +
    +

    + + +

    +
    Function: int rl_crlf (void) +
    Move the cursor to the start of the next screen line. +
    +

    + + +

    +
    Function: int rl_show_char (int c) +
    Display character c on 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. +
    +

    + + +

    +
    Function: int rl_message (const char *, ...) +
    The arguments are a format string as would be supplied to printf, +possibly containing conversion specifications such as `%d', and +any additional arguments necessary to satisfy the conversion specifications. +The resulting string is displayed in the echo area. The echo area +is also used to display numeric arguments and search strings. +
    +

    + + +

    +
    Function: int rl_clear_message (void) +
    Clear the message in the echo area. +
    +

    + + +

    +
    Function: void rl_save_prompt (void) +
    Save the local Readline prompt display state in preparation for +displaying a new message in the message area with rl_message(). +
    +

    + + +

    +
    Function: void rl_restore_prompt (void) +
    Restore the local Readline prompt display state saved by the most +recent call to rl_save_prompt. +
    +

    + + +

    +
    Function: int rl_expand_prompt (char *prompt) +
    Expand any special character sequences in prompt and set up the +local Readline prompt redisplay variables. +This function is called by readline(). It may also be called to +expand the primary prompt if the rl_on_new_line_with_prompt() +function or rl_already_prompted variable is used. +It returns the number of visible characters on the last line of the +(possibly multi-line) prompt. +
    +

    + + +

    +
    Function: int rl_set_prompt (const char *prompt) +
    Make Readline use prompt for subsequent redisplay. This calls +rl_expand_prompt() to expand the prompt and sets rl_prompt +to the result. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.7 Modifying Text

    + +

    + + +

    +
    Function: int rl_insert_text (const char *text) +
    Insert text into the line at the current cursor position. +Returns the number of characters inserted. +
    +

    + + +

    +
    Function: int rl_delete_text (int start, int end) +
    Delete the text between start and end in the current line. +Returns the number of characters deleted. +
    +

    + + +

    +
    Function: char * rl_copy_text (int start, int end) +
    Return a copy of the text between start and end in +the current line. +
    +

    + + +

    +
    Function: int rl_kill_text (int start, int end) +
    Copy the text between start and 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 start is less than end, +the text is appended, otherwise prepended. If the last command was +not a kill, a new kill ring slot is used. +
    +

    + + +

    +
    Function: int rl_push_macro_input (char *macro) +
    Cause macro to be inserted into the line, as if it had been invoked +by a key bound to a macro. Not especially useful; use +rl_insert_text() instead. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.8 Character Input

    + +

    + + +

    +
    Function: 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 rl_pending_input (see section 2.3 Readline Variables) +and rl_stuff_char(), macros, and characters read from the keyboard. +While waiting for input, this function will call any function assigned to +the rl_event_hook variable. +
    +

    + + +

    +
    Function: int rl_getc (FILE *stream) +
    Return the next character available from stream, which is assumed to +be the keyboard. +
    +

    + + +

    +
    Function: int rl_stuff_char (int c) +
    Insert c into the Readline input stream. It will be "read" +before Readline attempts to read characters from the terminal with +rl_read_key(). Up to 512 characters may be pushed back. +rl_stuff_char returns 1 if the character was successfully inserted; +0 otherwise. +
    +

    + + +

    +
    Function: int rl_execute_next (int c) +
    Make c be the next command to be executed when rl_read_key() +is called. This sets rl_pending_input. +
    +

    + + +

    +
    Function: int rl_clear_pending_input (void) +
    Unset rl_pending_input, effectively negating the effect of any +previous call to rl_execute_next(). This works only if the +pending input has not already been read with rl_read_key(). +
    +

    + + +

    +
    Function: int rl_set_keyboard_input_timeout (int u) +
    While waiting for keyboard input in rl_read_key(), Readline will +wait for u microseconds for input before calling any function +assigned to rl_event_hook. The default waiting period is +one-tenth of a second. Returns the old timeout value. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.9 Terminal Management

    + +

    + + +

    +
    Function: void rl_prep_terminal (int meta_flag) +
    Modify the terminal settings for Readline's use, so readline() +can read a single character at a time from the keyboard. +The meta_flag argument should be non-zero if Readline should +read eight-bit input. +
    +

    + + +

    +
    Function: void rl_deprep_terminal (void) +
    Undo the effects of rl_prep_terminal(), leaving the terminal in +the state in which it was before the most recent call to +rl_prep_terminal(). +
    +

    + + +

    +
    Function: void rl_tty_set_default_bindings (Keymap kmap) +
    Read the operating system's terminal editing characters (as would be displayed +by stty) to their Readline equivalents. The bindings are performed +in kmap. +
    +

    + + +

    +
    Function: int rl_reset_terminal (const char *terminal_name) +
    Reinitialize Readline's idea of the terminal settings using +terminal_name as the terminal type (e.g., vt100). +If terminal_name is NULL, the value of the TERM +environment variable is used. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.10 Utility Functions

    + +

    + + +

    +
    Function: void rl_replace_line (const char *text, int clear_undo) +
    Replace the contents of rl_line_buffer with text. +The point and mark are preserved, if possible. +If clear_undo is non-zero, the undo list associated with the +current line is cleared. +
    +

    + + +

    +
    Function: int rl_extend_line_buffer (int len) +
    Ensure that rl_line_buffer has enough space to hold len +characters, possibly reallocating it if necessary. +
    +

    + + +

    +
    Function: int rl_initialize (void) +
    Initialize or re-initialize Readline's internal state. +It's not strictly necessary to call this; readline() calls it before +reading any input. +
    +

    + + +

    +
    Function: int rl_ding (void) +
    Ring the terminal bell, obeying the setting of bell-style. +
    +

    + + +

    +
    Function: int rl_alphabetic (int c) +
    Return 1 if c is an alphabetic character. +
    +

    + + +

    +
    Function: 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. matches is the list +of strings, in argv format, such as a list of completion matches. +len is the number of strings in matches, and max +is the length of the longest string in matches. This function uses +the setting of print-completions-horizontally to select how the +matches are displayed (see section 1.3.1 Readline Init File Syntax). +
    +

    + +The following are implemented as macros, defined in chardefs.h. +Applications should refrain from using them. +

    + + +

    +
    Function: int _rl_uppercase_p (int c) +
    Return 1 if c is an uppercase alphabetic character. +
    +

    + + +

    +
    Function: int _rl_lowercase_p (int c) +
    Return 1 if c is a lowercase alphabetic character. +
    +

    + + +

    +
    Function: int _rl_digit_p (int c) +
    Return 1 if c is a numeric character. +
    +

    + + +

    +
    Function: int _rl_to_upper (int c) +
    If c is a lowercase alphabetic character, return the corresponding +uppercase character. +
    +

    + + +

    +
    Function: int _rl_to_lower (int c) +
    If c is an uppercase alphabetic character, return the corresponding +lowercase character. +
    +

    + + +

    +
    Function: int _rl_digit_value (int c) +
    If c is a number, return the value it represents. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.11 Miscellaneous Functions

    + +

    + + +

    +
    Function: int rl_macro_bind (const char *keyseq, const char *macro, Keymap map) +
    Bind the key sequence keyseq to invoke the macro macro. +The binding is performed in map. When keyseq is invoked, the +macro will be inserted into the line. This function is deprecated; +use rl_generic_bind() instead. +
    +

    + + +

    +
    Function: void rl_macro_dumper (int readable) +
    Print the key sequences bound to macros and their values, using +the current keymap, to rl_outstream. +If readable is non-zero, the list is formatted in such a way +that it can be made part of an inputrc file and re-read. +
    +

    + + +

    +
    Function: int rl_variable_bind (const char *variable, const char *value) +
    Make the Readline variable variable have value. +This behaves as if the readline command +`set variable value' had been executed in an inputrc +file (see section 1.3.1 Readline Init File Syntax). +
    +

    + + +

    +
    Function: void rl_variable_dumper (int readable) +
    Print the readline variable names and their current values +to rl_outstream. +If readable is non-zero, the list is formatted in such a way +that it can be made part of an inputrc file and re-read. +
    +

    + + +

    +
    Function: int rl_set_paren_blink_timeout (int u) +
    Set the time interval (in microseconds) that Readline waits when showing +a balancing character when blink-matching-paren has been enabled. +
    +

    + + +

    +
    Function: char * rl_get_termcap (const char *cap) +
    Retrieve the string value of the termcap capability 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. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.12 Alternate Interface

    + +

    + +An alternate interface is available to plain readline(). Some +applications need to interleave keyboard I/O with file, device, or +window system I/O, typically by using a main loop to 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. +

    + + +

    +
    Function: 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 prompt. Save the value of 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. +
    +

    + + +

    +
    Function: void rl_callback_read_char (void) +
    Whenever an application determines that keyboard input is available, it +should call rl_callback_read_char(), which will read the next +character from the current input source. +If that character completes the line, rl_callback_read_char will +invoke the lhandler function saved by rl_callback_handler_install +to process the line. +Before calling the lhandler function, the terminal settings are +reset to the values they had before calling +rl_callback_handler_install. +If the lhandler function returns, +the terminal settings are modified for Readline's use again. +EOF is indicated by calling lhandler with a +NULL line. +
    +

    + + +

    +
    Function: 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 lhandler installed by rl_callback_handler_install +does not exit the program, either this function or the function referred +to by the value of rl_deprep_term_function should be called before +the program exits to reset the terminal settings. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.4.13 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 `M-c', then typing `M-c' would +change the case of the character under point. Typing `M-1 0 M-c' +would change the case of the following 10 characters, leaving the cursor on +the last character changed. +

    + +
     
    /* 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);
    +}
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.5 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 (SIGINT, SIGQUIT, SIGTERM, +SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU). +When one of these signals is received, the signal handler +will reset the terminal attributes to those that were in effect before +readline() was called, reset the signal handling to what it was +before 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 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 rl_free_line_state() below). +

    + +There is an additional Readline signal handler, for SIGWINCH, which +the kernel sends to a process whenever the terminal's size changes (for +example, if a user resizes an xterm). The Readline SIGWINCH +handler updates Readline's internal screen size information, and then calls +any SIGWINCH signal handler the calling application has installed. +Readline calls the application's 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 longjmp back to a main processing loop), it must +call 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 readline(), not in +a signal handler, so Readline's internal signal state is not corrupted. +

    + + +

    +
    Variable: int rl_catch_signals +
    If this variable is non-zero, Readline will install signal handlers for +SIGINT, SIGQUIT, SIGTERM, SIGALRM, +SIGTSTP, SIGTTIN, and SIGTTOU. +

    + +The default value of rl_catch_signals is 1. +

    +

    + + +

    +
    Variable: int rl_catch_sigwinch +
    If this variable is non-zero, Readline will install a signal handler for +SIGWINCH. +

    + +The default value of rl_catch_sigwinch is 1. +

    +

    + +If an application does not wish to have Readline catch any signals, or +to handle signals other than those Readline catches (SIGHUP, +for example), +Readline provides convenience functions to do the necessary terminal +and internal state cleanup upon receipt of a signal. +

    + + +

    +
    Function: void rl_cleanup_after_signal (void) +
    This function will reset the state of the terminal to what it was before +readline() was called, and remove the Readline signal handlers for +all signals, depending on the values of rl_catch_signals and +rl_catch_sigwinch. +
    +

    + + +

    +
    Function: 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 rl_cleanup_after_signal(). The +Readline signal handler for SIGINT calls this to abort the +current input line. +
    +

    + + +

    +
    Function: void rl_reset_after_signal (void) +
    This will reinitialize the terminal and reinstall any Readline signal +handlers, depending on the values of rl_catch_signals and +rl_catch_sigwinch. +
    +

    + +If an application does not wish Readline to catch SIGWINCH, it may +call rl_resize_terminal() or rl_set_screen_size() to force +Readline to update its idea of the terminal size when a SIGWINCH +is received. +

    + + +

    +
    Function: void rl_resize_terminal (void) +
    Update Readline's internal screen size by reading values from the kernel. +
    +

    + + +

    +
    Function: void rl_set_screen_size (int rows, int cols) +
    Set Readline's idea of the terminal size to rows rows and +cols columns. +
    +

    + +If an application does not want to install a SIGWINCH handler, but +is still interested in the screen dimensions, Readline's idea of the screen +size may be queried. +

    + + +

    +
    Function: 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. +
    +

    + +The following functions install and remove Readline's signal handlers. +

    + + +

    +
    Function: int rl_set_signals (void) +
    Install Readline's signal handler for SIGINT, SIGQUIT, +SIGTERM, SIGALRM, SIGTSTP, SIGTTIN, +SIGTTOU, and SIGWINCH, depending on the values of +rl_catch_signals and rl_catch_sigwinch. +
    +

    + + +

    +
    Function: int rl_clear_signals (void) +
    Remove all of the Readline signal handlers installed by +rl_set_signals(). +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.6 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. +

    + +

    + + + + +
    2.6.1 How Completing Works  The logic used to do completion.
    2.6.2 Completion Functions  Functions provided by Readline.
    2.6.3 Completion Variables  Variables which control completion.
    2.6.4 A Short Completion Example  An example of writing completer subroutines.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.6.1 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: +

    + +

      +
    1. +The user-interface function rl_complete(). This function is +called with the same arguments as other bindable Readline functions: +count and invoking_key. +It isolates the word to be completed and calls +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. +

      + +

    2. +The internal function rl_completion_matches() uses an +application-supplied 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 +rl_completion_entry_function. +

      + +

    3. +The generator function is called repeatedly from +rl_completion_matches(), returning a string each time. The +arguments to the generator function are text and state. +text is the partial word to be completed. 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 +(char *)NULL to inform rl_completion_matches() that there are +no more possibilities left. Usually the generator function computes the +list of possible completions when 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 malloc(); Readline +frees the strings when it has finished with them. +

      + +

    +

    + + +

    +
    Function: 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 +rl_completion_matches()). The default is to do filename completion. +
    +

    + + +

    +
    Variable: rl_compentry_func_t * rl_completion_entry_function +
    This is a pointer to the generator function for +rl_completion_matches(). +If the value of rl_completion_entry_function is +NULL then the default filename generator +function, rl_filename_completion_function(), is used. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.6.2 Completion Functions

    + +

    + +Here is the complete list of callable completion functions present in +Readline. +

    + + +

    +
    Function: int rl_complete_internal (int what_to_do) +
    Complete the word at or before point. what_to_do says what to do +with the completion. A value of `?' means list the possible +completions. `TAB' means do standard completion. `*' means +insert all of the possible completions. `!' means to display +all of the possible completions, if there is more than one, as well as +performing partial completion. +
    +

    + + +

    +
    Function: 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 +rl_completion_matches() and rl_completion_entry_function). +The default is to do filename +completion. This calls rl_complete_internal() with an +argument depending on invoking_key. +
    +

    + + +

    +
    Function: int rl_possible_completions (int count, int invoking_key) +
    List the possible completions. See description of rl_complete +(). This calls rl_complete_internal() with an argument of +`?'. +
    +

    + + +

    +
    Function: 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 rl_complete(). +This calls rl_complete_internal() with an argument of `*'. +
    +

    + + +

    +
    Function: int rl_completion_mode (rl_command_func_t *cfunc) +
    Returns the apppriate value to pass to rl_complete_internal() +depending on whether cfunc was called twice in succession and +the value of the show-all-if-ambiguous variable. +Application-specific completion functions may use this function to present +the same interface as rl_complete(). +
    +

    + + +

    +
    Function: 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 +text. If there are no completions, returns NULL. +The first entry in the returned array is the substitution for text. +The remaining entries are the possible completions. The array is +terminated with a NULL pointer. +

    + +entry_func is a function of two args, and returns a +char *. The first argument is text. The second is a +state argument; it is zero on the first call, and non-zero on subsequent +calls. entry_func returns a NULL pointer to the caller +when there are no more matches. +

    +

    + + +

    +
    Function: char * rl_filename_completion_function (const char *text, int state) +
    A generator function for filename completion in the general case. +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). +
    +

    + + +

    +
    Function: char * rl_username_completion_function (const char *text, int state) +
    A completion generator for usernames. text contains a partial +username preceded by a random character (usually `~'). As with all +completion generators, state is zero on the first call and non-zero +for subsequent calls. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.6.3 Completion Variables

    + +

    + + +

    +
    Variable: rl_compentry_func_t * rl_completion_entry_function +
    A pointer to the generator function for rl_completion_matches(). +NULL means to use rl_filename_completion_function(), the default +filename completer. +
    +

    + + +

    +
    Variable: rl_completion_func_t * rl_attempted_completion_function +
    A pointer to an alternative function to create matches. +The function is called with text, start, and end. +start and end are indices in rl_line_buffer defining +the boundaries of text, which is a character string. +If this function exists and returns NULL, or if this variable is +set to NULL, then rl_complete() will call the value of +rl_completion_entry_function to generate matches, otherwise the +array of strings returned will be used. +If this function sets the rl_attempted_completion_over +variable to a non-zero value, Readline will not perform its default +completion even if this function returns no matches. +
    +

    + + +

    +
    Variable: 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 rl_filename_quote_characters +appears in a completed filename. The function is called with +text, match_type, and quote_pointer. The text +is the filename to be quoted. The match_type is either +SINGLE_MATCH, if there is only one completion match, or +MULT_MATCH. Some functions use this to decide whether or not to +insert a closing quote character. The quote_pointer is a pointer +to any opening quote character the user typed. Some functions choose +to reset this character. +
    +

    + + +

    +
    Variable: 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 text, the text of the word +to be dequoted, and quote_char, which is the quoting character +that delimits the filename (usually `'' or `"'). If +quote_char is zero, the filename was not in an embedded string. +
    +

    + + +

    +
    Variable: 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: text, the text of the line, and index, the +index of the character in the line. It is used to decide whether a +character found in rl_completer_word_break_characters should be +used to break words for the completer. +
    +

    + + +

    +
    Variable: 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 NULL terminated array of matches. +The first element (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. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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: +(char **matches, int num_matches, int max_length) +where matches is the array of matching strings, +num_matches is the number of strings in that array, and +max_length is the length of the longest string in that array. +Readline provides a convenience function, rl_display_match_list, +that takes care of doing the display to Readline's output stream. That +function may be called from this hook. +
    +

    + + +

    +
    Variable: 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: +" \t\n\"\\'`@$><=;|&{(". +
    +

    + + +

    +
    Variable: const char * rl_basic_quote_characters +
    A list of quote characters which can cause a word break. +
    +

    + + +

    +
    Variable: const char * rl_completer_word_break_characters +
    The list of characters that signal a break between words for +rl_complete_internal(). The default list is the value of +rl_basic_word_break_characters. +
    +

    + + +

    +
    Variable: 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 +rl_completer_word_break_characters are treated as any other character, +unless they also appear within this list. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: const char * rl_special_prefixes +
    The list of characters that are word break characters, but should be +left in 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. +
    +

    + + +

    +
    Variable: 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. +
    +

    + + +

    +
    Variable: 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 (` '). Setting this to the null +character (`\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. +
    +

    + + +

    +
    Variable: int rl_completion_suppress_append +
    If non-zero, 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. +
    +

    + + +

    +
    Variable: 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 mark-directories variable. +This variable exists so that application completion functions can +override the user's global preference (set via the +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. +
    +

    + + +

    +
    Variable: int rl_ignore_completion_duplicates +
    If non-zero, then duplicates in the matches are removed. +The default is 1. +
    +

    + + +

    +
    Variable: int rl_filename_completion_desired +
    Non-zero means that the results of the matches are to be treated as +filenames. This is 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 +rl_filename_quote_characters and rl_filename_quoting_desired +is set to a non-zero value. +
    +

    + + +

    +
    Variable: 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 +rl_filename_quote_chars. This is 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 rl_filename_quoting_function. +
    +

    + + +

    +
    Variable: int rl_attempted_completion_over +
    If an application-specific completion function assigned to +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. +
    +

    + + +

    +
    Variable: int rl_completion_type +
    Set to a character describing the type of completion Readline is currently +attempting; see the description of rl_complete_internal() +(see section 2.6.2 Completion Functions) for the list of characters. +
    +

    + + +

    +
    Variable: int rl_inhibit_completion +
    If this variable is non-zero, completion is inhibited. The completion +character will be inserted as any other bound to self-insert. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    2.6.4 A Short Completion Example

    + +

    + +Here is a small application demonstrating the use of the GNU Readline +library. It is called fileman, and the source code resides in +`examples/fileman.c'. This sample application provides +completion of command names, line editing features, and access to the +history list. +

    + +
     
    /* 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);
    +}
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    Concept Index

    + +
    Jump to:   C +   +E +   +I +   +K +   +N +   +R +   +V +   +Y +   +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Index Entry Section

    C
    command editing1.2.1 Readline Bare Essentials

    E
    editing command lines1.2.1 Readline Bare Essentials

    I
    initialization file, readline1.3 Readline Init File
    interaction, readline1.2 Readline Interaction

    K
    kill ring1.2.3 Readline Killing Commands
    killing text1.2.3 Readline Killing Commands

    N
    notation, readline1.2.1 Readline Bare Essentials

    R
    readline, function2.1 Basic Behavior

    V
    variables, readline1.3.1 Readline Init File Syntax

    Y
    yanking text1.2.3 Readline Killing Commands

    Jump to:   C +   +E +   +I +   +K +   +N +   +R +   +V +   +Y +   +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    Function and Variable Index

    + +
    Jump to:   _ +   +
    +A +   +B +   +C +   +D +   +E +   +F +   +H +   +I +   +K +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +Y +   +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Index Entry Section

    _
    _rl_digit_p2.4.10 Utility Functions
    _rl_digit_value2.4.10 Utility Functions
    _rl_lowercase_p2.4.10 Utility Functions
    _rl_to_lower2.4.10 Utility Functions
    _rl_to_upper2.4.10 Utility Functions
    _rl_uppercase_p2.4.10 Utility Functions

    A
    abort (C-g)1.4.8 Some Miscellaneous Commands
    abort (C-g)1.4.8 Some Miscellaneous Commands
    accept-line (Newline or Return)1.4.2 Commands For Manipulating The History
    accept-line (Newline or Return)1.4.2 Commands For Manipulating The History

    B
    backward-char (C-b)1.4.1 Commands For Moving
    backward-char (C-b)1.4.1 Commands For Moving
    backward-delete-char (Rubout)1.4.3 Commands For Changing Text
    backward-delete-char (Rubout)1.4.3 Commands For Changing Text
    backward-kill-line (C-x Rubout)1.4.4 Killing And Yanking
    backward-kill-line (C-x Rubout)1.4.4 Killing And Yanking
    backward-kill-word (M-DEL)1.4.4 Killing And Yanking
    backward-kill-word (M-DEL)1.4.4 Killing And Yanking
    backward-word (M-b)1.4.1 Commands For Moving
    backward-word (M-b)1.4.1 Commands For Moving
    beginning-of-history (M-&#60;)1.4.2 Commands For Manipulating The History
    beginning-of-history (M-&#60;)1.4.2 Commands For Manipulating The History
    beginning-of-line (C-a)1.4.1 Commands For Moving
    beginning-of-line (C-a)1.4.1 Commands For Moving
    bell-style1.3.1 Readline Init File Syntax

    C
    call-last-kbd-macro (C-x e)1.4.7 Keyboard Macros
    call-last-kbd-macro (C-x e)1.4.7 Keyboard Macros
    capitalize-word (M-c)1.4.3 Commands For Changing Text
    capitalize-word (M-c)1.4.3 Commands For Changing Text
    character-search (C-])1.4.8 Some Miscellaneous Commands
    character-search (C-])1.4.8 Some Miscellaneous Commands
    character-search-backward (M-C-])1.4.8 Some Miscellaneous Commands
    character-search-backward (M-C-])1.4.8 Some Miscellaneous Commands
    clear-screen (C-l)1.4.1 Commands For Moving
    clear-screen (C-l)1.4.1 Commands For Moving
    comment-begin1.3.1 Readline Init File Syntax
    complete (TAB)1.4.6 Letting Readline Type For You
    complete (TAB)1.4.6 Letting Readline Type For You
    completion-query-items1.3.1 Readline Init File Syntax
    convert-meta1.3.1 Readline Init File Syntax
    copy-backward-word ()1.4.4 Killing And Yanking
    copy-backward-word ()1.4.4 Killing And Yanking
    copy-forward-word ()1.4.4 Killing And Yanking
    copy-forward-word ()1.4.4 Killing And Yanking
    copy-region-as-kill ()1.4.4 Killing And Yanking
    copy-region-as-kill ()1.4.4 Killing And Yanking

    D
    delete-char (C-d)1.4.3 Commands For Changing Text
    delete-char (C-d)1.4.3 Commands For Changing Text
    delete-char-or-list ()1.4.6 Letting Readline Type For You
    delete-char-or-list ()1.4.6 Letting Readline Type For You
    delete-horizontal-space ()1.4.4 Killing And Yanking
    delete-horizontal-space ()1.4.4 Killing And Yanking
    digit-argument (M-0, M-1, <small>...</small> M--)1.4.5 Specifying Numeric Arguments
    digit-argument (M-0, M-1, <small>...</small> M--)1.4.5 Specifying Numeric Arguments
    disable-completion1.3.1 Readline Init File Syntax
    do-uppercase-version (M-a, M-b, M-x, <small>...</small>)1.4.8 Some Miscellaneous Commands
    do-uppercase-version (M-a, M-b, M-x, <small>...</small>)1.4.8 Some Miscellaneous Commands
    downcase-word (M-l)1.4.3 Commands For Changing Text
    downcase-word (M-l)1.4.3 Commands For Changing Text
    dump-functions ()1.4.8 Some Miscellaneous Commands
    dump-functions ()1.4.8 Some Miscellaneous Commands
    dump-macros ()1.4.8 Some Miscellaneous Commands
    dump-macros ()1.4.8 Some Miscellaneous Commands
    dump-variables ()1.4.8 Some Miscellaneous Commands
    dump-variables ()1.4.8 Some Miscellaneous Commands

    E
    editing-mode1.3.1 Readline Init File Syntax
    emacs-editing-mode (C-e)1.4.8 Some Miscellaneous Commands
    emacs-editing-mode (C-e)1.4.8 Some Miscellaneous Commands
    enable-keypad1.3.1 Readline Init File Syntax
    end-kbd-macro (C-x ))1.4.7 Keyboard Macros
    end-kbd-macro (C-x ))1.4.7 Keyboard Macros
    end-of-history (M-&#62;)1.4.2 Commands For Manipulating The History
    end-of-history (M-&#62;)1.4.2 Commands For Manipulating The History
    end-of-line (C-e)1.4.1 Commands For Moving
    end-of-line (C-e)1.4.1 Commands For Moving
    exchange-point-and-mark (C-x C-x)1.4.8 Some Miscellaneous Commands
    exchange-point-and-mark (C-x C-x)1.4.8 Some Miscellaneous Commands
    expand-tilde1.3.1 Readline Init File Syntax

    F
    forward-backward-delete-char ()1.4.3 Commands For Changing Text
    forward-backward-delete-char ()1.4.3 Commands For Changing Text
    forward-char (C-f)1.4.1 Commands For Moving
    forward-char (C-f)1.4.1 Commands For Moving
    forward-search-history (C-s)1.4.2 Commands For Manipulating The History
    forward-search-history (C-s)1.4.2 Commands For Manipulating The History
    forward-word (M-f)1.4.1 Commands For Moving
    forward-word (M-f)1.4.1 Commands For Moving

    H
    history-preserve-point1.3.1 Readline Init File Syntax
    history-search-backward ()1.4.2 Commands For Manipulating The History
    history-search-backward ()1.4.2 Commands For Manipulating The History
    history-search-forward ()1.4.2 Commands For Manipulating The History
    history-search-forward ()1.4.2 Commands For Manipulating The History
    horizontal-scroll-mode1.3.1 Readline Init File Syntax

    I
    input-meta1.3.1 Readline Init File Syntax
    insert-comment (M-#)1.4.8 Some Miscellaneous Commands
    insert-comment (M-#)1.4.8 Some Miscellaneous Commands
    insert-completions (M-*)1.4.6 Letting Readline Type For You
    insert-completions (M-*)1.4.6 Letting Readline Type For You
    isearch-terminators1.3.1 Readline Init File Syntax

    K
    keymap1.3.1 Readline Init File Syntax
    kill-line (C-k)1.4.4 Killing And Yanking
    kill-line (C-k)1.4.4 Killing And Yanking
    kill-region ()1.4.4 Killing And Yanking
    kill-region ()1.4.4 Killing And Yanking
    kill-whole-line ()1.4.4 Killing And Yanking
    kill-whole-line ()1.4.4 Killing And Yanking
    kill-word (M-d)1.4.4 Killing And Yanking
    kill-word (M-d)1.4.4 Killing And Yanking

    M
    mark-modified-lines1.3.1 Readline Init File Syntax
    mark-symlinked-directories1.3.1 Readline Init File Syntax
    match-hidden-files1.3.1 Readline Init File Syntax
    menu-complete ()1.4.6 Letting Readline Type For You
    menu-complete ()1.4.6 Letting Readline Type For You
    meta-flag1.3.1 Readline Init File Syntax

    N
    next-history (C-n)1.4.2 Commands For Manipulating The History
    next-history (C-n)1.4.2 Commands For Manipulating The History
    non-incremental-forward-search-history (M-n)1.4.2 Commands For Manipulating The History
    non-incremental-forward-search-history (M-n)1.4.2 Commands For Manipulating The History
    non-incremental-reverse-search-history (M-p)1.4.2 Commands For Manipulating The History
    non-incremental-reverse-search-history (M-p)1.4.2 Commands For Manipulating The History

    O
    output-meta1.3.1 Readline Init File Syntax
    overwrite-mode ()1.4.3 Commands For Changing Text
    overwrite-mode ()1.4.3 Commands For Changing Text

    P
    page-completions1.3.1 Readline Init File Syntax
    possible-completions (M-?)1.4.6 Letting Readline Type For You
    possible-completions (M-?)1.4.6 Letting Readline Type For You
    prefix-meta (ESC)1.4.8 Some Miscellaneous Commands
    prefix-meta (ESC)1.4.8 Some Miscellaneous Commands
    previous-history (C-p)1.4.2 Commands For Manipulating The History
    previous-history (C-p)1.4.2 Commands For Manipulating The History

    Q
    quoted-insert (C-q or C-v)1.4.3 Commands For Changing Text
    quoted-insert (C-q or C-v)1.4.3 Commands For Changing Text

    R
    re-read-init-file (C-x C-r)1.4.8 Some Miscellaneous Commands
    re-read-init-file (C-x C-r)1.4.8 Some Miscellaneous Commands
    readline2.1 Basic Behavior
    redraw-current-line ()1.4.1 Commands For Moving
    redraw-current-line ()1.4.1 Commands For Moving
    reverse-search-history (C-r)1.4.2 Commands For Manipulating The History
    reverse-search-history (C-r)1.4.2 Commands For Manipulating The History
    revert-line (M-r)1.4.8 Some Miscellaneous Commands
    revert-line (M-r)1.4.8 Some Miscellaneous Commands
    rl_add_defun2.4.1 Naming a Function
    rl_add_funmap_entry2.4.4 Associating Function Names and Bindings
    rl_add_undo2.4.5 Allowing Undoing
    rl_alphabetic2.4.10 Utility Functions
    rl_already_prompted2.3 Readline Variables
    rl_attempted_completion_function2.6.3 Completion Variables
    rl_attempted_completion_over2.6.3 Completion Variables
    rl_basic_quote_characters2.6.3 Completion Variables
    rl_basic_word_break_characters2.6.3 Completion Variables
    rl_begin_undo_group2.4.5 Allowing Undoing
    rl_bind_key2.4.3 Binding Keys
    rl_bind_key_in_map2.4.3 Binding Keys
    rl_binding_keymap2.3 Readline Variables
    rl_callback_handler_install2.4.12 Alternate Interface
    rl_callback_handler_remove2.4.12 Alternate Interface
    rl_callback_read_char2.4.12 Alternate Interface
    rl_catch_signals2.5 Readline Signal Handling
    rl_catch_sigwinch2.5 Readline Signal Handling
    rl_char_is_quoted_p2.6.3 Completion Variables
    rl_cleanup_after_signal2.5 Readline Signal Handling
    rl_clear_message2.4.6 Redisplay
    rl_clear_pending_input2.4.8 Character Input
    rl_clear_signals2.5 Readline Signal Handling
    rl_complete2.6.1 How Completing Works
    rl_complete2.6.2 Completion Functions
    rl_complete_internal2.6.2 Completion Functions
    rl_completer_quote_characters2.6.3 Completion Variables
    rl_completer_word_break_characters2.6.3 Completion Variables
    rl_completion_append_character2.6.3 Completion Variables
    rl_completion_display_matches_hook2.6.3 Completion Variables
    rl_completion_entry_function2.6.1 How Completing Works
    rl_completion_entry_function2.6.3 Completion Variables
    rl_completion_mark_symlink_dirs2.6.3 Completion Variables
    rl_completion_matches2.6.2 Completion Functions
    rl_completion_mode2.6.2 Completion Functions
    rl_completion_query_items2.6.3 Completion Variables
    rl_completion_suppress_append2.6.3 Completion Variables
    rl_completion_type2.6.3 Completion Variables
    rl_copy_keymap2.4.2 Selecting a Keymap
    rl_copy_text2.4.7 Modifying Text
    rl_crlf2.4.6 Redisplay
    rl_delete_text2.4.7 Modifying Text
    rl_deprep_term_function2.3 Readline Variables
    rl_deprep_terminal2.4.9 Terminal Management
    rl_ding2.4.10 Utility Functions
    rl_directory_completion_hook2.6.3 Completion Variables
    rl_discard_keymap2.4.2 Selecting a Keymap
    rl_dispatching2.3 Readline Variables
    rl_display_match_list2.4.10 Utility Functions
    rl_do_undo2.4.5 Allowing Undoing
    rl_done2.3 Readline Variables
    rl_editing_mode2.3 Readline Variables
    rl_end2.3 Readline Variables
    rl_end_undo_group2.4.5 Allowing Undoing
    rl_erase_empty_line2.3 Readline Variables
    rl_event_hook2.3 Readline Variables
    rl_execute_next2.4.8 Character Input
    rl_executing_keymap2.3 Readline Variables
    rl_executing_macro2.3 Readline Variables
    rl_expand_prompt2.4.6 Redisplay
    rl_explicit_arg2.3 Readline Variables
    rl_extend_line_buffer2.4.10 Utility Functions
    rl_filename_completion_desired2.6.3 Completion Variables
    rl_filename_completion_function2.6.2 Completion Functions
    rl_filename_dequoting_function2.6.3 Completion Variables
    rl_filename_quote_characters2.6.3 Completion Variables
    rl_filename_quoting_desired2.6.3 Completion Variables
    rl_filename_quoting_function2.6.3 Completion Variables
    rl_forced_update_display2.4.6 Redisplay
    rl_free_line_state2.5 Readline Signal Handling
    rl_free_undo_list2.4.5 Allowing Undoing
    rl_function_dumper2.4.4 Associating Function Names and Bindings
    rl_function_of_keyseq2.4.4 Associating Function Names and Bindings
    rl_funmap_names2.4.4 Associating Function Names and Bindings
    rl_generic_bind2.4.3 Binding Keys
    rl_get_keymap2.4.2 Selecting a Keymap
    rl_get_keymap_by_name2.4.2 Selecting a Keymap
    rl_get_keymap_name2.4.2 Selecting a Keymap
    rl_get_screen_size2.5 Readline Signal Handling
    rl_get_termcap2.4.11 Miscellaneous Functions
    rl_getc2.4.8 Character Input
    rl_getc_function2.3 Readline Variables
    rl_gnu_readline_p2.3 Readline Variables
    rl_ignore_completion_duplicates2.6.3 Completion Variables
    rl_ignore_some_completions_function2.6.3 Completion Variables
    rl_inhibit_completion2.6.3 Completion Variables
    rl_initialize2.4.10 Utility Functions
    rl_insert_completions2.6.2 Completion Functions
    rl_insert_text2.4.7 Modifying Text
    rl_instream2.3 Readline Variables
    rl_invoking_keyseqs2.4.4 Associating Function Names and Bindings
    rl_invoking_keyseqs_in_map2.4.4 Associating Function Names and Bindings
    rl_kill_text2.4.7 Modifying Text
    rl_last_func2.3 Readline Variables
    rl_library_version2.3 Readline Variables
    rl_line_buffer2.3 Readline Variables
    rl_list_funmap_names2.4.4 Associating Function Names and Bindings
    rl_macro_bind2.4.11 Miscellaneous Functions
    rl_macro_dumper2.4.11 Miscellaneous Functions
    rl_make_bare_keymap2.4.2 Selecting a Keymap
    rl_make_keymap2.4.2 Selecting a Keymap
    rl_mark2.3 Readline Variables
    rl_message2.4.6 Redisplay
    rl_modifying2.4.5 Allowing Undoing
    rl_named_function2.4.4 Associating Function Names and Bindings
    rl_num_chars_to_read2.3 Readline Variables
    rl_numeric_arg2.3 Readline Variables
    rl_on_new_line2.4.6 Redisplay
    rl_on_new_line_with_prompt2.4.6 Redisplay
    rl_outstream2.3 Readline Variables
    rl_parse_and_bind2.4.3 Binding Keys
    rl_pending_input2.3 Readline Variables
    rl_point2.3 Readline Variables
    rl_possible_completions2.6.2 Completion Functions
    rl_pre_input_hook2.3 Readline Variables
    rl_prep_term_function2.3 Readline Variables
    rl_prep_terminal2.4.9 Terminal Management
    rl_prompt2.3 Readline Variables
    rl_push_macro_input2.4.7 Modifying Text
    rl_read_init_file2.4.3 Binding Keys
    rl_read_key2.4.8 Character Input
    rl_readline_name2.3 Readline Variables
    rl_readline_state2.3 Readline Variables
    rl_readline_version2.3 Readline Variables
    rl_redisplay2.4.6 Redisplay
    rl_redisplay_function2.3 Readline Variables
    rl_replace_line2.4.10 Utility Functions
    rl_reset_after_signal2.5 Readline Signal Handling
    rl_reset_line_state2.4.6 Redisplay
    rl_reset_terminal2.4.9 Terminal Management
    rl_resize_terminal2.5 Readline Signal Handling
    rl_restore_prompt2.4.6 Redisplay
    rl_save_prompt2.4.6 Redisplay
    rl_set_key2.4.3 Binding Keys
    rl_set_keyboard_input_timeout2.4.8 Character Input
    rl_set_keymap2.4.2 Selecting a Keymap
    rl_set_paren_blink_timeout2.4.11 Miscellaneous Functions
    rl_set_prompt2.4.6 Redisplay
    rl_set_screen_size2.5 Readline Signal Handling
    rl_set_signals2.5 Readline Signal Handling
    rl_show_char2.4.6 Redisplay
    rl_special_prefixes2.6.3 Completion Variables
    rl_startup_hook2.3 Readline Variables
    rl_stuff_char2.4.8 Character Input
    rl_terminal_name2.3 Readline Variables
    rl_tty_set_default_bindings2.4.9 Terminal Management
    rl_unbind_command_in_map2.4.3 Binding Keys
    rl_unbind_function_in_map2.4.3 Binding Keys
    rl_unbind_key2.4.3 Binding Keys
    rl_unbind_key_in_map2.4.3 Binding Keys
    rl_username_completion_function2.6.2 Completion Functions
    rl_variable_bind2.4.11 Miscellaneous Functions
    rl_variable_dumper2.4.11 Miscellaneous Functions

    S
    self-insert (a, b, A, 1, !, <small>...</small>)1.4.3 Commands For Changing Text
    self-insert (a, b, A, 1, !, <small>...</small>)1.4.3 Commands For Changing Text
    set-mark (C-@)1.4.8 Some Miscellaneous Commands
    set-mark (C-@)1.4.8 Some Miscellaneous Commands
    show-all-if-ambiguous1.3.1 Readline Init File Syntax
    start-kbd-macro (C-x ()1.4.7 Keyboard Macros
    start-kbd-macro (C-x ()1.4.7 Keyboard Macros

    T
    tab-insert (M-TAB)1.4.3 Commands For Changing Text
    tab-insert (M-TAB)1.4.3 Commands For Changing Text
    tilde-expand (M-~)1.4.8 Some Miscellaneous Commands
    tilde-expand (M-~)1.4.8 Some Miscellaneous Commands
    transpose-chars (C-t)1.4.3 Commands For Changing Text
    transpose-chars (C-t)1.4.3 Commands For Changing Text
    transpose-words (M-t)1.4.3 Commands For Changing Text
    transpose-words (M-t)1.4.3 Commands For Changing Text

    U
    undo (C-_ or C-x C-u)1.4.8 Some Miscellaneous Commands
    undo (C-_ or C-x C-u)1.4.8 Some Miscellaneous Commands
    universal-argument ()1.4.5 Specifying Numeric Arguments
    universal-argument ()1.4.5 Specifying Numeric Arguments
    unix-line-discard (C-u)1.4.4 Killing And Yanking
    unix-line-discard (C-u)1.4.4 Killing And Yanking
    unix-word-rubout (C-w)1.4.4 Killing And Yanking
    unix-word-rubout (C-w)1.4.4 Killing And Yanking
    upcase-word (M-u)1.4.3 Commands For Changing Text
    upcase-word (M-u)1.4.3 Commands For Changing Text

    V
    vi-editing-mode (M-C-j)1.4.8 Some Miscellaneous Commands
    vi-editing-mode (M-C-j)1.4.8 Some Miscellaneous Commands
    visible-stats1.3.1 Readline Init File Syntax

    Y
    yank (C-y)1.4.4 Killing And Yanking
    yank (C-y)1.4.4 Killing And Yanking
    yank-last-arg (M-. or M-_)1.4.2 Commands For Manipulating The History
    yank-last-arg (M-. or M-_)1.4.2 Commands For Manipulating The History
    yank-nth-arg (M-C-y)1.4.2 Commands For Manipulating The History
    yank-nth-arg (M-C-y)1.4.2 Commands For Manipulating The History
    yank-pop (M-y)1.4.4 Killing And Yanking
    yank-pop (M-y)1.4.4 Killing And Yanking

    Jump to:   _ +   +
    +A +   +B +   +C +   +D +   +E +   +F +   +H +   +I +   +K +   +M +   +N +   +O +   +P +   +Q +   +R +   +S +   +T +   +U +   +V +   +Y +   +

    + +


    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Table of Contents

    + +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Short Table of Contents

    +
    +1. Command Line Editing +
    +2. Programming with GNU Readline +
    +Concept Index +
    +Function and Variable Index +
    + +
    +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    About this document

    +This document was generated by Chet Ramey on June, 27 2002 +using texi2html +

    +The buttons in the navigation panels have the following meaning: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Button Name Go to From 1.2.3 go to
    + [ < ] +Back + +previous section in reading order + +1.2.2 +
    + [ > ] +Forward + +next section in reading order + +1.2.4 +
    + [ << ] +FastBack + +previous or up-and-previous section + +1.1 +
    + [ Up ] +Up + +up section + +1.2 +
    + [ >> ] +FastForward + +next or up-and-next section + +1.3 +
    + [Top] +Top + +cover (top) of document + +   +
    + [Contents] +Contents + +table of contents + +   +
    + [Index] +Index + +concept index + +   +
    + [ ? ] +About + +this page + +   +
    +

    +where the Example assumes that the current position +is at Subsubsection One-Two-Three of a document of +the following structure: +
      +
    • 1. Section One
    • +
        +
      • 1.1 Subsection One-One
      • +
          +
        • ...
        • +
        +
      • 1.2 Subsection One-Two
      • +
          +
        • 1.2.1 Subsubsection One-Two-One +
        • 1.2.2 Subsubsection One-Two-Two +
        • 1.2.3 Subsubsection One-Two-Three     +<== Current Position +
        • 1.2.4 Subsubsection One-Two-Four +
        +
      • 1.3 Subsection One-Three
      • +
          +
        • ...
        • +
        +
      • 1.4 Subsection One-Four
      • +
      +
    + +
    +
    + +This document was generated +by Chet Ramey on June, 27 2002 +using texi2html + + + diff --git a/readline-doc-4.3/doc/readline.info b/readline-doc-4.3/doc/readline.info new file mode 100644 index 0000000..57dbdfa --- /dev/null +++ b/readline-doc-4.3/doc/readline.info @@ -0,0 +1,3638 @@ +This is readline.info, produced by makeinfo version 4.1 from +/usr/homes/chet/src/bash/readline-src/doc/rlman.texinfo. + +INFO-DIR-SECTION Libraries +START-INFO-DIR-ENTRY +* Readline: (readline). The GNU readline library API +END-INFO-DIR-ENTRY + + 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. + + 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. + + +File: readline.info, Node: Top, Next: Command Line Editing, Up: (dir) + +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. + + +File: readline.info, Node: Command Line Editing, Next: Programming with GNU Readline, Prev: Top, Up: Top + +Command Line Editing +******************** + + This chapter describes the basic features of the GNU command line +editing interface. + +* 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. + + +File: readline.info, Node: Introduction and Notation, Next: Readline Interaction, Up: Command Line Editing + +Introduction to Line Editing +============================ + + The following paragraphs describe the notation used to represent +keystrokes. + + The text `C-k' is read as `Control-K' and describes the character +produced when the key is pressed while the Control key is depressed. + + The text `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 is pressed. The Meta key is labeled on many keyboards. On +keyboards with two keys labeled (usually to either side of the +space bar), the on the left side is generally set to work as a +Meta key. The 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, or another key working as a +Meta key, the identical keystroke can be generated by typing +_first_, and then typing . Either process is known as "metafying" +the key. + + The text `M-C-k' is read as `Meta-Control-k' and describes the +character produced by "metafying" `C-k'. + + In addition, several keys have their own names. Specifically, +, , , , , and all stand for themselves +when seen in this text, or in an init file (*note Readline Init File::). +If your keyboard lacks a key, typing will produce the +desired character. The key may be labeled or on +some keyboards. + + +File: readline.info, Node: Readline Interaction, Next: Readline Init File, Prev: Introduction and Notation, Up: Command Line Editing + +Readline Interaction +==================== + + 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 . You do not have to be at the end of +the line to press ; 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. + + +File: readline.info, Node: Readline Bare Essentials, Next: Readline Movement Commands, Up: Readline Interaction + +Readline Bare Essentials +------------------------ + + 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 `C-b' to move the cursor to the left, and then correct your +mistake. Afterwards, you can move the cursor to the right with `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. + +`C-b' + Move back one character. + +`C-f' + Move forward one character. + + or + Delete the character to the left of the cursor. + +`C-d' + Delete the character underneath the cursor. + +Printing characters + Insert the character into the line at the cursor. + +`C-_' or `C-x C-u' + Undo the last editing command. You can undo all the way back to an + empty line. + +(Depending on your configuration, the key be set to delete +the character to the left of the cursor and the key set to delete +the character underneath the cursor, like `C-d', rather than the +character to the left of the cursor.) + + +File: readline.info, Node: Readline Movement Commands, Next: Readline Killing Commands, Prev: Readline Bare Essentials, Up: Readline Interaction + +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 `C-b', `C-f', `C-d', and +. Here are some commands for moving more rapidly about the line. + +`C-a' + Move to the start of the line. + +`C-e' + Move to the end of the line. + +`M-f' + Move forward a word, where a word is composed of letters and + digits. + +`M-b' + Move backward a word. + +`C-l' + Clear the screen, reprinting the current line at the top. + + Notice how `C-f' moves forward a character, while `M-f' moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. + + +File: readline.info, Node: Readline Killing Commands, Next: Readline Arguments, Prev: Readline Movement Commands, Up: Readline Interaction + +Readline Killing Commands +------------------------- + + "Killing" text means to delete the text from the line, but to save +it away for later use, usually by "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 "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. + + Here is the list of commands for killing text. + +`C-k' + Kill the text from the current cursor position to the end of the + line. + +`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 `M-f'. + +`M-' + 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 `M-b'. + +`C-w' + Kill from the cursor to the previous whitespace. This is + different than `M-' because the word boundaries differ. + + Here is how to "yank" the text back into the line. Yanking means to +copy the most-recently-killed text from the kill buffer. + +`C-y' + Yank the most recently killed text back into the buffer at the + cursor. + +`M-y' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `C-y' or `M-y'. + + +File: readline.info, Node: Readline Arguments, Next: Searching, Prev: Readline Killing Commands, Up: Readline Interaction + +Readline Arguments +------------------ + + You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the 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 `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 (`-'), 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 `C-d' command an argument of 10, you could type `M-1 0 C-d', which +will delete the next ten characters on the input line. + + +File: readline.info, Node: Searching, Prev: Readline Arguments, Up: Readline Interaction + +Searching for Commands in the History +------------------------------------- + + Readline provides commands for searching through the command history +for lines containing a specified string. There are two search modes: +"incremental" and "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 `C-r'. Typing `C-s' searches +forward through the history. The characters present in the value of +the `isearch-terminators' variable are used to terminate an incremental +search. If that variable has not been assigned a value, the and +`C-J' characters will terminate an incremental search. `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 `C-r' or +`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 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 +`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. + + +File: readline.info, Node: Readline Init File, Next: Bindable Readline Commands, Prev: Readline Interaction, Up: Command Line Editing + +Readline Init File +================== + + 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 "inputrc" file, conventionally in his home +directory. The name of this file is taken from the value of the +environment variable `INPUTRC'. If that variable is unset, the default +is `~/.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 `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. + + +File: readline.info, Node: Readline Init File Syntax, Next: Conditional Init Constructs, Up: Readline Init File + +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 `#' are +comments. Lines beginning with a `$' indicate conditional constructs +(*note Conditional Init Constructs::). Other lines denote variable +settings and key bindings. + +Variable Settings + You can modify the run-time behavior of Readline by altering the + values of variables in Readline using the `set' command within the + init file. The syntax is simple: + + set VARIABLE VALUE + + Here, for example, is how to change from the default Emacs-like + key binding to use `vi' line editing commands: + + set editing-mode vi + + Variable names and values, where appropriate, are recognized + without regard to case. + + A great deal of run-time behavior is changeable with the following + variables. + + `bell-style' + Controls what happens when Readline wants to ring the + terminal bell. If set to `none', Readline never rings the + bell. If set to `visible', Readline uses a visible bell if + one is available. If set to `audible' (the default), + Readline attempts to ring the terminal's bell. + + `comment-begin' + The string to insert at the beginning of the line when the + `insert-comment' command is executed. The default value is + `"#"'. + + `completion-ignore-case' + If set to `on', Readline performs filename matching and + completion in a case-insensitive fashion. The default value + is `off'. + + `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 `100'. + + `convert-meta' + If set to `on', Readline will convert characters with the + eighth bit set to an ASCII key sequence by stripping the + eighth bit and prefixing an character, converting them + to a meta-prefixed key sequence. The default value is `on'. + + `disable-completion' + If set to `On', Readline will inhibit word completion. + Completion characters will be inserted into the line as if + they had been mapped to `self-insert'. The default is `off'. + + `editing-mode' + The `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 `emacs' or `vi'. + + `enable-keypad' + When set to `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 `off'. + + `expand-tilde' + If set to `on', tilde expansion is performed when Readline + attempts word completion. The default is `off'. + + If set to `on', the history code attempts to place point at + the same location on each history line retrived with + `previous-history' or `next-history'. + + `horizontal-scroll-mode' + This variable can be set to either `on' or `off'. Setting it + to `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 `off'. + + `input-meta' + If set to `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 `off'. The name `meta-flag' is a synonym + for this variable. + + `isearch-terminators' + The string of characters that should terminate an incremental + search without subsequently executing the character as a + command (*note Searching::). If this variable has not been + given a value, the characters and `C-J' will terminate + an incremental search. + + `keymap' + Sets Readline's idea of the current keymap for key binding + commands. Acceptable `keymap' names are `emacs', + `emacs-standard', `emacs-meta', `emacs-ctlx', `vi', `vi-move', + `vi-command', and `vi-insert'. `vi' is equivalent to + `vi-command'; `emacs' is equivalent to `emacs-standard'. The + default value is `emacs'. The value of the `editing-mode' + variable also affects the default keymap. + + `mark-directories' + If set to `on', completed directory names have a slash + appended. The default is `on'. + + `mark-modified-lines' + This variable, when set to `on', causes Readline to display an + asterisk (`*') at the start of history lines which have been + modified. This variable is `off' by default. + + `mark-symlinked-directories' + If set to `on', completed names which are symbolic links to + directories have a slash appended (subject to the value of + `mark-directories'). The default is `off'. + + `match-hidden-files' + This variable, when set to `on', causes Readline to match + files whose names begin with a `.' (hidden files) when + performing filename completion, unless the leading `.' is + supplied by the user in the filename to be completed. This + variable is `on' by default. + + `output-meta' + If set to `on', Readline will display characters with the + eighth bit set directly rather than as a meta-prefixed escape + sequence. The default is `off'. + + `page-completions' + If set to `on', Readline uses an internal `more'-like pager + to display a screenful of possible completions at a time. + This variable is `on' by default. + + `print-completions-horizontally' + If set to `on', Readline will display completions with matches + sorted horizontally in alphabetical order, rather than down + the screen. The default is `off'. + + `show-all-if-ambiguous' + This alters the default behavior of the completion functions. + If set to `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 `off'. + + `visible-stats' + If set to `on', a character denoting a file's type is + appended to the filename when listing possible completions. + The default is `off'. + +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 MACRO). + + KEYNAME: FUNCTION-NAME or MACRO + KEYNAME is the name of a key spelled out in English. For + example: + Control-u: universal-argument + Meta-Rubout: backward-kill-word + Control-o: "> output" + + In the above example, `C-u' is bound to the function + `universal-argument', `M-DEL' is bound to the function + `backward-kill-word', and `C-o' is bound to run the macro + expressed on the right hand side (that is, to insert the text + `> output' into the line). + + A number of symbolic character names are recognized while + processing this key binding syntax: DEL, ESC, ESCAPE, LFD, + NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB. + + "KEYSEQ": FUNCTION-NAME or MACRO + KEYSEQ differs from KEYNAME above in that strings denoting an + entire key sequence can be specified, by placing the key + sequence in double quotes. Some GNU Emacs style key escapes + can be used, as in the following example, but the special + character names are not recognized. + + "\C-u": universal-argument + "\C-x\C-r": re-read-init-file + "\e[11~": "Function Key 1" + + In the above example, `C-u' is again bound to the function + `universal-argument' (just as it was in the first example), + `C-x C-r' is bound to the function `re-read-init-file', and + ` <[> <1> <1> <~>' is bound to insert the text `Function + Key 1'. + + The following GNU Emacs style escape sequences are available when + specifying key sequences: + + `\C-' + control prefix + + `\M-' + meta prefix + + `\e' + an escape character + + `\\' + backslash + + `\"' + <">, a double quotation mark + + `\'' + <'>, a single quote or apostrophe + + In addition to the GNU Emacs style escape sequences, a second set + of backslash escapes is available: + + `\a' + alert (bell) + + `\b' + backspace + + `\d' + delete + + `\f' + form feed + + `\n' + newline + + `\r' + carriage return + + `\t' + horizontal tab + + `\v' + vertical tab + + `\NNN' + the eight-bit character whose value is the octal value NNN + (one to three digits) + + `\xHH' + the eight-bit character whose value is the hexadecimal value + HH (one or two hex digits) + + 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 `"' and `''. For example, + the following binding will make `C-x \' insert a single `\' into + the line: + "\C-x\\": "\\" + + +File: readline.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File + +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. + +`$if' + The `$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. + + `mode' + The `mode=' form of the `$if' directive is used to test + whether Readline is in `emacs' or `vi' mode. This may be + used in conjunction with the `set keymap' command, for + instance, to set bindings in the `emacs-standard' and + `emacs-ctlx' keymaps only if Readline is starting out in + `emacs' mode. + + `term' + The `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 + `=' is tested against both the full name of the terminal and + the portion of the terminal name before the first `-'. This + allows `sun' to match both `sun' and `sun-cmd', for instance. + + `application' + The APPLICATION construct is used to include + application-specific settings. Each program using the + Readline library sets the 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: + $if Bash + # Quote the current or previous word + "\C-xq": "\eb\"\ef\"" + $endif + +`$endif' + This command, as seen in the previous example, terminates an `$if' + command. + +`$else' + Commands in this branch of the `$if' directive are executed if the + test fails. + +`$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 `/etc/inputrc': + $include /etc/inputrc + + +File: readline.info, Node: Sample Init File, Prev: Conditional Init Constructs, Up: Readline Init File + +Sample Init File +---------------- + + Here is an example of an INPUTRC file. This illustrates key +binding, variable assignment, and conditional syntax. + + + # 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 + + +File: readline.info, Node: Bindable Readline Commands, Next: Readline vi Mode, Prev: Readline Init File, Up: Command Line Editing + +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. + + This section describes Readline commands that may be bound to key +sequences. Command names without an accompanying key sequence are +unbound by default. + + In the following descriptions, "point" refers to the current cursor +position, and "mark" refers to a cursor position saved by the +`set-mark' command. The text between the point and mark is referred to +as the "region". + + +File: readline.info, Node: Commands For Moving, Next: Commands For History, Up: Bindable Readline Commands + +Commands For Moving +------------------- + +`beginning-of-line (C-a)' + Move to the start of the current line. + +`end-of-line (C-e)' + Move to the end of the line. + +`forward-char (C-f)' + Move forward a character. + +`backward-char (C-b)' + Move back a character. + +`forward-word (M-f)' + Move forward to the end of the next word. Words are composed of + letters and digits. + +`backward-word (M-b)' + Move back to the start of the current or previous word. Words are + composed of letters and digits. + +`clear-screen (C-l)' + Clear the screen and redraw the current line, leaving the current + line at the top of the screen. + +`redraw-current-line ()' + Refresh the current line. By default, this is unbound. + + +File: readline.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands + +Commands For Manipulating The History +------------------------------------- + +`accept-line (Newline or Return)' + 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 `add_history()'. If this line is a modified history line, + the history line is restored to its original state. + +`previous-history (C-p)' + Move `back' through the history list, fetching the previous + command. + +`next-history (C-n)' + Move `forward' through the history list, fetching the next command. + +`beginning-of-history (M-<)' + Move to the first line in the history. + +`end-of-history (M->)' + Move to the end of the input history, i.e., the line currently + being entered. + +`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. + +`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. + +`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. + +`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. + +`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. + +`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. + +`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 N, + insert the Nth word from the previous command (the words in the + previous command begin with word 0). A negative argument inserts + the Nth word from the end of the previous command. + +`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 + `yank-nth-arg'. Successive calls to `yank-last-arg' move back + through the history list, inserting the last argument of each line + in turn. + + +File: readline.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands + +Commands For Changing Text +-------------------------- + +`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 `delete-char', then return EOF. + +`backward-delete-char (Rubout)' + Delete the character behind the cursor. A numeric argument means + to kill the characters instead of deleting them. + +`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. + +`quoted-insert (C-q or C-v)' + Add the next character typed to the line verbatim. This is how to + insert key sequences like `C-q', for example. + +`tab-insert (M-)' + Insert a tab character. + +`self-insert (a, b, A, 1, !, ...)' + Insert yourself. + +`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. + +`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. + +`upcase-word (M-u)' + Uppercase the current (or following) word. With a negative + argument, uppercase the previous word, but do not move the cursor. + +`downcase-word (M-l)' + Lowercase the current (or following) word. With a negative + argument, lowercase the previous word, but do not move the cursor. + +`capitalize-word (M-c)' + Capitalize the current (or following) word. With a negative + argument, capitalize the previous word, but do not move the cursor. + +`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 + `emacs' mode; `vi' mode does overwrite differently. Each call to + `readline()' starts in insert mode. + + In overwrite mode, characters bound to `self-insert' replace the + text at point rather than pushing the text to the right. + Characters bound to `backward-delete-char' replace the character + before point with a space. + + By default, this command is unbound. + + +File: readline.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands + +Killing And Yanking +------------------- + +`kill-line (C-k)' + Kill the text from point to the end of the line. + +`backward-kill-line (C-x Rubout)' + Kill backward to the beginning of the line. + +`unix-line-discard (C-u)' + Kill backward from the cursor to the beginning of the current line. + +`kill-whole-line ()' + Kill all characters on the current line, no matter where point is. + By default, this is unbound. + +`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 `forward-word'. + +`backward-kill-word (M-)' + Kill the word behind point. Word boundaries are the same as + `backward-word'. + +`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. + +`delete-horizontal-space ()' + Delete all spaces and tabs around point. By default, this is + unbound. + +`kill-region ()' + Kill the text in the current region. By default, this command is + unbound. + +`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. + +`copy-backward-word ()' + Copy the word before point to the kill buffer. The word + boundaries are the same as `backward-word'. By default, this + command is unbound. + +`copy-forward-word ()' + Copy the word following point to the kill buffer. The word + boundaries are the same as `forward-word'. By default, this + command is unbound. + +`yank (C-y)' + Yank the top of the kill ring into the buffer at point. + +`yank-pop (M-y)' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `yank' or `yank-pop'. + + +File: readline.info, Node: Numeric Arguments, Next: Commands For Completion, Prev: Commands For Killing, Up: Bindable Readline Commands + +Specifying Numeric Arguments +---------------------------- + +`digit-argument (M-0, M-1, ... M--)' + Add this digit to the argument already accumulating, or start a new + argument. `M--' starts a negative argument. + +`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 `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. + + +File: readline.info, Node: Commands For Completion, Next: Keyboard Macros, Prev: Numeric Arguments, Up: Bindable Readline Commands + +Letting Readline Type For You +----------------------------- + +`complete ()' + Attempt to perform completion on the text before point. The + actual completion performed is application-specific. The default + is filename completion. + +`possible-completions (M-?)' + List the possible completions of the text before point. + +`insert-completions (M-*)' + Insert all completions of the text before point that would have + been generated by `possible-completions'. + +`menu-complete ()' + Similar to `complete', but replaces the word to be completed with + a single match from the list of possible completions. Repeated + execution of `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 + `bell-style') and the original text is restored. An argument of N + moves 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 , but is unbound by + default. + +`delete-char-or-list ()' + Deletes the character under the cursor if not at the beginning or + end of the line (like `delete-char'). If at the end of the line, + behaves identically to `possible-completions'. This command is + unbound by default. + + +File: readline.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands + +Keyboard Macros +--------------- + +`start-kbd-macro (C-x ()' + Begin saving the characters typed into the current keyboard macro. + +`end-kbd-macro (C-x ))' + Stop saving the characters typed into the current keyboard macro + and save the definition. + +`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. + + +File: readline.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands + +Some Miscellaneous Commands +--------------------------- + +`re-read-init-file (C-x C-r)' + Read in the contents of the INPUTRC file, and incorporate any + bindings or variable assignments found there. + +`abort (C-g)' + Abort the current editing command and ring the terminal's bell + (subject to the setting of `bell-style'). + +`do-uppercase-version (M-a, M-b, M-X, ...)' + If the metafied character X is lowercase, run the command that is + bound to the corresponding uppercase character. + +`prefix-meta ()' + Metafy the next character typed. This is for keyboards without a + meta key. Typing ` f' is equivalent to typing `M-f'. + +`undo (C-_ or C-x C-u)' + Incremental undo, separately remembered for each line. + +`revert-line (M-r)' + Undo all changes made to this line. This is like executing the + `undo' command enough times to get back to the beginning. + +`tilde-expand (M-~)' + Perform tilde expansion on the current word. + +`set-mark (C-@)' + Set the mark to the point. If a numeric argument is supplied, the + mark is set to that position. + +`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. + +`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. + +`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. + +`insert-comment (M-#)' + Without a numeric argument, the value of the `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 `comment-begin', the value is inserted, otherwise the + characters in `comment-begin' are deleted from the beginning of + the line. In either case, the line is accepted as if a newline + had been typed. + +`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 INPUTRC + file. This command is unbound by default. + +`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 + INPUTRC file. This command is unbound by default. + +`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 + INPUTRC file. This command is unbound by default. + +`emacs-editing-mode (C-e)' + When in `vi' command mode, this causes a switch to `emacs' editing + mode. + +`vi-editing-mode (M-C-j)' + When in `emacs' editing mode, this causes a switch to `vi' editing + mode. + + +File: readline.info, Node: Readline vi Mode, Prev: Bindable Readline Commands, Up: Command Line Editing + +Readline vi Mode +================ + + While the Readline library does not have a full set of `vi' editing +functions, it does contain enough to allow simple editing of the line. +The Readline `vi' mode behaves as specified in the POSIX 1003.2 +standard. + + In order to switch interactively between `emacs' and `vi' editing +modes, use the command `M-C-j' (bound to emacs-editing-mode when in +`vi' mode and to vi-editing-mode in `emacs' mode). The Readline +default is `emacs' mode. + + When you enter a line in `vi' mode, you are already placed in +`insertion' mode, as if you had typed an `i'. Pressing switches +you into `command' mode, where you can edit the text of the line with +the standard `vi' movement keys, move to previous history lines with +`k' and subsequent lines with `j', and so forth. + + 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. + + 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. + + +File: readline.info, Node: Programming with GNU Readline, Next: Concept Index, Prev: Command Line Editing, Up: Top + +Programming with GNU Readline +***************************** + + This chapter describes the interface between the GNU Readline +Library and other programs. If you are a programmer, and you wish to +include the features found in 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. + + +File: readline.info, Node: Basic Behavior, Next: Custom Functions, Up: Programming with GNU Readline + +Basic Behavior +============== + + Many programs provide a command line interface, such as `mail', +`ftp', and `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 +`gets()' or `fgets()'. + + The function `readline()' prints a prompt PROMPT and then reads and +returns a single line of text from the user. If PROMPT is `NULL' or +the empty string, no prompt is displayed. The line `readline' returns +is allocated with `malloc()'; the caller should `free()' the line when +it has finished with it. The declaration for `readline' in ANSI C is + + `char *readline (const char *PROMPT);' + +So, one might say + `char *line = readline ("Enter a line: ");' + +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 `readline' encounters an `EOF' while reading the line, and the +line is empty at that point, then `(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 + for example), you must call `add_history()' to save the line away +in a "history" list of such lines. + + `add_history (line)'; + +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 `gets()' library +function, and has the advantage of no static buffer to overflow: + + /* 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); + } + + This function gives the user the default behaviour of +completion: completion on file names. If you do not want Readline to +complete on filenames, you can change the binding of the key with +`rl_bind_key()'. + + `int rl_bind_key (int KEY, rl_command_func_t *FUNCTION);' + + `rl_bind_key()' takes two arguments: KEY is the character that you +want to bind, and FUNCTION is the address of the function to call when +KEY is pressed. Binding to `rl_insert()' makes insert +itself. `rl_bind_key()' returns non-zero if KEY is not a valid ASCII +character code (between 0 and 255). + + Thus, to disable the default behavior, the following suffices: + `rl_bind_key ('\t', rl_insert);' + + This code should be executed once at the start of your program; you +might write a function called `initialize_readline()' which performs +this and other desired initializations, such as installing custom +completers (*note Custom Completers::). + + +File: readline.info, Node: Custom Functions, Next: Readline Variables, Prev: Basic Behavior, Up: Programming with GNU Readline + +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 `' in any file that +uses Readline's features. Since some of the definitions in +`readline.h' use the `stdio' library, the file `' should be +included before `readline.h'. + + `readline.h' defines a C preprocessor variable that should be +treated as an integer, `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 0xMMMM. MM is the +two-digit major version number; MM is the two-digit minor version +number. For Readline 4.2, for example, the value of +`RL_READLINE_VERSION' would be `0x0402'. + +* Menu: + +* Readline Typedefs:: C declarations to make code readable. +* Function Writing:: Variables and calling conventions. + + +File: readline.info, Node: Readline Typedefs, Next: Function Writing, Up: Custom Functions + +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 FUNC as a pointer to +a function which takes two `int' arguments and returns an `int' (this +is the type of all of the Readline bindable functions). Instead of the +classic C declaration + + `int (*func)();' + +or the ANSI-C style declaration + + `int (*func)(int, int);' + +we may write + + `rl_command_func_t *func;' + + The full list of function pointer types available is + +`typedef int rl_command_func_t (int, int);' + +`typedef char *rl_compentry_func_t (const char *, int);' + +`typedef char **rl_completion_func_t (const char *, int, int);' + +`typedef char *rl_quote_func_t (char *, int, char *);' + +`typedef char *rl_dequote_func_t (char *, int);' + +`typedef int rl_compignore_func_t (char **);' + +`typedef void rl_compdisp_func_t (char **, int, int);' + +`typedef int rl_hook_func_t (void);' + +`typedef int rl_getc_func_t (FILE *);' + +`typedef int rl_linebuf_func_t (char *, int);' + +`typedef int rl_intfunc_t (int);' + +`#define rl_ivoidfunc_t rl_hook_func_t' + +`typedef int rl_icpfunc_t (char *);' + +`typedef int rl_icppfunc_t (char **);' + +`typedef void rl_voidfunc_t (void);' + +`typedef void rl_vintfunc_t (int);' + +`typedef void rl_vcpfunc_t (char *);' + +`typedef void rl_vcppfunc_t (char **);' + +File: readline.info, Node: Function Writing, Prev: Readline Typedefs, Up: Custom Functions + +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 `foo' looks like + + `int foo (int count, int key)' + +where COUNT is the numeric argument (or 1 if defaulted) and 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. + + +File: readline.info, Node: Readline Variables, Next: Readline Convenience Functions, Prev: Custom Functions, Up: Programming with GNU Readline + +Readline Variables +================== + + These variables are available to function writers. + + - Variable: char * rl_line_buffer + This is the line gathered so far. You are welcome to modify the + contents of the line, but see *Note Allowing Undoing::. The + function `rl_extend_line_buffer' is available to increase the + memory allocated to `rl_line_buffer'. + + - Variable: int rl_point + The offset of the current cursor position in `rl_line_buffer' (the + _point_). + + - Variable: int rl_end + The number of characters present in `rl_line_buffer'. When + `rl_point' is at the end of the line, `rl_point' and `rl_end' are + equal. + + - Variable: int rl_mark + The MARK (saved position) in the current line. If set, the mark + and point define a _region_. + + - Variable: int rl_done + Setting this to a non-zero value causes Readline to return the + current line immediately. + + - Variable: int rl_num_chars_to_read + Setting this to a positive value before calling `readline()' causes + Readline to return after accepting that many characters, rather + than reading up to a character bound to `accept-line'. + + - Variable: 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. + + - Variable: 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. + + - Variable: 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. + + - Variable: char * rl_prompt + The prompt Readline uses. This is set from the argument to + `readline()', and should not be assigned to directly. The + `rl_set_prompt()' function (*note Redisplay::) may be used to + modify the prompt string after calling `readline()'. + + - Variable: int rl_already_prompted + If an application wishes to display the prompt itself, rather than + have Readline do it the first time `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 + `readline()' so the redisplay functions can update the display + properly. The calling application is responsible for managing the + value; Readline never sets it. + + - Variable: const char * rl_library_version + The version number of this revision of the library. + + - Variable: int rl_readline_version + An integer encoding the current version of the library. The + encoding is of the form 0xMMMM, where MM is the two-digit major + version number, and MM is the two-digit minor version number. For + example, for Readline-4.2, `rl_readline_version' would have the + value 0x0402. + + - Variable: int rl_gnu_readline_p + Always set to 1, denoting that this is GNU readline rather than + some emulation. + + - Variable: 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 `TERM' + environment variable the first time it is called. + + - Variable: 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 + (*note Conditional Init Constructs::). + + - Variable: FILE * rl_instream + The stdio stream from which Readline reads input. If `NULL', + Readline defaults to STDIN. + + - Variable: FILE * rl_outstream + The stdio stream to which Readline performs output. If `NULL', + Readline defaults to STDOUT. + + - Variable: 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. + + - Variable: rl_hook_func_t * rl_startup_hook + If non-zero, this is the address of a function to call just before + `readline' prints the first prompt. + + - Variable: 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 `readline' starts + reading input characters. + + - Variable: 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. + + - Variable: 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 + `rl_getc', the default Readline character input function (*note + Character Input::). + + - Variable: 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 `rl_redisplay', the default Readline + redisplay function (*note Redisplay::). + + - Variable: 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 + `int' flag that says whether or not to use eight-bit characters. + By default, this is set to `rl_prep_terminal' (*note Terminal + Management::). + + - Variable: 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 + `rl_prep_term_function'. By default, this is set to + `rl_deprep_terminal' (*note Terminal Management::). + + - Variable: Keymap rl_executing_keymap + This variable is set to the keymap (*note Keymaps::) in which the + currently executing readline function was found. + + - Variable: Keymap rl_binding_keymap + This variable is set to the keymap (*note Keymaps::) in which the + last key binding occurred. + + - Variable: char * rl_executing_macro + This variable is set to the text of any currently-executing macro. + + - Variable: int rl_readline_state + A variable with bit values that encapsulate the current Readline + state. A bit is set with the `RL_SETSTATE' macro, and unset with + the `RL_UNSETSTATE' macro. Use the `RL_ISSTATE' macro to test + whether a particular state bit is set. Current state bits include: + + `RL_STATE_NONE' + Readline has not yet been called, nor has it begun to + intialize. + + `RL_STATE_INITIALIZING' + Readline is initializing its internal data structures. + + `RL_STATE_INITIALIZED' + Readline has completed its initialization. + + `RL_STATE_TERMPREPPED' + Readline has modified the terminal modes to do its own input + and redisplay. + + `RL_STATE_READCMD' + Readline is reading a command from the keyboard. + + `RL_STATE_METANEXT' + Readline is reading more input after reading the meta-prefix + character. + + `RL_STATE_DISPATCHING' + Readline is dispatching to a command. + + `RL_STATE_MOREINPUT' + Readline is reading more input while executing an editing + command. + + `RL_STATE_ISEARCH' + Readline is performing an incremental history search. + + `RL_STATE_NSEARCH' + Readline is performing a non-incremental history search. + + `RL_STATE_SEARCH' + Readline is searching backward or forward through the history + for a string. + + `RL_STATE_NUMERICARG' + Readline is reading a numeric argument. + + `RL_STATE_MACROINPUT' + Readline is currently getting its input from a + previously-defined keyboard macro. + + `RL_STATE_MACRODEF' + Readline is currently reading characters defining a keyboard + macro. + + `RL_STATE_OVERWRITE' + Readline is in overwrite mode. + + `RL_STATE_COMPLETING' + Readline is performing word completion. + + `RL_STATE_SIGHANDLER' + Readline is currently executing the readline signal handler. + + `RL_STATE_UNDOING' + Readline is performing an undo. + + `RL_STATE_DONE' + Readline has read a key sequence bound to `accept-line' and + is about to return the line to the caller. + + + - Variable: 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. + + - Variable: 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. + + - Variable: int rl_editing_mode + Set to a value denoting Readline's current editing mode. A value + of 1 means Readline is currently in emacs mode; 0 means that vi + mode is active. + + +File: readline.info, Node: Readline Convenience Functions, Next: Readline Signal Handling, Prev: Readline Variables, Up: Programming with GNU Readline + +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 `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. + + +File: readline.info, Node: Function Naming, Next: Keymaps, Up: Readline Convenience Functions + +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 + + Meta-Rubout: backward-kill-word + + This binds the keystroke to the function +_descriptively_ named `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: + + - Function: int rl_add_defun (const char *name, rl_command_func_t + *function, int key) + Add NAME to the list of named functions. Make FUNCTION be the + function that gets called. If KEY is not -1, then bind it to + FUNCTION using `rl_bind_key()'. + + 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. + + +File: readline.info, Node: Keymaps, Next: Binding Keys, Prev: Function Naming, Up: Readline Convenience Functions + +Selecting a Keymap +------------------ + + Key bindings take place on a "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. + + - Function: Keymap rl_make_bare_keymap (void) + Returns a new, empty keymap. The space for the keymap is + allocated with `malloc()'; the caller should free it by calling + `rl_discard_keymap()' when done. + + - Function: Keymap rl_copy_keymap (Keymap map) + Return a new keymap which is a copy of MAP. + + - Function: 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. + + - Function: void rl_discard_keymap (Keymap keymap) + Free the storage associated with KEYMAP. + + Readline has several internal keymaps. These functions allow you to +change which keymap is active. + + - Function: Keymap rl_get_keymap (void) + Returns the currently active keymap. + + - Function: void rl_set_keymap (Keymap keymap) + Makes KEYMAP the currently active keymap. + + - Function: Keymap rl_get_keymap_by_name (const char *name) + Return the keymap matching NAME. NAME is one which would be + supplied in a `set keymap' inputrc line (*note Readline Init + File::). + + - Function: char * rl_get_keymap_name (Keymap keymap) + Return the name matching KEYMAP. NAME is one which would be + supplied in a `set keymap' inputrc line (*note Readline Init + File::). + + +File: readline.info, Node: Binding Keys, Next: Associating Function Names and Bindings, Prev: Keymaps, Up: Readline Convenience Functions + +Binding Keys +------------ + + Key sequences are associate with functions through the keymap. +Readline has several internal keymaps: `emacs_standard_keymap', +`emacs_meta_keymap', `emacs_ctlx_keymap', `vi_movement_keymap', and +`vi_insertion_keymap'. `emacs_standard_keymap' is the default, and the +examples in this manual assume that. + + Since `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 `readline()' will be overridden. An +alternate mechanism is to install custom key bindings in an +initialization function assigned to the `rl_startup_hook' variable +(*note Readline Variables::). + + These functions manage key bindings. + + - Function: int rl_bind_key (int key, rl_command_func_t *function) + Binds KEY to FUNCTION in the currently active keymap. Returns + non-zero in the case of an invalid KEY. + + - Function: int rl_bind_key_in_map (int key, rl_command_func_t + *function, Keymap map) + Bind KEY to FUNCTION in MAP. Returns non-zero in the case of an + invalid KEY. + + - Function: int rl_unbind_key (int key) + Bind KEY to the null function in the currently active keymap. + Returns non-zero in case of error. + + - Function: int rl_unbind_key_in_map (int key, Keymap map) + Bind KEY to the null function in MAP. Returns non-zero in case of + error. + + - Function: int rl_unbind_function_in_map (rl_command_func_t + *function, Keymap map) + Unbind all keys that execute FUNCTION in MAP. + + - Function: int rl_unbind_command_in_map (const char *command, Keymap + map) + Unbind all keys that are bound to COMMAND in MAP. + + - Function: int rl_set_key (const char *keyseq, rl_command_func_t + *function, Keymap map) + Bind the key sequence represented by the string KEYSEQ to the + function FUNCTION. This makes new keymaps as necessary. The + initial keymap in which to do bindings is MAP. + + - Function: int rl_generic_bind (int type, const char *keyseq, char + *data, Keymap map) + Bind the key sequence represented by the string KEYSEQ to the + arbitrary pointer DATA. TYPE says what kind of data is pointed to + by DATA; this can be a function (`ISFUNC'), a macro (`ISMACR'), or + a keymap (`ISKMAP'). This makes new keymaps as necessary. The + initial keymap in which to do bindings is MAP. + + - Function: int rl_parse_and_bind (char *line) + Parse LINE as if it had been read from the `inputrc' file and + perform any key bindings and variable assignments found (*note + Readline Init File::). + + - Function: int rl_read_init_file (const char *filename) + Read keybindings and variable assignments from FILENAME (*note + Readline Init File::). + + +File: readline.info, Node: Associating Function Names and Bindings, Next: Allowing Undoing, Prev: Binding Keys, Up: Readline Convenience Functions + +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. + + - Function: rl_command_func_t * rl_named_function (const char *name) + Return the function with name NAME. + + - Function: rl_command_func_t * rl_function_of_keyseq (const char + *keyseq, Keymap map, int *type) + Return the function invoked by KEYSEQ in keymap MAP. If MAP is + `NULL', the current keymap is used. If TYPE is not `NULL', the + type of the object is returned in the `int' variable it points to + (one of `ISFUNC', `ISKMAP', or `ISMACR'). + + - Function: char ** rl_invoking_keyseqs (rl_command_func_t *function) + Return an array of strings representing the key sequences used to + invoke FUNCTION in the current keymap. + + - Function: 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 FUNCTION in the keymap MAP. + + - Function: void rl_function_dumper (int readable) + Print the readline function names and the key sequences currently + bound to them to `rl_outstream'. If READABLE is non-zero, the + list is formatted in such a way that it can be made part of an + `inputrc' file and re-read. + + - Function: void rl_list_funmap_names (void) + Print the names of all bindable Readline functions to + `rl_outstream'. + + - Function: 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 `free()' the array when you are done, but not + the pointers. + + - Function: int rl_add_funmap_entry (const char *name, + rl_command_func_t *function) + Add NAME to the list of bindable Readline command names, and make + FUNCTION the function to be called when NAME is invoked. + + +File: readline.info, Node: Allowing Undoing, Next: Redisplay, Prev: Associating Function Names and Bindings, Up: Readline Convenience Functions + +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 `rl_insert_text()' or `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 `rl_begin_undo_group()' and +`rl_end_undo_group()'. + + The types of events that can be undone are: + + enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END }; + + Notice that `UNDO_DELETE' means to insert some text, and +`UNDO_INSERT' means to delete some text. That is, the undo code tells +what to undo, not how to undo it. `UNDO_BEGIN' and `UNDO_END' are tags +added by `rl_begin_undo_group()' and `rl_end_undo_group()'. + + - Function: int rl_begin_undo_group (void) + Begins saving undo information in a group construct. The undo + information usually comes from calls to `rl_insert_text()' and + `rl_delete_text()', but could be the result of calls to + `rl_add_undo()'. + + - Function: int rl_end_undo_group (void) + Closes the current undo group started with `rl_begin_undo_group + ()'. There should be one call to `rl_end_undo_group()' for each + call to `rl_begin_undo_group()'. + + - Function: void rl_add_undo (enum undo_code what, int start, int end, + char *text) + Remember how to undo an event (according to WHAT). The affected + text runs from START to END, and encompasses TEXT. + + - Function: void rl_free_undo_list (void) + Free the existing undo list. + + - Function: int rl_do_undo (void) + Undo the first thing on the undo list. Returns `0' if there was + nothing to undo, non-zero if something was undone. + + Finally, if you neither insert nor delete text, but directly modify +the existing text (e.g., change its case), call `rl_modifying()' once, +just before you modify the text. You must supply the indices of the +text range that you are going to modify. + + - Function: int rl_modifying (int start, int end) + Tell Readline to save the text between START and END as a single + undo unit. It is assumed that you will subsequently modify that + text. + + +File: readline.info, Node: Redisplay, Next: Modifying Text, Prev: Allowing Undoing, Up: Readline Convenience Functions + +Redisplay +--------- + + - Function: void rl_redisplay (void) + Change what's displayed on the screen to reflect the current + contents of `rl_line_buffer'. + + - Function: int rl_forced_update_display (void) + Force the line to be updated and redisplayed, whether or not + Readline thinks the screen display is correct. + + - Function: int rl_on_new_line (void) + Tell the update functions that we have moved onto a new (empty) + line, usually after ouputting a newline. + + - Function: int rl_on_new_line_with_prompt (void) + Tell the update functions that we have moved onto a new line, with + 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 RL_ALREADY_PROMPTED. + + - Function: int rl_reset_line_state (void) + Reset the display state to a clean state and redisplay the current + line starting on a new line. + + - Function: int rl_crlf (void) + Move the cursor to the start of the next screen line. + + - Function: int rl_show_char (int c) + Display character C on `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. + + - Function: int rl_message (const char *, ...) + The arguments are a format string as would be supplied to `printf', + possibly containing conversion specifications such as `%d', and + any additional arguments necessary to satisfy the conversion + specifications. The resulting string is displayed in the "echo + area". The echo area is also used to display numeric arguments + and search strings. + + - Function: int rl_clear_message (void) + Clear the message in the echo area. + + - Function: void rl_save_prompt (void) + Save the local Readline prompt display state in preparation for + displaying a new message in the message area with `rl_message()'. + + - Function: void rl_restore_prompt (void) + Restore the local Readline prompt display state saved by the most + recent call to `rl_save_prompt'. + + - Function: int rl_expand_prompt (char *prompt) + Expand any special character sequences in PROMPT and set up the + local Readline prompt redisplay variables. This function is + called by `readline()'. It may also be called to expand the + primary prompt if the `rl_on_new_line_with_prompt()' function or + `rl_already_prompted' variable is used. It returns the number of + visible characters on the last line of the (possibly multi-line) + prompt. + + - Function: int rl_set_prompt (const char *prompt) + Make Readline use PROMPT for subsequent redisplay. This calls + `rl_expand_prompt()' to expand the prompt and sets `rl_prompt' to + the result. + + +File: readline.info, Node: Modifying Text, Next: Character Input, Prev: Redisplay, Up: Readline Convenience Functions + +Modifying Text +-------------- + + - Function: int rl_insert_text (const char *text) + Insert TEXT into the line at the current cursor position. Returns + the number of characters inserted. + + - Function: int rl_delete_text (int start, int end) + Delete the text between START and END in the current line. + Returns the number of characters deleted. + + - Function: char * rl_copy_text (int start, int end) + Return a copy of the text between START and END in the current + line. + + - Function: int rl_kill_text (int start, int end) + Copy the text between START and 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 START is + less than END, the text is appended, otherwise prepended. If the + last command was not a kill, a new kill ring slot is used. + + - Function: int rl_push_macro_input (char *macro) + Cause MACRO to be inserted into the line, as if it had been invoked + by a key bound to a macro. Not especially useful; use + `rl_insert_text()' instead. + + +File: readline.info, Node: Character Input, Next: Terminal Management, Prev: Modifying Text, Up: Readline Convenience Functions + +Character Input +--------------- + + - Function: 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 + RL_PENDING_INPUT (*note Readline Variables::) and + `rl_stuff_char()', macros, and characters read from the keyboard. + While waiting for input, this function will call any function + assigned to the `rl_event_hook' variable. + + - Function: int rl_getc (FILE *stream) + Return the next character available from STREAM, which is assumed + to be the keyboard. + + - Function: int rl_stuff_char (int c) + Insert C into the Readline input stream. It will be "read" before + Readline attempts to read characters from the terminal with + `rl_read_key()'. Up to 512 characters may be pushed back. + `rl_stuff_char' returns 1 if the character was successfully + inserted; 0 otherwise. + + - Function: int rl_execute_next (int c) + Make C be the next command to be executed when `rl_read_key()' is + called. This sets RL_PENDING_INPUT. + + - Function: int rl_clear_pending_input (void) + Unset RL_PENDING_INPUT, effectively negating the effect of any + previous call to `rl_execute_next()'. This works only if the + pending input has not already been read with `rl_read_key()'. + + - Function: int rl_set_keyboard_input_timeout (int u) + While waiting for keyboard input in `rl_read_key()', Readline will + wait for U microseconds for input before calling any function + assigned to `rl_event_hook'. The default waiting period is + one-tenth of a second. Returns the old timeout value. + + +File: readline.info, Node: Terminal Management, Next: Utility Functions, Prev: Character Input, Up: Readline Convenience Functions + +Terminal Management +------------------- + + - Function: void rl_prep_terminal (int meta_flag) + Modify the terminal settings for Readline's use, so `readline()' + can read a single character at a time from the keyboard. The + META_FLAG argument should be non-zero if Readline should read + eight-bit input. + + - Function: void rl_deprep_terminal (void) + Undo the effects of `rl_prep_terminal()', leaving the terminal in + the state in which it was before the most recent call to + `rl_prep_terminal()'. + + - Function: void rl_tty_set_default_bindings (Keymap kmap) + Read the operating system's terminal editing characters (as would + be displayed by `stty') to their Readline equivalents. The + bindings are performed in KMAP. + + - Function: int rl_reset_terminal (const char *terminal_name) + Reinitialize Readline's idea of the terminal settings using + TERMINAL_NAME as the terminal type (e.g., `vt100'). If + TERMINAL_NAME is `NULL', the value of the `TERM' environment + variable is used. + + +File: readline.info, Node: Utility Functions, Next: Miscellaneous Functions, Prev: Terminal Management, Up: Readline Convenience Functions + +Utility Functions +----------------- + + - Function: void rl_replace_line (const char *text, int clear_undo) + Replace the contents of `rl_line_buffer' with TEXT. The point and + mark are preserved, if possible. If CLEAR_UNDO is non-zero, the + undo list associated with the current line is cleared. + + - Function: int rl_extend_line_buffer (int len) + Ensure that `rl_line_buffer' has enough space to hold LEN + characters, possibly reallocating it if necessary. + + - Function: int rl_initialize (void) + Initialize or re-initialize Readline's internal state. It's not + strictly necessary to call this; `readline()' calls it before + reading any input. + + - Function: int rl_ding (void) + Ring the terminal bell, obeying the setting of `bell-style'. + + - Function: int rl_alphabetic (int c) + Return 1 if C is an alphabetic character. + + - Function: 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. `matches' is the list + of strings, in argv format, such as a list of completion matches. + `len' is the number of strings in `matches', and `max' is the + length of the longest string in `matches'. This function uses the + setting of `print-completions-horizontally' to select how the + matches are displayed (*note Readline Init File Syntax::). + + The following are implemented as macros, defined in `chardefs.h'. +Applications should refrain from using them. + + - Function: int _rl_uppercase_p (int c) + Return 1 if C is an uppercase alphabetic character. + + - Function: int _rl_lowercase_p (int c) + Return 1 if C is a lowercase alphabetic character. + + - Function: int _rl_digit_p (int c) + Return 1 if C is a numeric character. + + - Function: int _rl_to_upper (int c) + If C is a lowercase alphabetic character, return the corresponding + uppercase character. + + - Function: int _rl_to_lower (int c) + If C is an uppercase alphabetic character, return the corresponding + lowercase character. + + - Function: int _rl_digit_value (int c) + If C is a number, return the value it represents. + + +File: readline.info, Node: Miscellaneous Functions, Next: Alternate Interface, Prev: Utility Functions, Up: Readline Convenience Functions + +Miscellaneous Functions +----------------------- + + - Function: int rl_macro_bind (const char *keyseq, const char *macro, + Keymap map) + Bind the key sequence KEYSEQ to invoke the macro MACRO. The + binding is performed in MAP. When KEYSEQ is invoked, the MACRO + will be inserted into the line. This function is deprecated; use + `rl_generic_bind()' instead. + + - Function: void rl_macro_dumper (int readable) + Print the key sequences bound to macros and their values, using + the current keymap, to `rl_outstream'. If READABLE is non-zero, + the list is formatted in such a way that it can be made part of an + `inputrc' file and re-read. + + - Function: int rl_variable_bind (const char *variable, const char + *value) + Make the Readline variable VARIABLE have VALUE. This behaves as + if the readline command `set VARIABLE VALUE' had been executed in + an `inputrc' file (*note Readline Init File Syntax::). + + - Function: void rl_variable_dumper (int readable) + Print the readline variable names and their current values to + `rl_outstream'. If READABLE is non-zero, the list is formatted in + such a way that it can be made part of an `inputrc' file and + re-read. + + - Function: int rl_set_paren_blink_timeout (int u) + Set the time interval (in microseconds) that Readline waits when + showing a balancing character when `blink-matching-paren' has been + enabled. + + - Function: char * rl_get_termcap (const char *cap) + Retrieve the string value of the termcap capability 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. + + +File: readline.info, Node: Alternate Interface, Next: A Readline Example, Prev: Miscellaneous Functions, Up: Readline Convenience Functions + +Alternate Interface +------------------- + + An alternate interface is available to plain `readline()'. Some +applications need to interleave keyboard I/O with file, device, or +window system I/O, typically by using a main loop to `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. + + - Function: 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 PROMPT. Save the value of 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. + + - Function: void rl_callback_read_char (void) + Whenever an application determines that keyboard input is + available, it should call `rl_callback_read_char()', which will + read the next character from the current input source. If that + character completes the line, `rl_callback_read_char' will invoke + the LHANDLER function saved by `rl_callback_handler_install' to + process the line. Before calling the LHANDLER function, the + terminal settings are reset to the values they had before calling + `rl_callback_handler_install'. If the LHANDLER function returns, + the terminal settings are modified for Readline's use again. + `EOF' is indicated by calling LHANDLER with a `NULL' line. + + - Function: 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 LHANDLER installed by + `rl_callback_handler_install' does not exit the program, either + this function or the function referred to by the value of + `rl_deprep_term_function' should be called before the program + exits to reset the terminal settings. + + +File: readline.info, Node: A Readline Example, Prev: Alternate Interface, Up: Readline Convenience Functions + +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 `M-c', then typing `M-c' would change the case of +the character under point. Typing `M-1 0 M-c' would change the case of +the following 10 characters, leaving the cursor on the last character +changed. + + /* 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); + } + + +File: readline.info, Node: Readline Signal Handling, Next: Custom Completers, Prev: Readline Convenience Functions, Up: Programming with GNU Readline + +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 (`SIGINT', `SIGQUIT', `SIGTERM', `SIGALRM', +`SIGTSTP', `SIGTTIN', and `SIGTTOU'). When one of these signals is +received, the signal handler will reset the terminal attributes to +those that were in effect before `readline()' was called, reset the +signal handling to what it was before `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 `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 +`rl_free_line_state()' below). + + There is an additional Readline signal handler, for `SIGWINCH', which +the kernel sends to a process whenever the terminal's size changes (for +example, if a user resizes an `xterm'). The Readline `SIGWINCH' +handler updates Readline's internal screen size information, and then +calls any `SIGWINCH' signal handler the calling application has +installed. Readline calls the application's `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 `longjmp' back to a main +processing loop), it _must_ call `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 `readline()', not in a +signal handler, so Readline's internal signal state is not corrupted. + + - Variable: int rl_catch_signals + If this variable is non-zero, Readline will install signal + handlers for `SIGINT', `SIGQUIT', `SIGTERM', `SIGALRM', `SIGTSTP', + `SIGTTIN', and `SIGTTOU'. + + The default value of `rl_catch_signals' is 1. + + - Variable: int rl_catch_sigwinch + If this variable is non-zero, Readline will install a signal + handler for `SIGWINCH'. + + The default value of `rl_catch_sigwinch' is 1. + + If an application does not wish to have Readline catch any signals, +or to handle signals other than those Readline catches (`SIGHUP', for +example), Readline provides convenience functions to do the necessary +terminal and internal state cleanup upon receipt of a signal. + + - Function: void rl_cleanup_after_signal (void) + This function will reset the state of the terminal to what it was + before `readline()' was called, and remove the Readline signal + handlers for all signals, depending on the values of + `rl_catch_signals' and `rl_catch_sigwinch'. + + - Function: 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 + `rl_cleanup_after_signal()'. The Readline signal handler for + `SIGINT' calls this to abort the current input line. + + - Function: void rl_reset_after_signal (void) + This will reinitialize the terminal and reinstall any Readline + signal handlers, depending on the values of `rl_catch_signals' and + `rl_catch_sigwinch'. + + If an application does not wish Readline to catch `SIGWINCH', it may +call `rl_resize_terminal()' or `rl_set_screen_size()' to force Readline +to update its idea of the terminal size when a `SIGWINCH' is received. + + - Function: void rl_resize_terminal (void) + Update Readline's internal screen size by reading values from the + kernel. + + - Function: void rl_set_screen_size (int rows, int cols) + Set Readline's idea of the terminal size to ROWS rows and COLS + columns. + + If an application does not want to install a `SIGWINCH' handler, but +is still interested in the screen dimensions, Readline's idea of the +screen size may be queried. + + - Function: 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. + + The following functions install and remove Readline's signal +handlers. + + - Function: int rl_set_signals (void) + Install Readline's signal handler for `SIGINT', `SIGQUIT', + `SIGTERM', `SIGALRM', `SIGTSTP', `SIGTTIN', `SIGTTOU', and + `SIGWINCH', depending on the values of `rl_catch_signals' and + `rl_catch_sigwinch'. + + - Function: int rl_clear_signals (void) + Remove all of the Readline signal handlers installed by + `rl_set_signals()'. + + +File: readline.info, Node: Custom Completers, Prev: Readline Signal Handling, Up: Programming with GNU Readline + +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. + + +File: readline.info, Node: How Completing Works, Next: Completion Functions, Up: Custom Completers + +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: + + 1. The user-interface function `rl_complete()'. This function is + called with the same arguments as other bindable Readline + functions: COUNT and INVOKING_KEY. It isolates the word to be + completed and calls `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. + + 2. The internal function `rl_completion_matches()' uses an + application-supplied "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 + `rl_completion_entry_function'. + + 3. The generator function is called repeatedly from + `rl_completion_matches()', returning a string each time. The + arguments to the generator function are TEXT and STATE. TEXT is + the partial word to be completed. 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 `(char *)NULL' to + inform `rl_completion_matches()' that there are no more + possibilities left. Usually the generator function computes the + list of possible completions when 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 `malloc()'; + Readline frees the strings when it has finished with them. + + + - Function: 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 `rl_completion_matches()'). The default is to do filename + completion. + + - Variable: rl_compentry_func_t * rl_completion_entry_function + This is a pointer to the generator function for + `rl_completion_matches()'. If the value of + `rl_completion_entry_function' is `NULL' then the default filename + generator function, `rl_filename_completion_function()', is used. + + +File: readline.info, Node: Completion Functions, Next: Completion Variables, Prev: How Completing Works, Up: Custom Completers + +Completion Functions +-------------------- + + Here is the complete list of callable completion functions present in +Readline. + + - Function: int rl_complete_internal (int what_to_do) + Complete the word at or before point. WHAT_TO_DO says what to do + with the completion. A value of `?' means list the possible + completions. `TAB' means do standard completion. `*' means + insert all of the possible completions. `!' means to display all + of the possible completions, if there is more than one, as well as + performing partial completion. + + - Function: 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 `rl_completion_matches()' and `rl_completion_entry_function'). + The default is to do filename completion. This calls + `rl_complete_internal()' with an argument depending on + INVOKING_KEY. + + - Function: int rl_possible_completions (int count, int invoking_key) + List the possible completions. See description of `rl_complete + ()'. This calls `rl_complete_internal()' with an argument of `?'. + + - Function: 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 `rl_complete()'. + This calls `rl_complete_internal()' with an argument of `*'. + + - Function: int rl_completion_mode (rl_command_func_t *cfunc) + Returns the apppriate value to pass to `rl_complete_internal()' + depending on whether CFUNC was called twice in succession and the + value of the `show-all-if-ambiguous' variable. + Application-specific completion functions may use this function to + present the same interface as `rl_complete()'. + + - Function: 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 + TEXT. If there are no completions, returns `NULL'. The first + entry in the returned array is the substitution for TEXT. The + remaining entries are the possible completions. The array is + terminated with a `NULL' pointer. + + ENTRY_FUNC is a function of two args, and returns a `char *'. The + first argument is TEXT. The second is a state argument; it is + zero on the first call, and non-zero on subsequent calls. + ENTRY_FUNC returns a `NULL' pointer to the caller when there are + no more matches. + + - Function: char * rl_filename_completion_function (const char *text, + int state) + A generator function for filename completion in the general case. + 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). + + - Function: char * rl_username_completion_function (const char *text, + int state) + A completion generator for usernames. TEXT contains a partial + username preceded by a random character (usually `~'). As with all + completion generators, STATE is zero on the first call and non-zero + for subsequent calls. + + +File: readline.info, Node: Completion Variables, Next: A Short Completion Example, Prev: Completion Functions, Up: Custom Completers + +Completion Variables +-------------------- + + - Variable: rl_compentry_func_t * rl_completion_entry_function + A pointer to the generator function for `rl_completion_matches()'. + `NULL' means to use `rl_filename_completion_function()', the + default filename completer. + + - Variable: rl_completion_func_t * rl_attempted_completion_function + A pointer to an alternative function to create matches. The + function is called with TEXT, START, and END. START and END are + indices in `rl_line_buffer' defining the boundaries of TEXT, which + is a character string. If this function exists and returns + `NULL', or if this variable is set to `NULL', then `rl_complete()' + will call the value of `rl_completion_entry_function' to generate + matches, otherwise the array of strings returned will be used. If + this function sets the `rl_attempted_completion_over' variable to + a non-zero value, Readline will not perform its default completion + even if this function returns no matches. + + - Variable: 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 + `rl_filename_quote_characters' appears in a completed filename. + The function is called with TEXT, MATCH_TYPE, and QUOTE_POINTER. + The TEXT is the filename to be quoted. The MATCH_TYPE is either + `SINGLE_MATCH', if there is only one completion match, or + `MULT_MATCH'. Some functions use this to decide whether or not to + insert a closing quote character. The QUOTE_POINTER is a pointer + to any opening quote character the user typed. Some functions + choose to reset this character. + + - Variable: 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 TEXT, the text + of the word to be dequoted, and QUOTE_CHAR, which is the quoting + character that delimits the filename (usually `'' or `"'). If + QUOTE_CHAR is zero, the filename was not in an embedded string. + + - Variable: 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: TEXT, the text of the line, + and INDEX, the index of the character in the line. It is used to + decide whether a character found in + `rl_completer_word_break_characters' should be used to break words + for the completer. + + - Variable: 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 `NULL' terminated array of matches. + The first element (`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. + + - Variable: 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. + + - Variable: 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: (`char **'MATCHES, `int' + NUM_MATCHES, `int' MAX_LENGTH) where MATCHES is the array of + matching strings, NUM_MATCHES is the number of strings in that + array, and MAX_LENGTH is the length of the longest string in that + array. Readline provides a convenience function, + `rl_display_match_list', that takes care of doing the display to + Readline's output stream. That function may be called from this + hook. + + - Variable: 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: `" + \t\n\"\\'`@$><=;|&{("'. + + - Variable: const char * rl_basic_quote_characters + A list of quote characters which can cause a word break. + + - Variable: const char * rl_completer_word_break_characters + The list of characters that signal a break between words for + `rl_complete_internal()'. The default list is the value of + `rl_basic_word_break_characters'. + + - Variable: 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 `rl_completer_word_break_characters' are treated as any + other character, unless they also appear within this list. + + - Variable: 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. + + - Variable: const char * rl_special_prefixes + The list of characters that are word break characters, but should + be left in 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. + + - Variable: 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. + + - Variable: 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 (` '). Setting + this to the null character (`\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. + + - Variable: int rl_completion_suppress_append + If non-zero, 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. + + - Variable: 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 MARK-DIRECTORIES variable. This variable exists so + that application completion functions can override the user's + global preference (set via the 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. + + - Variable: int rl_ignore_completion_duplicates + If non-zero, then duplicates in the matches are removed. The + default is 1. + + - Variable: int rl_filename_completion_desired + Non-zero means that the results of the matches are to be treated as + filenames. This is _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 `rl_filename_quote_characters' and + `rl_filename_quoting_desired' is set to a non-zero value. + + - Variable: 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 + `rl_filename_quote_chars'. This is _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 `rl_filename_quoting_function'. + + - Variable: int rl_attempted_completion_over + If an application-specific completion function assigned to + `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. + + - Variable: int rl_completion_type + Set to a character describing the type of completion Readline is + currently attempting; see the description of + `rl_complete_internal()' (*note Completion Functions::) for the + list of characters. + + - Variable: int rl_inhibit_completion + If this variable is non-zero, completion is inhibited. The + completion character will be inserted as any other bound to + `self-insert'. + + +File: readline.info, Node: A Short Completion Example, Prev: Completion Variables, Up: Custom Completers + +A Short Completion Example +-------------------------- + + Here is a small application demonstrating the use of the GNU Readline +library. It is called `fileman', and the source code resides in +`examples/fileman.c'. This sample application provides completion of +command names, line editing features, and access to the history list. + + /* 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 + #include + #include + #include + #include + + #include + #include + + 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); + } + + +File: readline.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU Readline, Up: Top + +Concept Index +************* + +* Menu: + +* command editing: Readline Bare Essentials. +* editing command lines: Readline Bare Essentials. +* initialization file, readline: Readline Init File. +* interaction, readline: Readline Interaction. +* kill ring: Readline Killing Commands. +* killing text: Readline Killing Commands. +* notation, readline: Readline Bare Essentials. +* readline, function: Basic Behavior. +* variables, readline: Readline Init File Syntax. +* yanking text: Readline Killing Commands. + + +File: readline.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top + +Function and Variable Index +*************************** + +* Menu: + +* _rl_digit_p: Utility Functions. +* _rl_digit_value: Utility Functions. +* _rl_lowercase_p: Utility Functions. +* _rl_to_lower: Utility Functions. +* _rl_to_upper: Utility Functions. +* _rl_uppercase_p: Utility Functions. +* abort (C-g): Miscellaneous Commands. +* accept-line (Newline or Return): Commands For History. +* backward-char (C-b): Commands For Moving. +* backward-delete-char (Rubout): Commands For Text. +* backward-kill-line (C-x Rubout): Commands For Killing. +* backward-kill-word (M-): Commands For Killing. +* backward-word (M-b): Commands For Moving. +* beginning-of-history (M-<): Commands For History. +* beginning-of-line (C-a): Commands For Moving. +* bell-style: Readline Init File Syntax. +* call-last-kbd-macro (C-x e): Keyboard Macros. +* capitalize-word (M-c): Commands For Text. +* character-search (C-]): Miscellaneous Commands. +* character-search-backward (M-C-]): Miscellaneous Commands. +* clear-screen (C-l): Commands For Moving. +* comment-begin: Readline Init File Syntax. +* complete (): Commands For Completion. +* completion-query-items: Readline Init File Syntax. +* convert-meta: Readline Init File Syntax. +* copy-backward-word (): Commands For Killing. +* copy-forward-word (): Commands For Killing. +* copy-region-as-kill (): Commands For Killing. +* delete-char (C-d): Commands For Text. +* delete-char-or-list (): Commands For Completion. +* delete-horizontal-space (): Commands For Killing. +* digit-argument (M-0, M-1, ... M--): Numeric Arguments. +* disable-completion: Readline Init File Syntax. +* do-uppercase-version (M-a, M-b, M-X, ...): Miscellaneous Commands. +* downcase-word (M-l): Commands For Text. +* dump-functions (): Miscellaneous Commands. +* dump-macros (): Miscellaneous Commands. +* dump-variables (): Miscellaneous Commands. +* editing-mode: Readline Init File Syntax. +* enable-keypad: Readline Init File Syntax. +* end-kbd-macro (C-x )): Keyboard Macros. +* end-of-history (M->): Commands For History. +* end-of-line (C-e): Commands For Moving. +* exchange-point-and-mark (C-x C-x): Miscellaneous Commands. +* expand-tilde: Readline Init File Syntax. +* forward-backward-delete-char (): Commands For Text. +* forward-char (C-f): Commands For Moving. +* forward-search-history (C-s): Commands For History. +* forward-word (M-f): Commands For Moving. +* history-preserve-point: Readline Init File Syntax. +* history-search-backward (): Commands For History. +* history-search-forward (): Commands For History. +* horizontal-scroll-mode: Readline Init File Syntax. +* input-meta: Readline Init File Syntax. +* insert-comment (M-#): Miscellaneous Commands. +* insert-completions (M-*): Commands For Completion. +* isearch-terminators: Readline Init File Syntax. +* keymap: Readline Init File Syntax. +* kill-line (C-k): Commands For Killing. +* kill-region (): Commands For Killing. +* kill-whole-line (): Commands For Killing. +* kill-word (M-d): Commands For Killing. +* mark-modified-lines: Readline Init File Syntax. +* mark-symlinked-directories: Readline Init File Syntax. +* match-hidden-files: Readline Init File Syntax. +* menu-complete (): Commands For Completion. +* meta-flag: Readline Init File Syntax. +* next-history (C-n): Commands For History. +* non-incremental-forward-search-history (M-n): Commands For History. +* non-incremental-reverse-search-history (M-p): Commands For History. +* output-meta: Readline Init File Syntax. +* overwrite-mode (): Commands For Text. +* page-completions: Readline Init File Syntax. +* possible-completions (M-?): Commands For Completion. +* prefix-meta (): Miscellaneous Commands. +* previous-history (C-p): Commands For History. +* quoted-insert (C-q or C-v): Commands For Text. +* re-read-init-file (C-x C-r): Miscellaneous Commands. +* readline: Basic Behavior. +* redraw-current-line (): Commands For Moving. +* reverse-search-history (C-r): Commands For History. +* revert-line (M-r): Miscellaneous Commands. +* rl_add_defun: Function Naming. +* rl_add_funmap_entry: Associating Function Names and Bindings. +* rl_add_undo: Allowing Undoing. +* rl_alphabetic: Utility Functions. +* rl_already_prompted: Readline Variables. +* rl_attempted_completion_function: Completion Variables. +* rl_attempted_completion_over: Completion Variables. +* rl_basic_quote_characters: Completion Variables. +* rl_basic_word_break_characters: Completion Variables. +* rl_begin_undo_group: Allowing Undoing. +* rl_bind_key: Binding Keys. +* rl_bind_key_in_map: Binding Keys. +* rl_binding_keymap: Readline Variables. +* rl_callback_handler_install: Alternate Interface. +* rl_callback_handler_remove: Alternate Interface. +* rl_callback_read_char: Alternate Interface. +* rl_catch_signals: Readline Signal Handling. +* rl_catch_sigwinch: Readline Signal Handling. +* rl_char_is_quoted_p: Completion Variables. +* rl_cleanup_after_signal: Readline Signal Handling. +* rl_clear_message: Redisplay. +* rl_clear_pending_input: Character Input. +* rl_clear_signals: Readline Signal Handling. +* rl_complete <1>: How Completing Works. +* rl_complete: Completion Functions. +* rl_complete_internal: Completion Functions. +* rl_completer_quote_characters: Completion Variables. +* rl_completer_word_break_characters: Completion Variables. +* rl_completion_append_character: Completion Variables. +* rl_completion_display_matches_hook: Completion Variables. +* rl_completion_entry_function <1>: Completion Variables. +* rl_completion_entry_function: How Completing Works. +* rl_completion_mark_symlink_dirs: Completion Variables. +* rl_completion_matches: Completion Functions. +* rl_completion_mode: Completion Functions. +* rl_completion_query_items: Completion Variables. +* rl_completion_suppress_append: Completion Variables. +* rl_completion_type: Completion Variables. +* rl_copy_keymap: Keymaps. +* rl_copy_text: Modifying Text. +* rl_crlf: Redisplay. +* rl_delete_text: Modifying Text. +* rl_deprep_term_function: Readline Variables. +* rl_deprep_terminal: Terminal Management. +* rl_ding: Utility Functions. +* rl_directory_completion_hook: Completion Variables. +* rl_discard_keymap: Keymaps. +* rl_dispatching: Readline Variables. +* rl_display_match_list: Utility Functions. +* rl_do_undo: Allowing Undoing. +* rl_done: Readline Variables. +* rl_editing_mode: Readline Variables. +* rl_end: Readline Variables. +* rl_end_undo_group: Allowing Undoing. +* rl_erase_empty_line: Readline Variables. +* rl_event_hook: Readline Variables. +* rl_execute_next: Character Input. +* rl_executing_keymap: Readline Variables. +* rl_executing_macro: Readline Variables. +* rl_expand_prompt: Redisplay. +* rl_explicit_arg: Readline Variables. +* rl_extend_line_buffer: Utility Functions. +* rl_filename_completion_desired: Completion Variables. +* rl_filename_completion_function: Completion Functions. +* rl_filename_dequoting_function: Completion Variables. +* rl_filename_quote_characters: Completion Variables. +* rl_filename_quoting_desired: Completion Variables. +* rl_filename_quoting_function: Completion Variables. +* rl_forced_update_display: Redisplay. +* rl_free_line_state: Readline Signal Handling. +* rl_free_undo_list: Allowing Undoing. +* rl_function_dumper: Associating Function Names and Bindings. +* rl_function_of_keyseq: Associating Function Names and Bindings. +* rl_funmap_names: Associating Function Names and Bindings. +* rl_generic_bind: Binding Keys. +* rl_get_keymap: Keymaps. +* rl_get_keymap_by_name: Keymaps. +* rl_get_keymap_name: Keymaps. +* rl_get_screen_size: Readline Signal Handling. +* rl_get_termcap: Miscellaneous Functions. +* rl_getc: Character Input. +* rl_getc_function: Readline Variables. +* rl_gnu_readline_p: Readline Variables. +* rl_ignore_completion_duplicates: Completion Variables. +* rl_ignore_some_completions_function: Completion Variables. +* rl_inhibit_completion: Completion Variables. +* rl_initialize: Utility Functions. +* rl_insert_completions: Completion Functions. +* rl_insert_text: Modifying Text. +* rl_instream: Readline Variables. +* rl_invoking_keyseqs: Associating Function Names and Bindings. +* rl_invoking_keyseqs_in_map: Associating Function Names and Bindings. +* rl_kill_text: Modifying Text. +* rl_last_func: Readline Variables. +* rl_library_version: Readline Variables. +* rl_line_buffer: Readline Variables. +* rl_list_funmap_names: Associating Function Names and Bindings. +* rl_macro_bind: Miscellaneous Functions. +* rl_macro_dumper: Miscellaneous Functions. +* rl_make_bare_keymap: Keymaps. +* rl_make_keymap: Keymaps. +* rl_mark: Readline Variables. +* rl_message: Redisplay. +* rl_modifying: Allowing Undoing. +* rl_named_function: Associating Function Names and Bindings. +* rl_num_chars_to_read: Readline Variables. +* rl_numeric_arg: Readline Variables. +* rl_on_new_line: Redisplay. +* rl_on_new_line_with_prompt: Redisplay. +* rl_outstream: Readline Variables. +* rl_parse_and_bind: Binding Keys. +* rl_pending_input: Readline Variables. +* rl_point: Readline Variables. +* rl_possible_completions: Completion Functions. +* rl_pre_input_hook: Readline Variables. +* rl_prep_term_function: Readline Variables. +* rl_prep_terminal: Terminal Management. +* rl_prompt: Readline Variables. +* rl_push_macro_input: Modifying Text. +* rl_read_init_file: Binding Keys. +* rl_read_key: Character Input. +* rl_readline_name: Readline Variables. +* rl_readline_state: Readline Variables. +* rl_readline_version: Readline Variables. +* rl_redisplay: Redisplay. +* rl_redisplay_function: Readline Variables. +* rl_replace_line: Utility Functions. +* rl_reset_after_signal: Readline Signal Handling. +* rl_reset_line_state: Redisplay. +* rl_reset_terminal: Terminal Management. +* rl_resize_terminal: Readline Signal Handling. +* rl_restore_prompt: Redisplay. +* rl_save_prompt: Redisplay. +* rl_set_key: Binding Keys. +* rl_set_keyboard_input_timeout: Character Input. +* rl_set_keymap: Keymaps. +* rl_set_paren_blink_timeout: Miscellaneous Functions. +* rl_set_prompt: Redisplay. +* rl_set_screen_size: Readline Signal Handling. +* rl_set_signals: Readline Signal Handling. +* rl_show_char: Redisplay. +* rl_special_prefixes: Completion Variables. +* rl_startup_hook: Readline Variables. +* rl_stuff_char: Character Input. +* rl_terminal_name: Readline Variables. +* rl_tty_set_default_bindings: Terminal Management. +* rl_unbind_command_in_map: Binding Keys. +* rl_unbind_function_in_map: Binding Keys. +* rl_unbind_key: Binding Keys. +* rl_unbind_key_in_map: Binding Keys. +* rl_username_completion_function: Completion Functions. +* rl_variable_bind: Miscellaneous Functions. +* rl_variable_dumper: Miscellaneous Functions. +* self-insert (a, b, A, 1, !, ...): Commands For Text. +* set-mark (C-@): Miscellaneous Commands. +* show-all-if-ambiguous: Readline Init File Syntax. +* start-kbd-macro (C-x (): Keyboard Macros. +* transpose-chars (C-t): Commands For Text. +* transpose-words (M-t): Commands For Text. +* undo (C-_ or C-x C-u): Miscellaneous Commands. +* universal-argument (): Numeric Arguments. +* unix-line-discard (C-u): Commands For Killing. +* unix-word-rubout (C-w): Commands For Killing. +* upcase-word (M-u): Commands For Text. +* visible-stats: Readline Init File Syntax. +* yank (C-y): Commands For Killing. +* yank-last-arg (M-. or M-_): Commands For History. +* yank-nth-arg (M-C-y): Commands For History. +* yank-pop (M-y): Commands For Killing. + + + +Tag Table: +Node: Top1164 +Node: Command Line Editing1763 +Node: Introduction and Notation2414 +Node: Readline Interaction4032 +Node: Readline Bare Essentials5219 +Node: Readline Movement Commands7000 +Node: Readline Killing Commands7957 +Node: Readline Arguments9866 +Node: Searching10902 +Node: Readline Init File13045 +Node: Readline Init File Syntax14106 +Node: Conditional Init Constructs24989 +Node: Sample Init File27514 +Node: Bindable Readline Commands30698 +Node: Commands For Moving31748 +Node: Commands For History32597 +Node: Commands For Text35455 +Node: Commands For Killing38169 +Node: Numeric Arguments40120 +Node: Commands For Completion41248 +Node: Keyboard Macros42780 +Node: Miscellaneous Commands43339 +Node: Readline vi Mode46688 +Node: Programming with GNU Readline48506 +Node: Basic Behavior49474 +Node: Custom Functions52904 +Node: Readline Typedefs54382 +Node: Function Writing56011 +Node: Readline Variables57219 +Node: Readline Convenience Functions66642 +Node: Function Naming67624 +Node: Keymaps68876 +Node: Binding Keys70632 +Node: Associating Function Names and Bindings73558 +Node: Allowing Undoing75803 +Node: Redisplay78338 +Node: Modifying Text81409 +Node: Character Input82638 +Node: Terminal Management84418 +Node: Utility Functions85593 +Node: Miscellaneous Functions87932 +Node: Alternate Interface89996 +Node: A Readline Example92141 +Node: Readline Signal Handling94078 +Node: Custom Completers99681 +Node: How Completing Works100396 +Node: Completion Functions103394 +Node: Completion Variables106778 +Node: A Short Completion Example117049 +Node: Concept Index129602 +Node: Function and Variable Index130424 + +End Tag Table diff --git a/readline-doc-4.3/doc/readline.ps b/readline-doc-4.3/doc/readline.ps new file mode 100644 index 0000000..21ca2ca --- /dev/null +++ b/readline-doc-4.3/doc/readline.ps @@ -0,0 +1,5200 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: readline.dvi +%%Pages: 66 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -D 300 -t letter -o readline.ps readline.dvi +%DVIPSParameters: dpi=300, compressed +%DVIPSSource: TeX output 2002.06.27:1354 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 300 300 (readline.dvi) +@start +%DVIPSBitmapFont: Fa cmbxti10 14.4 1 +/Fa 1 47 df<120E123FEA7F80A212FFA21300127E123C0909798815>46 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmsl9 9 1 +/Fb 1 121 df<383FC7E038078380EB0200EA038413C8EA01D8EA00F05B7F1201133812 +02487EEA081E123838FC3FC013107F8F14>120 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmsltt10 9 4 +/Fc 4 78 df45 D48 +D<134013E0EA01C01203120F123D12111201EA0380A6EA0700A6120EEAFFE0A20B177B96 +14>I<381F81F813C1380FC3E0EA0EC213C6A213CE13CC381CCDC013DD13D9A213F1A238 +38E3801303A53870070038FC0FC0A215177F9614>77 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd cmtt9 9 47 +/Fd 47 127 df<126012F0AD12601200A4126012F0A212600417789614>33 +D35 +D40 D<128012C01260123012381218121C120EA31207A9120EA3121C121812 +381230126012C01280081D7C9914>II<127012F812FCA2127C120C1218 +123012E012C0060A798414>44 DI<127012F8A3127005057984 +14>I<1203A25A5A123F12F712471207AEEA7FF0A20C177C9614>49 +D<1306131E133E13F8EA01F0EA03C0EA0F80EA1F00123C12F85A7E123C121FEA0F80EA03 +C0EA01F0EA00F8133E131E13060F157E9514>60 D<12C012F07E123E7EEA0780EA03E0EA +01F0EA0078133E131E133E1378EA01F0EA03E0EA0780EA1F00123E12F85A12C00F157E95 +14>62 DIII<3801F180EA07FFEA0E1FEA1C071238EA7003A348C7FCA738 +700380A338380700121CEA0E0EEA07FCEA01F011177F9614>67 D<38FC1F80A2007C1300 +EA7637A4EA7777A2EA7367A313E7EA71C7A2EA7007A638F80F80A211177F9614>77 +D<38FE3F80A2383E0E00123BA4138E1239A213CEA31238A213EE136EA4133E12FEA21117 +7F9614>I82 D93 +D95 D97 D<12FCA2121CA513F8EA1DFEEA +1F07EA1E03001C1380EB01C0A6EB0380001E1300EA1F0EEA1DFCEA0CF81217809614>I< +EA03F8EA0FFEEA1C0EEA3804EA7000126012E0A412601270EA380EEA1C1EEA0FFCEA03F0 +0F107E8F14>I<137EA2130EA5EA07CEEA0FFEEA1C3EEA301EEA700E12E0A61270EA301E +EA383E381FEFC0EA07CF12177F9614>II<13FCEA01FEEA +038EEA07041300A3EA7FFE12FFEA0700ACEAFFF8A20F177F9614>II<12FCA2121CA51378EA1D +FEEA1F86EA1E07121CAA38FF8FE0A21317809614>I<1206120FA21206C7FCA4B4FCA212 +07ACEAFFF8A20D187C9714>I<136013F0A213601300A4EA1FF0A2EA0070B2EA40E0EAE0 +C0EA7F80EA3F000C207E9714>I<12FCA2121CA5EBFF80A2EB1C005B5B5BEA1DC0EA1FE0 +A2EA1E70EA1C38133C131C7F38FF1F80A21117809614>IIIIIIIII<1206120EA4EA7FFC12FFEA0E +00A8130EA3131CEA07F8EA01F00F157F9414>II<38FE3F80A2383C1E00EA1C1CA36C5AA3EA0630EA0770A36C5AA31110 +7F8F14>I<38FE3F80A238700700EA380EA3EA39CEA3EA1B6C121AA3EA1E7CA2EA0E3811 +107F8F14>II<38FE3F80A2381C0E005BA2120E5BA212071330A2EA0370 +A25B1201A25BA3485A12730077C7FC127E123C11187F8F14>II126 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe cmti9 9 1 +/Fe 1 47 df<1230127812F0126005047C830C>46 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmr9 9 39 +/Ff 39 123 df<13FEEA038138060180EA0E03381C010090C7FCA5B51280EA1C03AE38FF +8FF0141A809915>12 DI<126012F0A212701210A31220A21240A2040B7D830B>44 +DI48 D<12035AB4FC1207B3A2EA +7FF80D187D9713>III<1318A2133813 +7813F813B8EA01381202A212041208121812101220124012C0B5FCEA0038A6EA03FF1018 +7F9713>III<1240EA7FFF13FEA2EA4004EA80081310A2 +EA00201340A21380120113005AA25A1206A2120EA5120410197E9813>III97 +D<12FC121CA913FCEA1D07381E0380381C01C0130014E0A6EB01C01480381E0300EA1906 +EA10F8131A809915>II<133F1307A9EA03E7EA0C17EA180F487E127012E0A6126012706C5A +EA1C373807C7E0131A7F9915>IIII<12FC121CA9137CEA1D87381E0380A2121CAB38FF9FF0141A809915>I<1218 +123CA212181200A612FC121CAE12FF081A80990A>I<12FC121CA9EB1FC0EB0F00130C5B +13205B13E0121DEA1E70EA1C7813387F131E7F148038FF9FE0131A809914>107 +D<12FC121CB3A6EAFF80091A80990A>I<38FC7C1F391D8E6380391E0781C0A2001C1301 +AB39FF9FE7F81D107F8F20>I +IIIIII<1208A41218A21238EAFFC0 +EA3800A81320A41218EA1C40EA07800B177F960F>I<38FC1F80EA1C03AB1307120CEA0E +0B3803F3F01410808F15>I<38FF0F80383C0700EA1C061304A26C5AA26C5AA3EA03A0A2 +EA01C0A36C5A11107F8F14>I<39FE7F1F8039381C0700003C1306381C0C04130E380E16 +081317A238072310149013A33803C1A014E0380180C0A319107F8F1C>I<38FE3F80383C +1E00EA1C086C5AEA0F306C5A6C5A12017F1203EA0270487E1208EA181CEA381E38FC3FC0 +12107F8F14>I<38FF0F80383C0700EA1C061304A26C5AA26C5AA3EA03A0A2EA01C0A36C +5AA248C7FCA212E112E212E4127811177F8F14>II +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg cmss10 10.95 2 +/Fg 2 42 df<13E0EA01C0EA0380120713005A121EA2121C123CA212381278A3127012F0 +AE12701278A31238123CA2121C121EA27E7E13801203EA01C0EA00E00B2E7CA112>40 +D<12E012707E123C121C121E7EA27E1380A2120313C0A3120113E0AE13C01203A3138012 +07A213005AA2121E121C123C12385A5A0B2E7EA112>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh cmbx10 12 27 +/Fh 27 123 df<90380FF83F90397FFDFFC03A01FC1FE3E03903F03FC7EA07E0D80FC013 +87ED83C091381F8000A6B612FCA2390FC01F80B2397FF8FFF8A223237FA221>11 +DI97 DII<49B4FCA2EB003FAB13FE3807FFBF380FC1FF48 +C67E003E7F127E127CA212FCA7127C127E123E6C5B380F81FF3907FF3FE0EA01FC1B237E +A220>I<13FE3807FF80380F83C0381E01E0383E00F0127E007C13F8147812FCB512F8A2 +00FCC7FCA3127CA26C1318A26C1330380F80E03803FFC0C6130015167E951A>II<9038FE0F803903FF9FC0380F83E3381F01F3391E00F000003E7FA5001E5BEA +1F01380F83E0380BFF80D808FEC7FC0018C8FCA2121C381FFFE014FC6C13FF7E001F1480 +397C001FC00078130F00F81307A3007CEB0F806CEB1F00381F807E6CB45A000113E01A21 +7F951D>II<121E123FEA7F80A4EA3F00121EC7FCA6EAFF80A2121FB2EAFFF0A20C24 +7EA30F>I107 +DI<3AFF03F803F890390FFE0FFE3A1F183F +183F9039201F201F014001C01380A201801380AE3BFFF0FFF0FFF0A22C167D9531>I<38 +FF03F0EB0FFC381F187EEB203EEB403FA21380AE39FFF1FFE0A21B167D9520>I<13FF00 +0713E0380F81F0381F00F8003E137C48133EA300FC133FA7007C133E007E137E003E137C +6C13F8380F81F03807FFE0C6130018167E951D>I<38FF87F0EBBFFC381FF07EEBC01F90 +38800F8015C0A2EC07E0A715C0140FA2EC1F8001C01300EBF07EEBBFFCEB8FE00180C7FC +A8EAFFF0A21B207E9520>I +I<38FF0F80EB1FE0381F33F013631343A2EBC1E0EB8000ADEAFFF8A214167E9518>I<38 +07F980EA1FFFEA3807EA7003EAF001A26CC7FCB4FC13F8EA7FFE6C7E6C1380120738003F +C0EAC007130312E0A200F0138038FC0F00EAEFFEEAC3F812167E9517>I<487EA41203A2 +1207A2120F123FB5FCA2EA1F80ABEB8180A5380F830013C3EA07FEEA01F811207F9F16> +I<38FF81FFA2381F803FAF5C5C380FC1BF3907FF3FE0EA01FC1B167D9520>I<39FFF01F +E0A2391FC00700000F1306EBE00E0007130C13F000035BA26C6C5AA26C6C5AA2EBFEE0EB +7EC0137F6D5AA26DC7FCA2130EA21B167F951E>I<3AFFF3FF83FCA23A1F807C00E0D80F +C014C08001E013010007017F1380A2D803F0EB0300ECCF8301F81387D801F913C61487D8 +00FD13ECEBFF0315FC017F5BEB7E01013E5BEB3C00A20118136026167F9529>I<39FFF0 +7FC0A2390FC01C006C6C5A6D5A00035B6C6C5A3800FD80137F91C7FC7F6D7E497EEB37E0 +EB67F013C33801C1F8380380FC48487E000E137F39FF81FFE0A21B167F951E>I<39FFF0 +1FE0A2391FC00700000F1306EBE00E0007130C13F000035BA26C6C5AA26C6C5AA2EBFEE0 +EB7EC0137F6D5AA26DC7FCA2130EA2130CA25B1278EAFC3813305BEA69C0EA7F80001FC8 +FC1B207F951E>I<387FFFF0A2387C07E038700FC0EA601F00E0138038C03F005B137EC6 +5A1201485AEBF030EA07E0120FEBC070EA1F80003F1360EB00E0EA7E03B5FCA214167E95 +19>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi cmtt10 12 29 +/Fi 29 122 df<13E0A538F0E1E0EAFCE7387EEFC0381FFF00EA07FCEA01F0EA07FCEA1F +FF387EEFC038FCE7E0EAF0E13800E000A513157D991A>42 D69 +D<387FFFFCB5FC7E380E001CA51400A2EB0380A3EA0FFFA3EA0E03A390C7FCA8EA7FE012 +FF127F161E7F9D1A>I73 +D<387F03F838FF87FC387F03F8381C01E0EB03C01480EB07005B131E131C5B13785B7F12 +1DEA1FDC139C130EEA1E0F7F001C13801303EB01C0A2EB00E0A21470007F13FC38FF81FE +387F00FC171E7F9D1A>75 DI<387FFFC0B512E0A26C13C013047D7E1A>95 D97 D<12FEA3120EA6133EEBFF80000F13E0EBC1F0EB8070EB00 +38120E141CA7000F13381478EB80F0EBC1E0EBFFC0000E138038063E00161E7F9D1A>I< +EBFF80000313C0000F13E0EA1F01383C00C04813001270A25AA51270A2007813707E381F +01F0380FFFE0000313C03800FE0014157D941A>III< +EB07E0EB1FF0EB3FF8EB7878EBF030EBE000A4387FFFF0B5FCA23800E000AF383FFF8048 +13C06C1380151E7F9D1A>I<3801F87C3807FFFE5A381E078C381C0380383801C0A5381C +0380EA1E07381FFF005BEA39F80038C7FCA27E381FFF8014E04813F83878007C0070131C +48130EA40070131C0078133C003E13F8381FFFF0000713C00001130017217F941A>I<12 +FEA3120EA6133EEBFF80000F13C013C1EB80E01300120EAC38FFE3FE13E713E3171E7F9D +1A>I +I<12FEA3120EA6EB0FFCEB1FFEEB0FFCEB03C0EB0780EB0F00131E5B5B13FC120F13DE13 +8F380E07801303EB01C014E0EB00F038FFE3FE14FF14FE181E7F9D1A>107 +DI<387CE0E038FFFBF8EA7FFF381F1F1CEA +1E1EA2EA1C1CAC387F1F1F39FF9F9F80397F1F1F00191580941A>IIII<3801F8E0EA07FEEA0FFFEA1E07EA3C03EA78011270EAE000A613011270EA +7803123CEA1E0FEA0FFFEA07FCEA01F0C7FCA8EB0FFEA317207E941A>I<387F81F838FF +8FFC387F9FFE3803FE1EEBF80CEBE000A25B5BAAEA7FFFB5FC7E17157F941A>I<3807FB +80EA1FFF127FEA7807EAE003A30078C7FCEA7FC0EA1FFCEA07FE38003F801307386001C0 +12E0A2EAF00338FC0780B51200EAEFFEEAE3F812157C941A>I<487E1203A6387FFFE0B5 +FCA238038000AA1470A43801C1E013FF6C1380EB3F00141C7F9B1A>I<38FE0FE0A3EA0E +00AD1301EA0F033807FFFE7EEA00FC17157F941A>I<387FC7FC00FF13FE007F13FC380E +00E0A3380701C0A338038380A33801C700A3EA00EEA3137CA2133817157F941A>I<387F +C7FC00FF13FE007F13FC380E00E0A27EEB01C013811203EB8380EA01C3A2EBC700EA00E7 +A213E61366136E133CA31338A3137813701230EA78E01271EA7FC06C5A001EC7FC17207F +941A>121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj cmbx12 13.14 52 +/Fj 52 122 df<123C127E12FFA4127E123C08087C8711>46 D48 D<131C133C13FC12FFA21200B3AA +387FFFFCA216237CA21F>I<48B4FC000713C0381E07F0383803F8386001FC387C00FE12 +FE14FF147FA2127C003813FFC7FC14FEA2EB01FC14F8EB03F0EB07E01480EB0F00131E5B +1370EBE003EA01C038038007380700061206380FFFFE5A5A4813FCB5FCA218237DA21F> +I<48B4FC000713E0381E03F0383801F8003C13FC387E00FEA3123EEA1C01000013FCA2EB +03F8EB07F0EB0FC03801FF00A2380007E0EB01F014F8EB00FC14FE14FFA21210127C12FE +A214FEA2387C01FC007013F8383E07F0380FFFC00001130018237DA21F>I<14381478A2 +14F81301130313071306130C131C13381330136013E0EA01C01380EA03005A120E5A1218 +5A12705AB612C0A2390001F800A790387FFFC0A21A237EA21F>I<0018130C001F137CEB +FFF814F014E014C01480EBFC000018C7FCA513FF001B13E0381F03F0381C00F8000813FC +C7127EA3147FA2127812FCA3147E5A006013FC1270383801F8381E07E03807FFC03801FE +0018237DA21F>II<1230123C003FB512 +C0A215804814005C5C38600018A200E05B485B5CC6485AA249C7FC1306130EA25BA2133C +A25BA213F8A41201A66C5A13601A257DA41F>II<13FF000313C0380F83E0381F00F04813F8007E13 +7CA2147E12FEA3147FA4127E14FF123EEA3F01001F137FEA0FFEEA03FCC7FC147EA2123C +007E13FCA214F814F0EA7C01383003E0381C0F80380FFF00EA03F818237DA21F>I<141C +A2143EA3147FA24A7EA39038019FC0A29038031FE0140F01077FEB0607A2010C7F140301 +1C7FEB1801A2496C7EA2017FB5FCA29039E0007F8049133FA2484880151F00038190C712 +0FA2486E7ED8FFF090B51280A229257EA42E>65 DI<9138FF8008010FEBF01890393FC03C789039FE0006F8D801F8130348481301 +4848130048481478121F48481438A2007F151890C8FCA2481500A97E16187F123FA26C6C +1430120F6C6C14606C6C14C06C6CEB0180D800FEEB070090383FC01E90380FFFF8010013 +C025257DA42C>I69 DI72 +DI75 DIII82 D<01FF1380000713E3380F80F7381E001F48130F481307140312F81401A2 +7E91C7FCB4FCEA7FE013FE383FFFE014F86C13FE00077F6C1480C67E010313C0EB003FEC +0FE01407A200C01303A315C07E6C13076C14806CEB0F0038FFC03E38E3FFF838803FE01B +257DA422>I<007FB612F8A2397E00FE010078EC00780070153800601518A200E0151C16 +0C5AA4C71400B3A390B512FEA226247EA32B>IIII89 D97 DIII<137F3803FFC03807C1F0380F80F8EA1F0048 +137C127E147E12FEA2B512FEA248C7FCA3127EA214067E6C130C380F80183807E0703803 +FFE038007F8017187E971C>II<3901FF07C00007EBDFE0380F83F1EA1F +01393E00F800007E7FA6003E5B6C485A380F83E0EBFFC0001190C7FC0030C8FCA2123812 +3C383FFFE06C13FC806C7F481480383C003F48EB0FC000F81307A4007CEB0F806CEB1F00 +381F807E3807FFF8C613C01B247E971F>II<120FEA1F80EA3FC0A4 +EA1F80EA0F00C7FCA7EA7FC0A2120FB3A2EAFFF8A20D277EA611>I107 DI<26FF80FE137F903A83FF81FFC03B0F8E0FC707E0019813CC903A +9007E803F001A013F0A201C013E0AF3BFFFC7FFE3FFFA230187E9733>I<38FF80FE9038 +83FF80390F8E0FC0139890389007E013A0A213C0AF39FFFC7FFEA21F187E9722>II<38FFC1FCEBCFFF390FFC1FC0 +9038F007E001C013F0140315F8140115FCA8EC03F8A215F0EBE0079038F00FE09038DC1F +809038CFFF00EBC3F801C0C7FCA9EAFFFCA21E237F9722>I<38FF83E0EB8FF8380F8C7C +EB90FC13B013A01478EBE0005BAEEAFFFEA216187F9719>114 D<3807F8C0EA1FFFEA3C +07EA7001EAF000A300FC1300B47EEA7FFC7F383FFF80000F13C0120338001FE01303EAC0 +01A212E014C0EAF00338FC078038EFFF00EAC3FC13187E9718>I<13C0A41201A3120312 +07120F121FB512C0A2380FC000AC1460A63807E0C013E13801FF8038007E0013237FA218 +>I<39FFC07FE0A2000F1307B0140FA200071317EBE0673903FFC7FE38007F071F187E97 +22>I<39FFF80FF8A2390FC001C015803907E00300A26D5A00031306EBF80E0001130C13 +FC00005B13FEEB7E30A26D5AA214E06D5AA26D5AA26DC7FCA21D187F9720>I<3BFFF9FF +E0FF80A23B1FC03F001C00000F6D13181580D807E05CA29039F03FC07000030137136015 +E02601F8635BA29038FCE3F1000001C15B15F990267F80FBC7FCA215FF90383F007EA201 +1E133CA3010C131829187F972C>I<39FFF83FF0A2390FC00F003807E00E6C6C5A6D5A6C +6C5A00001360EB7EC06D5AA2131F6D7E497E80EB33F81361EBE0FC3801C07E3803807F39 +07003F8048131F39FFC07FF8A21D187F9720>I<39FFF80FF8A2390FC001C015803907E0 +0300A26D5A00031306EBF80E0001130C13FC00005B13FEEB7E30A26D5AA214E06D5AA26D +5AA26DC7FCA21306A25B1230EA781CEAFC185B1370EA68E0EA7FC0001FC8FC1D237F9720 +>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk cmsl10 10.95 48 +/Fk 48 122 df12 +DI +45 D<137EEA01C338030180000713C0EA0E0014E05AA2EA3C0112381278A538F003C0A5 +1480130712E01400A2130E1260EA701CEA3038EA3870EA0FC0131F7C9D17>48 +D<13181338EA01F8EA0E701200A513E0A6EA01C0A6EA0380A6EA07001380EAFFFC0E1E7B +9D17>I<1408140C141C143CA2147C147E149EA2EB011EA21302801304A21308A2011013 +8014071320A2EB7FFF90384007C0EB8003A2EA0100A21202EC01E01206001F130339FF80 +1FFE1F207F9F22>65 D<0007B5FC3900F803C090387801E0EC00F04913F8A515F03801E0 +01EC03E015C0EC0F809038FFFE009038E00F803903C003C0EC01E015F0A21400A2485A14 +01A215E01403EC07C0390F000F80EC3E00B512F01D1F7E9E20>II<0007B57E3900F801E0903878007081497F151E150E150FA348481480A6 +484814005DA3151E153E4848133C5DA25D4A5A4A5A260F000FC7FC143CB512F0211F7E9E +23>I<0007B512FC3900F8007C0178131C150C5B1504A414043901E00800A31438EBFFF8 +EBE0383803C010A4EC00081510485AA21520A2156015C0380F00011407B612801E1F7E9E +1F>I<0007B512F83900F800780178133815185B1508A53901E00800A314181438EBFFF8 +3803C0301410A491C7FC485AA648C8FC7FEAFFFC1D1F7E9E1E>I<3A07FF83FFC03A00F8 +007C000178133CA2495BA648485BA490B5FCEBE0004848485AA64848485AA64848485A01 +807F39FFF07FF8221F7E9E22>72 D<3807FF803800F8001378A25BA6485AA6485AA6485A +A648C7FC7FEAFFF0111F7E9E10>I<3A07FF803FE03A00F8001F000178130C5D4913205D +5D4AC7FC1402140848485A5C146014F013E1EBE4F83803C878EBD07CEBE03CEBC03E141E +141F48487E81140781140381380F00016D487E39FFF00FFE231F7E9E23>75 +D<3807FFE0D800FCC7FC1378A25BA6485AA6485AA41580EC0100EA0780A25C1402140614 +0E380F001E147CB512FC191F7E9E1C>IIII<0007B5FC3900F803C090387800F015785B157CA41578484813F815F0EC +01E0EC03C0EC0F00EBFFFCD803C0C7FCA6485AA648C8FC7FEAFFF81E1F7E9E1F>I<3807 +FFFE3900F8078090387801E0EC00F05B15F8A415F03801E00115E0EC03C0EC0780EC1E00 +EBFFF03803C03880141E140EA2140F48485AA51501D80F0013029038800F8239FFF8078C +C7EA01F020207E9E22>82 DI<003FB512 +F0383C078000301430126039400F0010A212C01280A3D8001E1300A65BA65BA65B7F383F +FFE01C1F7A9E21>I<39FFF00FF8391F0003E06CEB01801400001EEB0100A6481302A648 +5BA600705BA25CA200785B1238001813C06C48C7FCEA0706EA01F81D20799E22>I<3BFF +F07FF81FF03B1F000FC007C0001E903907800380001FED01006C1502140F5EEC17C00213 +5B142301805C000713435E14C3913883E0401481D981015B13C1D803C213E193C7FC13C4 +15F2EBC80015F4EA01F015F85B5D5B15605B000014402C207A9E2F>87 +D97 D<1207123F120F7EA2120EA65A137CEA1D +83381E0180001C13C0EB00E05A14F0A5387001E0A214C013031480EB0700EAE80EEACC38 +EA83E014207B9F19>I<13FEEA0383380E0780121C0038130090C7FC12785AA45AA37E5B +EA70026C5AEA1C18EA07E011147D9314>I<1438EB01F8EB00781438A21470A614E013FC +EA0382EA0601121CEA3C00383801C0127812F0A438E00380A412F0EA700738380F00381C +37803807C7E015207D9F19>I<13F8EA070EEA0E07381C038012381278127012F0B5FC00 +F0C7FCA25AA46C5AEA7002EA3004EA1C18EA07E011147D9314>II<140EEB3E11EBE1A33801C1C2380381E0EA07801301120FA3380703C01480EB87 +00EA04FC48C7FCA21218121CEA0FFF14C014E0381800F04813305A5AA3006013606C13C0 +381C0700EA07FC181F809417>I<13E0120712011200A2485AA6485AEB8F80EB90E013A0 +EBC0601380000713E01300A5380E01C0A6381C0380001E13C038FF8FF014207E9F19>I< +EA01C0EA03E0A213C0EA0180C7FCA6EA0380121F12071203A2EA0700A6120EA65A121EEA +FF800B1F7F9E0C>I<13E0120712011200A2485AA6485AEB81FCEB80F014C0EB81801400 +EA07045B13181338137C131C120E7FA2130F7F1480EA1C03381E07C038FF8FF016207E9F +18>107 D<13E0120712011200A2EA01C0A6EA0380A6EA0700A6120EA65A121EEAFF800B +207F9F0C>I<390387C07C391F9861863907A072073903C03403EB80380007EB7807EB00 +70A5000EEBE00EA64848485A001EEBE01E3AFFCFFCFFC022147E9326>I<38038F80381F +90E0EA07A03803C0601380000713E01300A5380E01C0A6381C0380001E13C038FF8FF014 +147E9319>I<13FCEA0387380E0180381C00C04813E0A24813F012F0A438E001E0A214C0 +130300F0138038700700EA380E6C5AEA07E014147D9317>IIIII< +1380EA0100A35A5A5A121EEAFFF8EA0E00A45AA65A1310A41320A2EA1840EA0F800D1C7C +9B12>I<381C0380EAFC1FEA3C07EA1C03A238380700A6EA700EA4131EA25BEA305E381F +9F8011147B9319>I<38FF83F8381E00E0001C13C01480121E380E01005B13025B12075B +A25BEA039013A013E05B5B120190C7FC15147C9318>I<39FF9FE1FC393C078070391C03 +0060148015401580EA0E0790380D81001309EB19C21311380F21C4EA0720EB40C814E8EB +80F0A26C485A1460000213401E147C9321>I<381FF0FF3803C0780001137014403800E0 +C0EBE180EB73001376133CA2131C132E134E1387EA0107380203801204380C01C0383C03 +E038FE07FC18147F9318>I<390FF83F803901E00E00EBC00C140813E000005B14301420 +5C13705CA20171C7FC1339133A133E133C133813181310A25BA25BEA70C0EAF08000F1C8 +FC12E61278191D809318>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl cmti10 10.95 20 +/Fl 20 122 df12 +D<127012F8A212F012E005057B840E>46 D +97 D<137EEA01C138030080EA0E07121E001C1300003CC7FC5AA35AA45B12701302EA30 +0CEA1830EA07C011147C9315>99 D<1478EB03F8EB0070A414E0A4EB01C0A213F1EA0389 +38070780EA0E03121C123C383807001278A3EAF00EA31420EB1C40A2EA703C135C38308C +80380F070015207C9F17>I<137CEA01C2EA0701120E121C123CEA3802EA780CEA7FF0EA +78005AA4EA7001A21302EA380CEA1830EA07C010147C9315>I103 D<13C0EA01E0A213C0C7FC +A7120E12131223EA4380EA4700A21287120EA35AA3EA38401380A21270EA31001232121C +0B1F7C9E0E>105 D108 D<391C0F80F0392630C318394740640C903880680EEB0070 +A2008E495A120EA34848485AA3ED70803A3803807100A215E115623970070064D8300313 +3821147C9325>I<381C0F80382630C0384740601380EB0070A2008E13E0120EA3381C01 +C0A3EB038400381388A2EB0708EB031000701330383001C016147C931A>I<137CEA01C3 +38030180000E13C0121E001C13E0123C1278A338F003C0A3EB07801400EA700F130EEA30 +18EA1870EA07C013147C9317>I<3801C1E0380262183804741C1378EB701EA2EA08E012 +00A33801C03CA3143838038078147014E0EBC1C038072380EB1E0090C7FCA2120EA45AA2 +B47E171D809317>I114 D<13FCEA0302EA0601EA0C03130713061300EA0F8013F0 +EA07F8EA03FCEA003E130E1270EAF00CA2EAE008EA4010EA2060EA1F8010147D9313>I< +EA018013C0EA0380A4EA0700A2EAFFF0EA0700120EA45AA45AA31320EA7040A21380A2EA +3100121E0C1C7C9B0F>I<000E13C0001313E0382301C0EA4381EA4701A238870380120E +A3381C0700A31410EB0E201218A2381C1E40EA0C263807C38014147C9318>I<380E0380 +EA1307002313C0EA4383EA4701130000871380120EA3381C0100A31302A25BA25BEA0E30 +EA03C012147C9315>I<000EEBC1C0001313E3392301C3E0384381C1384701C015603987 +038040120EA3391C070080A3EC0100A21306EB0F02000C5B380E13083803E1F01B147C93 +1E>I<000E13C0001313E0382301C0EA4381EA4701A238870380120EA3381C0700A4130E +1218A2EA1C1EEA0C3CEA07DCEA001CA25B12F05BEAE060485AEA4380003EC7FC131D7C93 +16>121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm cmr8 8 29 +/Fm 29 118 df<126012F0A212701210A21220A21240A2040A7D960A>39 +D45 D<1206120E12FE120EB1EAFFE00B157D9412>49 +D<13101338A3135CA3138EA3EA0107A238020380A33807FFC0EA0401A2380800E0A20018 +13F0123838FE03FE17177F961A>65 DIIIII76 D<00FEEB03F8001E14C000171305A338138009A23811C011A3 +3810E021A2EB7041A3EB3881A2EB1D01A2130EA2123839FE040FF81D177F9620>I80 D82 DI<387FFFF83860381800401308A200801304A300001300AF3803FF +8016177F9619>I<12FCA212C0B3AB12FCA206217D980A>91 D97 +D<12F81238A8EA39F0EA3E0CEA380613077F1480A414005B1306EA361CEA21F011177F96 +14>II101 D<1203EA0780A2EA0300C7FCA5EA1F801203AF1243EAE300 +12E7127C091D82960B>106 D<12F81238A8133E13381330134013801239EA3FC0EA39E0 +123813F01378133CA2EAFE7F10177F9613>I110 DII114 +DI<1208A31218A21238EAFFC0EA3800A71340A4EA1C80EA0F000A147F93 +0E>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn cmsy9 9 2 +/Fn 2 106 df<13801201EA0300A31206A25AA35AA35AA25AA35AA21260A37EA27EA37E +A37EA27EA3EA0180120009267D9B0F>104 D<12C0A21260A37EA27EA37EA37EA27EA3EA +0180A2EA0300A31206A25AA35AA35AA25AA35AA209267E9B0F>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo cmsltt10 10.95 29 +/Fo 29 122 df<1206120FEA1F80120FA21203EA0700A25A120E123C127C12F01260090E +769B18>39 D<387FFFC0B512E0A26C13C013047C8F18>45 D<133E13FF000313803807C3 +C0EA0F01000E13E0EA1C00123C003813F014705AA34813E0A4EB01C0A2130300F01380EA +7007EB0F00EA781E6C5AEA1FF85BEA07C0141C7C9B18>48 D<13181338A2137813F81203 +120F137012041200A413E0A6EA01C0A6EA7FFE12FF127F0F1C7B9B18>I67 D<3807FFC014E014F03801C0F814 +78143C141CEA0380141EA2140EA33807001CA4143C1438120E147014F0EB01E0EB03C013 +07387FFF8038FFFE00EA7FF8171C7F9B18>I<0007B5FC5A7E3801C007A3140638038000 +A2EB818014C0A213FF481380A21303A2140090C7FC120E140C141CA4387FFFF8B5FC7E18 +1C7F9B18>I74 D76 D<3907E01F80000FEB3FC0000714803903 +B02E00146EA214CE380730DC1331149CA21333141C000E5B13371336133E133C131848C6 +5AA638FE03F800FF7F00FE5B1A1C7F9B18>I<126012F0A37E1278A3127C123CA3123E12 +1EA3121F7EA313801207A313C01203A413E01201A313F0120013600C24789F18>92 +D<387FFFC0B512E0A26C13C013047E7F18>95 D97 D<127EA3120EA45A137CEA1DFF001F13801383381E01C0123CEB00E012 +38A4387801C0A2EB0380A2EB0F00EA7C1FEAFFFCEAEFF8EA63E0131C7C9B18>I100 D<13F8EA07FE487E381F +0780EA3C03387801C0127012E0A2B5FCA2148000E0C7FCA213033870078038780F00EA3F +FE6C5AEA07F012147B9318>III<14C0EB01E013031301EB00C01400A4EBFFC0A31301A2EB0380A6 +EB0700A6130EA65BA2EA6038EAF078B45A5BEA3F8013277F9C18>106 +DII<13FCEA03FF000F1380 +EA1F07383C03C0EA7801007013E0EAE000A4EB01C0A2EB0380EAF007EB0F00EA7C3EEA3F +FC6C5AEA07E013147C9318>111 D113 D<381FE1F8EBE7FCEBEFFE3800FE1EEBFC0C3801F8005B5B5BA3485AA6EA +FFFC7F5B17147E9318>II<387E07E0EAFE0FEA7E07EA0E00A2381C01C0A638380380A41307131F383FFF +E06C13F03807E3E014147D9318>117 D<38FF87F8138F1387383800E0EB01C0A3148013 +E3EA39F31233EB7700A212371376EA3666136EEA3C7CA2EA383815147C9318>119 +D<381FE3FC13E713E33803C3C000011380EBE700EA00EE13FC137C1338137813FCEA01DC +EA038E12071307120E38FF1FE0EB9FF0EB1FE016147E9318>I<380FF1FE381FF9FF380F +F1FE3803807013C0000113E0A213C114C0A23800E380A2EBE700A213E6136E136C137C13 +78A21370A25BA2485A12F3EAF780B4C7FC5A1278181E7F9318>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fp cmcsc10 10.95 12 +/Fp 12 121 df<1318A2133CA3134EA213CF1387A238010380A2000313C0EA0201A23807 +FFE0EA0400A2481370A2001813380038137838FE01FF18177F961C>97 +D99 +D101 DII105 D<38FC01FC381E007014201217EA1380A2EA11C0EA10E0A213701338A2131C13 +0E1307A2EB03A0EB01E0A213001460123800FE132016177E961C>110 +D<13FE38038380380E00E0481370003C1378003813380078133C0070131C00F0131EA700 +70131C0078133C00381338003C1378001C13706C13E0380383803800FE0017177E961D> +II115 +D<38FF81FC381C00701420B0000C1340120E6C138038018300EA007C16177E961C>117 +D<38FF80FE381F0070000E13606C1340EB80803803C100EA01C3EA00E213F4137813387F +133E134E13C7EB8780380103C0EA0201380600E0000413F0000C1370003C137800FE13FF +18177F961C>120 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fq cmbx12 17.28 34 +/Fq 34 121 df49 DI<913A03FF80018002 +3FEBF00349B5EAFC0701079038003F0FD91FF8EB079FD93FC0EB01FFD9FF807F4848C812 +7F4848153F0007161F49150F485A001F1607A2485A1703127FA24992C7FCA212FFA9127F +A27FEF0380123FA26C7E1707000F17006C7E6D150E0003161E6C6C151C6C6C6C1478D93F +C05CD91FF8EB03E0D907FFEB3F800101D9FFFEC7FCD9003F13F80203138031317CB03A> +67 D69 DII73 D76 D78 D80 D +82 D<007FB8FCA39039C00FF801D87E00EC003F007C82007882A200708200F01780A348 +1603A5C792C7FCB3AA017FB6FCA331307DAF38>84 DII97 +DIIIII<90 +391FF007C09039FFFE3FE03A01F83F79F03907E00FC3000F14E19039C007E0E0001FECF0 +00A2003F80A5001F5CA2000F5CEBE00F00075C2603F83FC7FC3806FFFE380E1FF090C9FC +121EA2121F7F90B57E6C14F015FC6C806C801680000F15C0003FC7127F007EEC1FE0007C +140F00FC1407A4007EEC0FC0003E1580003F141FD80FC0EB7E003907F803FC0001B512F0 +D8001F90C7FC242F7E9F28>III108 D<2703F007F8EB1FE000FFD9 +3FFEEBFFF8913A783F01E0FC02C090388300FE280FF1801FC6137F2607F30013CC01F602 +F8148001FC5CA3495CB3B500C3B5380FFFFCA33E207D9F43>I<3903F007F800FFEB3FFE +EC783F02C013803A0FF1801FC03807F30001F614E013FCA35BB3B500C3B5FCA328207D9F +2D>II<3901F83FE000FFEBFF +FC9038FBE07F9039FF003F80D80FFEEB1FC06C48EB0FE04914F0ED07F8A216FC1503A216 +FEA816FC1507A216F8A2ED0FF06D14E06DEB1FC06DEB3F809039FBC0FE009038F8FFF8EC +3FC091C8FCABB512C0A3272E7E9F2D>I<3803F03F00FFEB7FC09038F1C3E01487390FF3 +0FF0EA07F6A29038FC07E0EC03C091C7FCA25BB2B512E0A31C207E9F21>114 +D<3801FF86000713FEEA1F00003C133E48131E140E12F8A36C90C7FCB47E13FC387FFFC0 +6C13F0806C7F00077F00017FEA003F01001380143F0060131F00E0130FA27E15007E6C13 +1E6C131C38FF807838F3FFF038C07F8019207D9F20>I<131CA5133CA3137CA213FC1201 +12031207381FFFFEB5FCA2D803FCC7FCB0EC0380A71201EC0700EA00FEEB7F0EEB3FFCEB +07F0192E7FAD1F>II119 D<3A7FFF807FFCA33A03FC000F006C6C131E6C6C5BEC803890387FC078013F5B +90381FE1E090380FF3C0ECFF806D90C7FC6D5A13016D7E81815B903803DFE09038078FF0 +8190380F07FC90381E03FEEB3C01496C7E4914804848EB7FC00003EC3FE026FFFC01B5FC +A328207F9F2B>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fr cmsy10 10.95 1 +/Fr 1 14 df<14FE903807FFC090381F01F0903878003C01E0130ED80180130348C7EA01 +800006EC00C0481560A2481530481518A248150CA4481506A90060150CA46C1518A26C15 +306C1560A26C15C06CEC01806C6CEB0300D800E0130E0178133C90381F01F0903807FFC0 +D900FEC7FC272B7DA02E>13 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fs cmbx12 14.4 55 +/Fs 55 122 df<123C127FEAFF80A213C0A3127F123E1200A2EA0180A3EA0300A2120612 +0E5A5A12100A157B8813>44 D<121C127FA2EAFF80A3EA7F00A2121C09097B8813>46 +D<130E131E137EEA07FE12FFA212F81200B3ABB512FEA317277BA622>49 +DII<140FA25C5C5C5C5BA2EB03 +BFEB073F130E131C133C1338137013E0EA01C0EA038012071300120E5A5A5A12F0B612F8 +A3C7EA7F00A890381FFFF8A31D277EA622>I<00181303381F801FEBFFFE5C5C5C14C091 +C7FC001CC8FCA7EB7FC0381DFFF8381F80FC381E003F1208C7EA1F8015C0A215E0A21218 +127C12FEA315C05A0078EB3F80A26CEB7F00381F01FE6CB45A000313F0C613801B277DA6 +22>II<1238123E003FB512F0A34814E015C0158015003870000EA25C485B5C5CC6485AA249 +5A130791C7FC5B5B131E133EA2137E137CA213FCA41201A76C5A13701C297CA822>I57 +D65 DI<91387FE003903907FFFC07011FEBFF0F90397FF00F9F +9039FF0001FFD801FC7F4848147F4848143F4848141F485A160F485A1607127FA290C9FC +5AA97E7F1607123FA26C7E160E6C7E6C6C141C6C6C143C6C6C14786CB4EB01F090397FF0 +07C0011FB512800107EBFE009038007FF028297CA831>IIII<91387FE003 +903907FFFC07011FEBFF0F90397FF00F9F9039FF0001FFD801FC7F484880484880484880 +485A82485A82127FA290CAFC5AA892B512F87E7F03001300123FA26C7EA26C7E6C7E6C7E +6C7E6CB45B90387FF007011FB5129F0107EBFE0F9039007FF0032D297CA835>II< +B512F0A33803FC00B3B1B512F0A314297EA819>I75 DIII< +ECFFC0010F13FC90383F807F9039FE001FC0D801F8EB07E048486D7E48486D7E000F8148 +486D7EA24848147FA2007F168090C8123FA34816C0AA6C16806D147FA2003F1600A26C6C +14FEA26C6C495A6C6C495A6C6C495A6C6C495A6C6C495A90263FC0FFC7FC90380FFFFC01 +0013C02A297CA833>IIII<9038FF80600003EBF0E000 +0F13F8381F80FD383F001F003E1307481303A200FC1301A214007EA26C140013C0EA7FFC +EBFFE06C13F86C13FE80000714806C14C0C6FC010F13E0EB007FEC1FF0140F140700E013 +03A46C14E0A26C13076C14C0B4EB0F80EBE03F39E3FFFE0000E15B38C01FF01C297CA825 +>I<007FB71280A39039807F807FD87C00140F00781507A20070150300F016C0A2481501 +A5C791C7FCB3A490B612C0A32A287EA72F>IIII89 +D<3803FF80000F13F0381F01FC383F80FE147F801580EA1F00C7FCA4EB3FFF3801FC3FEA +0FE0EA1F80EA3F00127E5AA4145F007E13DF393F839FFC381FFE0F3803FC031E1B7E9A21 +>97 DIIIII<9038FF80F00003EBE3 +F8390FC1FE1C391F007C7C48137E003EEB3E10007EEB3F00A6003E133E003F137E6C137C +380FC1F8380BFFE00018138090C8FC1238A2123C383FFFF814FF6C14C06C14E06C14F012 +1F383C0007007CEB01F8481300A4007CEB01F0A2003FEB07E0390FC01F806CB512003800 +7FF01E287E9A22>II<1207EA0F80EA1FC0EA3FE0A3EA1F +C0EA0F80EA0700C7FCA7EAFFE0A3120FB3A3EAFFFEA30F2B7EAA12>I108 D<26FFC07FEB1FC0903AC1FFC07FF0903AC307E0C1F8D8 +0FC49038F101FC9039C803F20001D801FE7F01D05BA201E05BB03CFFFE3FFF8FFFE0A333 +1B7D9A38>I<38FFC07E9038C1FF809038C30FC0D80FC413E0EBC80701D813F013D0A213 +E0B039FFFE3FFFA3201B7D9A25>II<38FFE1FE9038EFFF809038FE0FE039 +0FF803F09038F001F801E013FC140015FEA2157FA8157E15FEA215FC140101F013F89038 +F807F09038FC0FE09038EFFF809038E1FC0001E0C7FCA9EAFFFEA320277E9A25>I<38FF +C1F0EBC7FCEBC63E380FCC7F13D813D0A2EBF03EEBE000B0B5FCA3181B7F9A1B>114 +D<3803FE30380FFFF0EA3E03EA7800127000F01370A27E00FE1300EAFFE06CB4FC14C06C +13E06C13F0000713F8C6FCEB07FC130000E0137C143C7E14387E6C137038FF01E038E7FF +C000C11300161B7E9A1B>I<13E0A41201A31203A21207120F381FFFE0B5FCA2380FE000 +AD1470A73807F0E0000313C03801FF8038007F0014267FA51A>I<39FFE07FF0A3000F13 +07B2140FA2000713173903F067FF3801FFC738007F87201B7D9A25>I<39FFFC03FFA339 +0FF000F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0EA214 +9EEB3F9C14FC6D5AA26D5AA36D5AA26D5AA2201B7F9A23>I<3BFFFC7FFC1FFCA33B0FE0 +0FE001C02607F007EB0380A201F8EBF00700031600EC0FF801FC5C0001150EEC1FFC2600 +FE1C5B15FE9039FF387E3C017F1438EC787F6D486C5A16F0ECE01F011F5CA26D486C5AA2 +EC800701075CA22E1B7F9A31>I<39FFFC1FFEA33907F003803803F8079038FC0F003801 +FE1E00005BEB7F3814F86D5A6D5A130F806D7E130F497EEB3CFEEB38FFEB787F9038F03F +803901E01FC0D803C013E0EB800F39FFF03FFFA3201B7F9A23>I<39FFFC03FFA3390FF0 +00F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0EA2149EEB +3F9C14FC6D5AA26D5AA36D5AA26D5AA25CA21307003890C7FCEA7C0FEAFE0E131E131C5B +EA74F0EA3FE0EA0F8020277F9A23>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ft cmtt10 10.95 91 +/Ft 91 127 df<127012F8B012701200A5127012F8A31270051C779B18>33 +DI +I<13C01201A3EA03F0EA0FFCEA3FFEEA7DCFEA71C738E1C38013C7A338F1C0001279123F +6C7EEA0FF8EA01FC13DE13CF13C73861C38012F1A212E1EBC7001271EA79DEEA3FFEEA1F +F8EA07E0EA01C0A3120011247D9F18>III<1238127CA2127E +123E120EA3121CA2123812F812F012C0070E789B18>I<137013F0EA01E0EA03C0EA0780 +EA0F00121E121C5AA25AA45AA81270A47EA27E121E7EEA0780EA03C0EA01F0120013700C +24799F18>I<126012F012787E7E7EEA07801203EA01C0A2EA00E0A41370A813E0A4EA01 +C0A2EA03801207EA0F00121E5A5A5A12600C247C9F18>II<136013F0A7387FFFC0B512E0A26C13C03800F000A7136013147E9718>I<121C +123E127E127F123F121F1207120E121E127C12F81260080C788518>I<387FFFC0B512E0 +A26C13C013047E8F18>I<1230127812FCA2127812300606778518>I<1303EB0780A2130F +14005B131EA2133E133C137C1378A213F85B12015B12035BA212075B120F90C7FCA25A12 +1E123E123CA2127C127812F85AA2126011247D9F18>IIII<131F5B1377A213E7120113C7EA038712 +071307120E121E123C1238127812F0B512F8A338000700A6EB7FF0A3151C7F9B18>52 +D<383FFF80A30038C7FCA8EA3BF8EA3FFE7F383C0780383003C0EA0001EB00E0A2126012 +F0A238E001C0EA7003387C0F80383FFF00EA1FFCEA03F0131C7E9B18>I<137E48B4FC00 +071380380F83C0EA1E03121C3838018090C7FC5AA2EAE1F8EAE7FEB5FC38FE078038F803 +C0EAF001EB00E05AA21270A3383801C0EA3C03381E0780380FFF006C5AEA01F8131C7E9B +18>I<12E0B512E0A214C038E00380EB0700C65A131E131C5BA25B13F05BA2485AA3485A +A448C7FCA7131D7E9C18>II<1230127812FCA2127812301200A8 +1230127812FCA2127812300614779318>58 D<1218123C127EA2123C12181200A8121812 +3C127EA2123E121E120E121C123C127812F01260071A789318>I<14C0EB03E01307EB1F +C0EB3F80EBFE00485AEA07F0485AEA3F8048C7FC12FCA2127F6C7EEA0FE06C7EEA01FC6C +7EEB3F80EB1FC0EB07E01303EB00C013187E9918>I<387FFFC0B512E0A26C13C0C8FCA4 +387FFFC0B512E0A26C13C0130C7E9318>I<126012F87E127F6C7EEA0FE06C7EEA01FC6C +7EEB3F80EB1FC0EB07E0A2EB1FC0EB3F80EBFE00485AEA07F0485AEA3F8048C7FC12FC5A +126013187E9918>II<137CEA01FEEA07FF380F +8780381E03C0EA3C1DEA387F3870FFE0EA71E313C112E1EAE380A638E1C1C0127113E338 +70FF8038387F00EA3C1C381E00E0EA0F833807FFC00001138038007E00131C7E9B18>I< +137013F8A213D8A2EA01DCA3138CEA038EA4EA0707A5380FFF80A3EA0E03381C01C0A338 +7F07F000FF13F8007F13F0151C7F9B18>II +IIII<3801F1C0EA03FD +EA0FFFEA1F0FEA1C03123813011270A290C7FC5AA5EB0FF0131F130F387001C0A2130312 +38A2EA1C07EA1F0FEA0FFFEA03FDEA01F1141C7E9B18>I<387F07F038FF8FF8387F07F0 +381C01C0A9EA1FFFA3EA1C01AA387F07F038FF8FF8387F07F0151C7F9B18>II<3801FFC0A338000E00B3 +12F0A2133CEA7FFCEA3FF0EA0FC0121C7D9B18>I<387F07F038FF87F8387F07F0381C03 +C0EB07801400130E131E5B13385B13F0121DA2EA1FB8A2131C121EEA1C0EA27FA2EB0380 +A2EB01C0387F03F038FF87F8387F03F0151C7F9B18>II<38FC01F8EAFE03A2383B06E0A4138EA2EA398CA213DCA3EA38D8A2 +13F81370A21300A638FE03F8A3151C7F9B18>I<387E07F038FF0FF8387F07F0381D81C0 +A313C1121CA213E1A313611371A213311339A31319A2131D130DA3EA7F07EAFF87EA7F03 +151C7F9B18>IIIII<3803F1C0EA1FFF5AEA7C0FEA7003EAE001A3 +90C7FC12701278123FEA1FF0EA07FEC67EEB0F80EB03C01301EB00E0A2126012E0130100 +F013C038F80780B5FCEBFE00EAE7F8131C7E9B18>I<387FFFF8B5FCA238E07038A40000 +1300B2EA07FFA3151C7F9B18>I<38FF83FEA3381C0070B36C13E0EA0F01380783C03803 +FF806C1300EA007C171C809B18>I<38FE03F8EAFF07EAFE03383C01E0001C13C0A3EA1E +03000E1380A438070700A4EA038EA4EA018C13DCA3EA00D813F8A21370151C7F9B18>I< +38FE03F8A338700070A36C13E0A513F8EA39FC13DCA2001913C0A3138CA2EA1D8DA31305 +000D1380EA0F07A2EA0E03151C7F9B18>I<387F0FE0139F130F380E0700120FEA070E13 +8EEA039C13DCEA01F8A212005B137013F07F487E13DCEA039E138EEA070F7F000E138013 +03001E13C0387F07F000FF13F8007F13F0151C7F9B18>I<38FE03F8EAFF07EAFE03381C +01C0EA1E03000E1380EA0F0700071300A2EA038EA2EA01DCA3EA00F8A21370A9EA01FC48 +7E6C5A151C7F9B18>I<383FFFE05AA2387001C01303EB07801400C65A131E131C133C5B +137013F0485A5B1203485A90C7FC5A001E13E0121C123C5A1270B5FCA3131C7E9B18>I< +EAFFF8A3EAE000B3ACEAFFF8A30D24779F18>I<126012F0A27E1278127C123CA2123E12 +1E121F7EA27F12077F1203A27F12017F12007F1378A2137C133C133E131EA2131F7F1480 +1307A2EB030011247D9F18>II<387FFFC0 +B512E0A26C13C013047E7F18>95 D<1206121E123E12381270A212E0A312F812FC127CA2 +1238070E789E18>II<127E12FE127E12 +0EA5133EEBFF80000F13C0EBC1E01380EB0070120E1438A6000F1370A2EB80E013C1EBFF +C0000E138038063E00151C809B18>IIIII<3801E1F03807FFF85A381E1E30381C0E00487EA5EA1C +0EEA1E1EEA1FFC5BEA39E00038C7FC7EEA1FFEEBFFC04813E0387801F038700070481338 +A4007813F0EA7E03381FFFC06C13803801FC00151F7F9318>I<127E12FE127E120EA513 +3EEBFF80000F13C013C1EB80E01300120EAB387FC7FC38FFE7FE387FC7FC171C809B18> +II<1338 +137CA313381300A4EA0FFCA3EA001CB3A4EA6038EAF078EAFFF0EA7FE0EA3F800E277E9C +18>I<127E12FE127E120EA5EB3FF0A3EB0780EB0F00131E5B5B5BEA0FF87F139C130EEA +0E0F7FEB038014C0387FC7F812FF127F151C7F9B18>II<38F9C1C038FFF7F013FF383E3E38EA3C3CA2EA3838AB38FE3E3EEB7E7EEB +3E3E1714809318>III< +EA7E3E38FEFF80007F13C0380FC1E01380EB0070120E1438A6000F1370A2EB80E013C1EB +FFC0000E1380EB3E0090C7FCA7EA7FC0487E6C5A151E809318>I<3801F380EA07FBEA1F +FFEA3E1FEA380FEA7007A2EAE003A6EA7007A2EA380FEA3C1FEA1FFFEA0FFBEA03E3EA00 +03A7EB1FF0EB3FF8EB1FF0151E7E9318>I<38FF0FC0EB3FE0EB7FF0EA07F0EBE060EBC0 +005BA290C7FCA9EAFFFC7F5B14147E9318>II<487E1203A4387FFFC0B5FCA238038000A9144014E0A33801C1C013FF6C1380 +EB3E0013197F9818>I<387E07E0EAFE0FEA7E07EA0E00AC1301EA0F033807FFFC6C13FE +3801FCFC1714809318>I<387F8FF000FF13F8007F13F0381C01C0380E0380A338070700 +A3138FEA038EA3EA01DCA3EA00F8A2137015147F9318>I<38FF07F8138F1307383800E0 +A4381C01C0137113F9A213D9EA1DDD000D1380A3138DEA0F8FA23807070015147F9318> +I<387F8FF0139F138F380F0700EA078EEA039EEA01DC13F81200137013F07FEA01DCEA03 +9E138EEA0707000E1380387F8FF000FF13F8007F13F015147F9318>I<387F8FF000FF13 +F8007F13F0380E01C0EB0380A21207EB0700A2EA0387A2138EEA01CEA213CC120013DC13 +78A31370A313F05B1279EA7BC0EA7F806CC7FC121E151E7F9318>I<383FFFF05AA23870 +01E0EB03C0EB078038000F00131E5B13F8485AEA03C0485A380F0070121E5A5AB512F0A3 +14147F9318>II<126012F0B3B012600424769F18>I<127CB4FC13C0 +1203C67EAB7FEB7FC0EB3FE0A2EB7FC0EBF0005BABEA03C012FF90C7FC127C13247E9F18 +>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fu cmr10 10.95 77 +/Fu 77 123 df<90381F83E09038F06E303901C07878380380F8903800F03048EB7000A7 +B612803907007000B2383FE3FF1D20809F1B>11 D<133FEBE0C0EA01C0380381E0EA0701 +A290C7FCA6B512E0EA0700B2383FC3FC1620809F19>II<90381F81F89038F04F043901C07C063903 +80F80FEB00F05A0270C7FCA6B7FC3907007007B23A3FE3FE3FE02320809F26>I34 +D<1340A2EA03F0EA0C4EEA10413820408012600040134038C041C01343A238E04180EB40 +001270127CEA3FC0EA1FF86C7EEA03FEEA007FEB4F801343EB41C0A2EAF040A312801480 +EA404100201300EA3042EA0C4CEA03F0EA0040A312257EA117>36 +D<127012F812FCA212741204A31208A21210A212201240060E7C9F0D>39 +D<13401380EA01005A12061204120C5AA212381230A212701260A412E0AC1260A4127012 +30A212381218A27E120412067E7EEA008013400A2E7BA112>I<7E12407E12307E120812 +0C7EA212077EA213801201A413C0AC1380A412031300A25A1206A25A120812185A12205A +5A0A2E7EA112>I<127012F012F8A212781208A31210A31220A21240050E7C840D>44 +DI<127012F8A3127005057C840D>I<144014C0EB0180A3EB0300 +A31306A25BA35BA35BA25BA35BA3485AA348C7FCA21206A35AA35AA25AA35AA35AA2122D +7EA117>II<13801203120F12F31203B3A6EA +07C0EA7FFE0F1E7C9D17>III<1306A2130EA2131E132EA2134E138EA2EA +010E1202A212041208A212101220A2124012C0B512F038000E00A7EBFFE0141E7F9D17> +II<137CEA +0182EA0701380E0380EA0C0712183838030090C7FC12781270A2EAF1F0EAF21CEAF406EA +F807EB0380A200F013C0A51270A214801238EB07001218EA0C0E6C5AEA01F0121F7E9D17 +>I<1240387FFFE014C0A23840008038800100A21302485AA25B5BA25BA21360A213E05B +1201A41203A76C5A131F7E9D17>III<127012F8A312 +701200AA127012F8A3127005147C930D>I<127012F8A312701200AA127012F012F8A212 +781208A31210A31220A21240051D7C930D>I<5B497EA3497EA3EB09E0A3EB10F0A3EB20 +78A3497EA2EBC03EEB801EA248B5FCEB000FA20002EB0780A348EB03C0A2120C001E14E0 +39FF801FFE1F207F9F22>65 DI<90380FE0109038381C309038E002703803C00139078000F048C71270121E15305A15 +10127C127800F81400A91278007C1410123CA26C1420A27E6C6C13406C6C13803900E003 +00EB380CEB0FF01C217E9F21>IIII<90380FE02090387818609038E004E03803800238070001481300001E1460 +A25A1520127C127800F81400A7EC7FFCEC03E000781301127C123CA27EA27E7E38038002 +3900E00460903878182090380FE0001E217D9F24>I<39FFF07FF8390F000780AD90B5FC +EB0007AF39FFF07FF81D1F7E9E22>II<39FFF0 +07FC390F0003E0EC0180150014025C5C5C5C5C5C49C7FC5B497E130FEB13C0EB21E01341 +EB80F0EB0078A28080A280EC0780A2EC03C015E015F039FFF01FFE1F1F7E9E23>75 +DI +IIII82 +D<3803F040380C0CC0EA1803EA3001EA6000A212E01440A36C13007E127CEA7F80EA3FF8 +6CB4FC00071380C613C0EB1FE013031301EB00F014707EA46C136014E06C13C038F80180 +38C60300EA81FC14217E9F19>I<007FB512E038780F010060EB006000401420A200C014 +3000801410A400001400B3497E3803FFFC1C1F7E9E21>I<39FFF00FF8390F0003E0EC00 +80B3A46CEB01001380120314026C6C5A6C6C5AEB3830EB0FC01D207E9E22>I<39FFF003 +FE391F8000F86CC7126015206C6C1340A36C6C1380A2EBE00100011400A23800F002A213 +F8EB7804A26D5AA36D5AA2131F6D5AA2EB07C0A36D5AA36DC7FC1F207F9E22>I<3BFFF0 +7FF81FF03B1F000FC007C06C903907800180170015C001805C00071502EC09E013C00003 +5DEC19F01410D801E05CA2EC2078D800F05CA2EC403C01785CA2EC801E017C1460013C14 +4090383D000F133F6D5CA2011E1307010E91C7FCA2010C7F010413022C207F9E2F>I<39 +FFF001FF391F800078000F146012076D1340000314807F3901F001001200EBF802EB7C06 +EB3C04EB3E08131EEB1F10EB0FB0EB07A014E06D5AACEB3FFC201F7F9E22>89 +D<12FFA212C0B3B3A512FFA2082D7CA10D>91 DI<12FFA21203B3B3A512FFA2082D80 +A10D>I<120812101220A21240A21280A312B812FCA2127C1238060E7D9F0D>96 +DI<121C12FC121CAA137CEA1D87381E0180EB00 +C0001C13E01470A21478A6147014F014E0001E13C0381A018038198700EA107C15207E9F +19>IIII<137CEA01C6EA030F1207EA0E061300A7EAFFF0EA0E00B2EA7FE010 +20809F0E>I<14E03803E330EA0E3CEA1C1C38380E00EA780FA5EA380E6C5AEA1E38EA33 +E00020C7FCA21230A2EA3FFE381FFF8014C0383001E038600070481330A4006013606C13 +C0381C03803803FC00141F7F9417>I<121C12FC121CAA137C1386EA1D03001E1380A212 +1CAE38FF8FF014207E9F19>I<1238127CA31238C7FCA6121C12FC121CB1EAFF80091F7F +9E0C>I<13E0EA01F0A3EA00E01300A61370EA07F012001370B3A31260EAF06013C0EA61 +80EA3F000C28829E0E>I<121C12FC121CAAEB1FE0EB0780EB060013045B5B5B136013E0 +EA1DF0EA1E70EA1C38133C131C7F130F7F148014C038FF9FF014207E9F18>I<121C12FC +121CB3ABEAFF8009207F9F0C>I<391C3E03E039FCC30C30391D019018001EEBE01CA200 +1C13C0AE3AFF8FF8FF8021147E9326>IIII<3801F04038070CC0EA0E02EA1C03EA38011278127012F0A61270 +12781238EA1C03EA0C05EA0709EA01F1EA0001A8EB0FF8151D7F9318>III<1202A31206A2120EA2123EEAFFF8EA0E00AB1304A5EA07081203EA01F00E1C7F +9B12>I<381C0380EAFC1FEA1C03AE1307120CEA061B3803E3F014147E9319>I<38FF83F8 +383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8A21370A3 +132015147F9318>I<39FF9FE1FC393C078070391C030060EC8020000E1440A214C0D807 +04138014E0A239038861001471A23801D032143A143E3800E01CA2EB6018EB40081E147F +9321>I<38FF87F8381E03C0380E0180EB0300EA0702EA0384EA01C813D8EA00F0137013 +7813F8139CEA010E1202EA060738040380000C13C0003C13E038FE07FC16147F9318>I< +38FF83F8383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8 +A21370A31320A25BA3EAF080A200F1C7FC1262123C151D7F9318>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fv cmbx12 20.736 14 +/Fv 14 122 df71 D76 D78 D82 +D85 D97 D<13FE12FFA412071203B04AB4 +FC021F13F0027F13FC9138FC03FE9039FFF000FF02C0EB3F8091C7EA1FC04915E0EE0FF0 +17F8A2EE07FCA317FEA917FCA3160F17F817F0161F6D15E06EEB3FC06EEB7F80D9F9E0EB +FF009039F0FC07FE91387FFFF8D9E01F13E09026C003FEC7FC2F3C7DBB36>I100 +D<49B47E010F13F0017F13FC9038FF81FE3A03FE007F80D807F8133F4848EB1FC0ED0FE0 +485A003F15F01507485A16F8A212FFA290B6FCA301C0C8FCA4127FA36C7E1678121F7F00 +0F15F06C6C13016C6CEB03E06C6CEB0FC03A00FFC07F8090393FFFFE00010F13F8010013 +C025267DA52C>I105 D<13FE12FFA412071203B3B3AEB512F8A415 +3C7DBB1A>108 D110 +D<3901FC03F000FFEB0FFC4AB4FC91383C3F80EC707F00079038E0FFC000035BEBFD80A2 +01FFEB7F809138003F00151E92C7FC5BB3A3B512FCA422267DA528>114 +D121 D E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 75 659 a Fv(GNU)33 b(Readline)h(Library)p 75 +709 1800 17 v 936 757 a Fu(Edition)17 b(4.3,)c(for)i +Ft(Readline)f(Library)g Fu(V)l(ersion)i(4.3.)1643 811 +y(Marc)o(h)e(2002)75 2467 y Fs(Brian)23 b(F)-6 b(o)n(x,)23 +b(F)-6 b(ree)23 b(Soft)n(w)n(are)f(F)-6 b(oundation)75 +2534 y(Chet)22 b(Ramey)-6 b(,)23 b(Case)e(W)-6 b(estern)23 +b(Reserv)n(e)f(Univ)n(ersit)n(y)p 75 2570 1800 9 v eop +%%Page: 2 2 +2 1 bop 75 217 a Fu(This)14 b(do)q(cumen)o(t)h(describ)q(es)g(the)f +(GNU)g(Readline)h(Library)l(,)f(a)g(utilit)o(y)h(whic)o(h)f(aids)g(in)h +(the)f(consistency)75 271 y(of)h(user)g(in)o(terface)h(across)e +(discrete)i(programs)e(that)h(need)h(to)e(pro)o(vide)i(a)f(command)g +(line)i(in)o(terface.)75 339 y(Published)g(b)o(y)f(the)f(F)l(ree)g +(Soft)o(w)o(are)f(F)l(oundation)75 394 y(59)h(T)l(emple)h(Place,)f +(Suite)i(330,)75 448 y(Boston,)d(MA)h(02111)f(USA)75 +516 y(P)o(ermission)j(is)f(gran)o(ted)g(to)f(mak)o(e)h(and)g +(distribute)i(v)o(erbatim)d(copies)i(of)f(this)h(man)o(ual)f(pro)o +(vided)h(the)75 570 y(cop)o(yrigh)o(t)e(notice)h(and)f(this)h(p)q +(ermission)g(notice)g(are)f(preserv)o(ed)h(on)f(all)h(copies.)75 +638 y(P)o(ermission)c(is)h(gran)o(ted)e(to)g(cop)o(y)h(and)g +(distribute)h(mo)q(di\014ed)g(v)o(ersions)f(of)f(this)h(man)o(ual)g +(under)h(the)f(con-)75 692 y(ditions)k(for)e(v)o(erbatim)h(cop)o(ying,) +g(pro)o(vided)h(that)e(the)h(en)o(tire)h(resulting)g(deriv)o(ed)g(w)o +(ork)e(is)h(distributed)75 747 y(under)h(the)f(terms)g(of)g(a)f(p)q +(ermission)j(notice)f(iden)o(tical)h(to)e(this)g(one.)75 +814 y(P)o(ermission)i(is)g(gran)o(ted)f(to)g(cop)o(y)h(and)f +(distribute)i(translations)f(of)f(this)h(man)o(ual)g(in)o(to)f(another) +g(lan-)75 869 y(guage,)e(under)h(the)f(ab)q(o)o(v)o(e)g(conditions)i +(for)d(mo)q(di\014ed)j(v)o(ersions,)e(except)h(that)f(this)h(p)q +(ermission)g(notice)75 924 y(ma)o(y)f(b)q(e)i(stated)f(in)h(a)f +(translation)g(appro)o(v)o(ed)g(b)o(y)g(the)g(F)l(ree)h(Soft)o(w)o(are) +d(F)l(oundation.)75 2661 y(Cop)o(yrigh)o(t)301 2660 y(c)289 +2661 y Fr(\015)h Fu(1988-2002)f(F)l(ree)i(Soft)o(w)o(are)f(F)l +(oundation,)h(Inc.)p eop +%%Page: 1 3 +1 2 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(1)75 149 y Fq(1)41 b(Command)28 b(Line)e(Editing)137 +271 y Fu(This)16 b(c)o(hapter)f(describ)q(es)i(the)e(basic)h(features)f +(of)g(the)g Fp(gnu)g Fu(command)g(line)i(editing)f(in)o(terface.)75 +403 y Fs(1.1)33 b(In)n(tro)r(duction)24 b(to)e(Line)i(Editing)137 +501 y Fu(The)16 b(follo)o(wing)g(paragraphs)e(describ)q(e)j(the)e +(notation)g(used)h(to)e(represen)o(t)i(k)o(eystrok)o(es.)137 +569 y(The)h(text)f Fo(C-k)h Fu(is)g(read)g(as)f(`Con)o(trol-K')g(and)h +(describ)q(es)h(the)f(c)o(haracter)f(pro)q(duced)h(when)h(the)1831 +567 y Fn(h)p 1844 541 19 2 v 1844 569 a Fm(k)p 1844 577 +V 1860 567 a Fn(i)75 624 y Fu(k)o(ey)d(is)h(pressed)g(while)g(the)f +(Con)o(trol)g(k)o(ey)g(is)h(depressed.)137 693 y(The)g(text)g +Fo(M-k)f Fu(is)i(read)f(as)f(`Meta-K')g(and)h(describ)q(es)i(the)e(c)o +(haracter)f(pro)q(duced)i(when)g(the)f(Meta)75 747 y(k)o(ey)e(\(if)g(y) +o(ou)g(ha)o(v)o(e)g(one\))g(is)h(depressed,)g(and)f(the)930 +745 y Fn(h)p 942 719 V 942 747 a Fm(k)p 942 755 V 958 +745 a Fn(i)987 747 y Fu(k)o(ey)g(is)h(pressed.)20 b(The)15 +b(Meta)e(k)o(ey)h(is)h(lab)q(eled)1779 745 y Fn(h)p 1791 +719 72 2 v 1791 747 a Fm(AL)m(T)p 1791 755 V 1860 745 +a Fn(i)75 802 y Fu(on)e(man)o(y)g(k)o(eyb)q(oards.)19 +b(On)13 b(k)o(eyb)q(oards)g(with)h(t)o(w)o(o)e(k)o(eys)g(lab)q(eled) +1213 800 y Fn(h)p 1225 774 V 1225 802 a Fm(AL)m(T)p 1225 +810 V 1294 800 a Fn(i)1322 802 y Fu(\(usually)i(to)e(either)i(side)g +(of)f(the)75 857 y(space)j(bar\),)f(the)388 855 y Fn(h)p +400 829 V 400 857 a Fm(AL)m(T)p 400 865 V 469 855 a Fn(i)499 +857 y Fu(on)h(the)g(left)g(side)g(is)g(generally)h(set)f(to)f(w)o(ork)g +(as)g(a)g(Meta)g(k)o(ey)l(.)22 b(The)1697 855 y Fn(h)p +1709 829 V 1709 857 a Fm(AL)m(T)p 1709 865 V 1778 855 +a Fn(i)1808 857 y Fu(k)o(ey)75 912 y(on)17 b(the)f(righ)o(t)h(ma)o(y)f +(also)h(b)q(e)g(con\014gured)g(to)f(w)o(ork)g(as)g(a)h(Meta)f(k)o(ey)g +(or)g(ma)o(y)g(b)q(e)i(con\014gured)f(as)f(some)75 967 +y(other)f(mo)q(di\014er,)h(suc)o(h)f(as)g(a)g(Comp)q(ose)g(k)o(ey)g +(for)f(t)o(yping)i(accen)o(ted)f(c)o(haracters.)137 1035 +y(If)c(y)o(ou)g(do)g(not)f(ha)o(v)o(e)h(a)f(Meta)h(or)694 +1033 y Fn(h)p 706 1007 V 706 1035 a Fm(AL)m(T)p 706 1043 +V 775 1033 a Fn(i)801 1035 y Fu(k)o(ey)l(,)g(or)g(another)f(k)o(ey)h(w) +o(orking)f(as)h(a)f(Meta)h(k)o(ey)l(,)g(the)g(iden)o(tical)75 +1090 y(k)o(eystrok)o(e)f(can)i(b)q(e)g(generated)f(b)o(y)g(t)o(yping) +809 1088 y Fn(h)p 822 1062 70 2 v 822 1090 a Fm(ESC)p +822 1098 V 888 1088 a Fn(i)915 1090 y Fl(\014rst)p Fu(,)g(and)g(then)h +(t)o(yping)1339 1088 y Fn(h)p 1351 1062 19 2 v 1351 1090 +a Fm(k)p 1351 1098 V 1368 1088 a Fn(i)1383 1090 y Fu(.)18 +b(Either)12 b(pro)q(cess)f(is)h(kno)o(wn)75 1145 y(as)j +Fk(metafying)k Fu(the)425 1143 y Fn(h)p 437 1117 V 437 +1145 a Fm(k)p 437 1153 V 454 1143 a Fn(i)484 1145 y Fu(k)o(ey)l(.)137 +1214 y(The)i(text)e Fo(M-C-k)h Fu(is)h(read)f(as)f(`Meta-Con)o(trol-k') +g(and)h(describ)q(es)i(the)e(c)o(haracter)g(pro)q(duced)h(b)o(y)75 +1268 y Fk(metafying)e Fo(C-k)p Fu(.)137 1337 y(In)g(addition,)h(sev)o +(eral)f(k)o(eys)f(ha)o(v)o(e)g(their)h(o)o(wn)f(names.)30 +b(Sp)q(eci\014cally)l(,)1384 1335 y Fn(h)p 1396 1309 +73 2 v 1396 1337 a Fm(DEL)p 1396 1345 V 1467 1335 a Fn(i)1482 +1337 y Fu(,)1514 1335 y Fn(h)p 1526 1309 70 2 v 1526 +1337 a Fm(ESC)p 1526 1345 V 1593 1335 a Fn(i)1608 1337 +y Fu(,)1640 1335 y Fn(h)p 1652 1309 72 2 v 1652 1337 +a Fm(LFD)p 1652 1345 V 1722 1335 a Fn(i)1737 1337 y Fu(,)1768 +1335 y Fn(h)p 1780 1309 70 2 v 1780 1337 a Fm(SPC)p 1780 +1345 V 1847 1335 a Fn(i)1862 1337 y Fu(,)75 1390 y Fn(h)p +87 1364 76 2 v 87 1392 a Fm(RET)p 87 1399 V 160 1390 +a Fn(i)175 1392 y Fu(,)23 b(and)306 1390 y Fn(h)p 318 +1364 74 2 v 318 1392 a Fm(T)m(AB)p 318 1399 V 390 1390 +a Fn(i)427 1392 y Fu(all)f(stand)g(for)f(themselv)o(es)h(when)h(seen)f +(in)g(this)g(text,)h(or)e(in)i(an)e(init)i(\014le)g(\(see)75 +1447 y(Section)d(1.3)f([Readline)h(Init)g(File],)h(page)e(4\).)32 +b(If)19 b(y)o(our)g(k)o(eyb)q(oard)h(lac)o(ks)f(a)1444 +1445 y Fn(h)p 1456 1419 72 2 v 1456 1447 a Fm(LFD)p 1456 +1454 V 1526 1445 a Fn(i)1560 1447 y Fu(k)o(ey)l(,)h(t)o(yping)1802 +1445 y Fn(h)p 1814 1419 49 2 v 1814 1447 a Fm(C-j)p 1814 +1454 V 1860 1445 a Fn(i)75 1501 y Fu(will)c(pro)q(duce)g(the)f(desired) +h(c)o(haracter.)j(The)874 1499 y Fn(h)p 886 1473 76 2 +v 886 1501 a Fm(RET)p 886 1509 V 959 1499 a Fn(i)989 +1501 y Fu(k)o(ey)c(ma)o(y)f(b)q(e)h(lab)q(eled)1385 1499 +y Fn(h)p 1397 1473 109 2 v 1397 1501 a Fm(Return)p 1397 +1509 V 1503 1499 a Fn(i)1533 1501 y Fu(or)1588 1499 y +Fn(h)p 1600 1473 86 2 v 1600 1501 a Fm(En)o(ter)p 1600 +1509 V 1684 1499 a Fn(i)1714 1501 y Fu(on)f(some)75 1556 +y(k)o(eyb)q(oards.)75 1688 y Fs(1.2)33 b(Readline)23 +b(In)n(teraction)137 1786 y Fu(Often)13 b(during)h(an)e(in)o(teractiv)o +(e)h(session)g(y)o(ou)g(t)o(yp)q(e)f(in)i(a)e(long)h(line)h(of)e(text,) +h(only)g(to)f(notice)h(that)f(the)75 1841 y(\014rst)k(w)o(ord)f(on)h +(the)h(line)h(is)e(missp)q(elled.)26 b(The)16 b(Readline)i(library)f +(giv)o(es)f(y)o(ou)g(a)g(set)g(of)g(commands)g(for)75 +1896 y(manipulating)g(the)f(text)g(as)f(y)o(ou)h(t)o(yp)q(e)g(it)g(in,) +g(allo)o(wing)h(y)o(ou)f(to)f(just)h(\014x)g(y)o(our)f(t)o(yp)q(o,)g +(and)h(not)g(forcing)75 1950 y(y)o(ou)f(to)f(ret)o(yp)q(e)h(the)g(ma)s +(jorit)o(y)f(of)h(the)g(line.)21 b(Using)15 b(these)f(editing)h +(commands,)f(y)o(ou)g(mo)o(v)o(e)f(the)h(cursor)75 2005 +y(to)i(the)i(place)g(that)e(needs)i(correction,)g(and)f(delete)h(or)f +(insert)g(the)h(text)e(of)h(the)g(corrections.)26 b(Then,)75 +2060 y(when)16 b(y)o(ou)f(are)h(satis\014ed)g(with)g(the)f(line,)i(y)o +(ou)e(simply)i(press)1160 2058 y Fn(h)p 1172 2032 76 +2 v 1172 2060 a Fm(RET)p 1172 2068 V 1245 2058 a Fn(i)1260 +2060 y Fu(.)k(Y)l(ou)16 b(do)f(not)h(ha)o(v)o(e)f(to)g(b)q(e)h(at)f +(the)75 2115 y(end)k(of)e(the)h(line)i(to)d(press)563 +2113 y Fn(h)p 575 2087 V 575 2115 a Fm(RET)p 575 2122 +V 648 2113 a Fn(i)663 2115 y Fu(;)i(the)f(en)o(tire)h(line)g(is)g +(accepted)f(regardless)g(of)g(the)g(lo)q(cation)g(of)g(the)75 +2170 y(cursor)d(within)h(the)g(line.)75 2284 y Fj(1.2.1)30 +b(Readline)20 b(Bare)g(Essen)n(tials)137 2382 y Fu(In)12 +b(order)g(to)f(en)o(ter)g(c)o(haracters)g(in)o(to)g(the)h(line,)h +(simply)g(t)o(yp)q(e)f(them.)18 b(The)12 b(t)o(yp)q(ed)g(c)o(haracter)f +(app)q(ears)75 2437 y(where)16 b(the)h(cursor)f(w)o(as,)f(and)h(then)h +(the)f(cursor)g(mo)o(v)o(es)g(one)g(space)g(to)g(the)g(righ)o(t.)23 +b(If)17 b(y)o(ou)f(mist)o(yp)q(e)g(a)75 2492 y(c)o(haracter,)e(y)o(ou)h +(can)g(use)h(y)o(our)f(erase)g(c)o(haracter)f(to)h(bac)o(k)g(up)g(and)h +(delete)g(the)f(mist)o(yp)q(ed)h(c)o(haracter.)137 2560 +y(Sometimes)g(y)o(ou)f(ma)o(y)g(mist)o(yp)q(e)h(a)f(c)o(haracter,)f +(and)i(not)f(notice)h(the)f(error)g(un)o(til)i(y)o(ou)e(ha)o(v)o(e)g(t) +o(yp)q(ed)75 2615 y(sev)o(eral)g(other)f(c)o(haracters.)19 +b(In)c(that)e(case,)i(y)o(ou)f(can)g(t)o(yp)q(e)h Fo(C-b)f +Fu(to)g(mo)o(v)o(e)f(the)i(cursor)f(to)g(the)g(left,)h(and)75 +2670 y(then)h(correct)e(y)o(our)h(mistak)o(e.)20 b(Afterw)o(ards,)13 +b(y)o(ou)i(can)g(mo)o(v)o(e)g(the)g(cursor)g(to)g(the)g(righ)o(t)g +(with)g Fo(C-f)p Fu(.)p eop +%%Page: 2 4 +2 3 bop 75 -58 a Fu(2)1322 b(GNU)15 b(Readline)h(Library)137 +149 y(When)h(y)o(ou)f(add)g(text)g(in)h(the)g(middle)h(of)e(a)f(line,)j +(y)o(ou)e(will)i(notice)f(that)f(c)o(haracters)f(to)h(the)g(righ)o(t)75 +204 y(of)e(the)g(cursor)g(are)g(`pushed)h(o)o(v)o(er')f(to)f(mak)o(e)h +(ro)q(om)g(for)f(the)i(text)f(that)f(y)o(ou)h(ha)o(v)o(e)g(inserted.)21 +b(Lik)o(ewise,)75 259 y(when)e(y)o(ou)g(delete)h(text)e(b)q(ehind)j +(the)e(cursor,)g(c)o(haracters)f(to)g(the)h(righ)o(t)f(of)g(the)h +(cursor)g(are)f(`pulled)75 314 y(bac)o(k')11 b(to)g(\014ll)h(in)h(the)e +(blank)h(space)g(created)f(b)o(y)h(the)f(remo)o(v)m(al)g(of)g(the)h +(text.)18 b(A)11 b(list)h(of)f(the)h(bare)f(essen)o(tials)75 +369 y(for)k(editing)h(the)f(text)g(of)g(an)g(input)h(line)h(follo)o +(ws.)75 449 y Fo(C-b)168 b Fu(Mo)o(v)o(e)14 b(bac)o(k)h(one)h(c)o +(haracter.)75 530 y Fo(C-f)168 b Fu(Mo)o(v)o(e)14 b(forw)o(ard)g(one)h +(c)o(haracter.)75 608 y Fn(h)p 87 582 73 2 v 87 610 a +Fm(DEL)p 87 618 V 158 608 a Fn(i)188 610 y Fu(or)244 +608 y Fn(h)p 256 582 159 2 v 256 610 a Fm(Bac)o(kspace)p +256 618 V 412 608 a Fn(i)315 665 y Fu(Delete)h(the)f(c)o(haracter)g(to) +f(the)h(left)h(of)f(the)g(cursor.)75 745 y Fo(C-d)168 +b Fu(Delete)16 b(the)f(c)o(haracter)g(underneath)h(the)f(cursor.)75 +825 y(Prin)o(ting)h(c)o(haracters)315 880 y(Insert)f(the)h(c)o +(haracter)e(in)o(to)h(the)h(line)h(at)d(the)h(cursor.)75 +961 y Fo(C-_)g Fu(or)f Fo(C-x)h(C-u)315 1015 y Fu(Undo)i(the)g(last)f +(editing)i(command.)25 b(Y)l(ou)17 b(can)g(undo)g(all)g(the)g(w)o(a)o +(y)f(bac)o(k)h(to)f(an)g(empt)o(y)315 1070 y(line.)75 +1151 y(\(Dep)q(ending)i(on)f(y)o(our)g(con\014guration,)g(the)863 +1149 y Fn(h)p 875 1123 V 875 1151 a Fm(Bac)o(kspace)p +875 1159 V 1032 1149 a Fn(i)1063 1151 y Fu(k)o(ey)g(b)q(e)h(set)f(to)f +(delete)i(the)f(c)o(haracter)g(to)f(the)75 1206 y(left)h(of)f(the)h +(cursor)f(and)g(the)596 1204 y Fn(h)p 608 1178 73 2 v +608 1206 a Fm(DEL)p 608 1213 V 679 1204 a Fn(i)710 1206 +y Fu(k)o(ey)h(set)f(to)g(delete)h(the)g(c)o(haracter)f(underneath)h +(the)g(cursor,)f(lik)o(e)75 1260 y Fo(C-d)p Fu(,)e(rather)h(than)g(the) +g(c)o(haracter)g(to)f(the)i(left)f(of)g(the)g(cursor.\))75 +1374 y Fj(1.2.2)30 b(Readline)20 b(Mo)n(v)n(emen)n(t)i(Commands)137 +1471 y Fu(The)14 b(ab)q(o)o(v)o(e)e(table)i(describ)q(es)g(the)g(most)e +(basic)i(k)o(eystrok)o(es)d(that)i(y)o(ou)g(need)h(in)f(order)g(to)g +(do)g(editing)75 1526 y(of)f(the)h(input)h(line.)21 b(F)l(or)12 +b(y)o(our)g(con)o(v)o(enience,)i(man)o(y)f(other)f(commands)h(ha)o(v)o +(e)f(b)q(een)i(added)f(in)h(addition)75 1580 y(to)h Fo(C-b)p +Fu(,)h Fo(C-f)p Fu(,)f Fo(C-d)p Fu(,)g(and)522 1578 y +Fn(h)p 534 1552 V 534 1580 a Fm(DEL)p 534 1588 V 605 +1578 a Fn(i)619 1580 y Fu(.)23 b(Here)16 b(are)g(some)f(commands)h(for) +f(mo)o(ving)h(more)g(rapidly)h(ab)q(out)f(the)75 1635 +y(line.)75 1716 y Fo(C-a)168 b Fu(Mo)o(v)o(e)14 b(to)h(the)g(start)f +(of)h(the)g(line.)75 1796 y Fo(C-e)168 b Fu(Mo)o(v)o(e)14 +b(to)h(the)g(end)h(of)f(the)g(line.)75 1876 y Fo(M-f)168 +b Fu(Mo)o(v)o(e)14 b(forw)o(ard)g(a)h(w)o(ord,)f(where)i(a)e(w)o(ord)h +(is)h(comp)q(osed)f(of)g(letters)g(and)h(digits.)75 1957 +y Fo(M-b)168 b Fu(Mo)o(v)o(e)14 b(bac)o(kw)o(ard)h(a)g(w)o(ord.)75 +2037 y Fo(C-l)168 b Fu(Clear)15 b(the)h(screen,)f(reprin)o(ting)h(the)f +(curren)o(t)g(line)i(at)e(the)g(top.)137 2118 y(Notice)e(ho)o(w)f +Fo(C-f)g Fu(mo)o(v)o(es)f(forw)o(ard)g(a)h(c)o(haracter,)g(while)i +Fo(M-f)e Fu(mo)o(v)o(es)f(forw)o(ard)g(a)h(w)o(ord.)18 +b(It)13 b(is)g(a)f(lo)q(ose)75 2173 y(con)o(v)o(en)o(tion)j(that)f(con) +o(trol)h(k)o(eystrok)o(es)f(op)q(erate)h(on)f(c)o(haracters)h(while)h +(meta)e(k)o(eystrok)o(es)g(op)q(erate)h(on)75 2227 y(w)o(ords.)75 +2341 y Fj(1.2.3)30 b(Readline)20 b(Killing)h(Commands)137 +2438 y Fk(Killing)26 b Fu(text)18 b(means)g(to)g(delete)i(the)f(text)f +(from)g(the)h(line,)i(but)d(to)g(sa)o(v)o(e)g(it)h(a)o(w)o(a)o(y)e(for) +h(later)h(use,)75 2493 y(usually)f(b)o(y)f Fk(y)o(anking)22 +b Fu(\(re-inserting\))17 b(it)g(bac)o(k)g(in)o(to)g(the)h(line.)27 +b(\(`Cut')15 b(and)j(`paste')e(are)g(more)h(recen)o(t)75 +2547 y(jargon)d(for)h(`kill')h(and)g(`y)o(ank'.\))137 +2615 y(If)g(the)f(description)h(for)f(a)g(command)g(sa)o(ys)f(that)h +(it)g(`kills')h(text,)e(then)i(y)o(ou)f(can)g(b)q(e)h(sure)f(that)f(y)o +(ou)75 2670 y(can)h(get)g(the)g(text)g(bac)o(k)g(in)h(a)f(di\013eren)o +(t)g(\(or)g(the)g(same\))g(place)h(later.)p eop +%%Page: 3 5 +3 4 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(3)137 149 y(When)12 b(y)o(ou)g(use)g(a)f(kill)i(command,)f(the)g +(text)f(is)h(sa)o(v)o(ed)f(in)i(a)e Fk(kill-ring)p Fu(.)21 +b(An)o(y)12 b(n)o(um)o(b)q(er)g(of)f(consecutiv)o(e)75 +204 y(kills)17 b(sa)o(v)o(e)e(all)h(of)f(the)h(killed)i(text)d +(together,)f(so)h(that)g(when)h(y)o(ou)f(y)o(ank)g(it)h(bac)o(k,)f(y)o +(ou)g(get)g(it)h(all.)22 b(The)75 259 y(kill)c(ring)f(is)f(not)g(line)i +(sp)q(eci\014c;)g(the)e(text)g(that)f(y)o(ou)h(killed)j(on)d(a)g +(previously)h(t)o(yp)q(ed)g(line)h(is)e(a)o(v)m(ailable)75 +314 y(to)f(b)q(e)g(y)o(ank)o(ed)g(bac)o(k)h(later,)e(when)i(y)o(ou)f +(are)g(t)o(yping)g(another)g(line.)137 380 y(Here)h(is)f(the)h(list)g +(of)e(commands)h(for)g(killing)j(text.)75 458 y Fo(C-k)168 +b Fu(Kill)17 b(the)f(text)e(from)h(the)g(curren)o(t)g(cursor)g(p)q +(osition)h(to)f(the)g(end)h(of)f(the)g(line.)75 535 y +Fo(M-d)168 b Fu(Kill)15 b(from)e(the)g(cursor)g(to)f(the)i(end)g(of)e +(the)i(curren)o(t)f(w)o(ord,)f(or,)h(if)g(b)q(et)o(w)o(een)h(w)o(ords,) +e(to)h(the)315 590 y(end)j(of)f(the)g(next)g(w)o(ord.)k(W)l(ord)c(b)q +(oundaries)i(are)e(the)g(same)g(as)g(those)f(used)i(b)o(y)f +Fo(M-f)p Fu(.)75 668 y Fo(M-)123 666 y Fn(h)p 135 640 +73 2 v 135 668 a Fm(DEL)p 135 675 V 206 666 a Fn(i)315 +668 y Fu(Kill)i(from)e(the)g(cursor)g(the)h(start)e(of)h(the)g(curren)o +(t)g(w)o(ord,)f(or,)h(if)g(b)q(et)o(w)o(een)h(w)o(ords,)e(to)h(the)315 +723 y(start)j(of)h(the)g(previous)h(w)o(ord.)31 b(W)l(ord)19 +b(b)q(oundaries)h(are)f(the)h(same)e(as)h(those)g(used)h(b)o(y)315 +777 y Fo(M-b)p Fu(.)75 855 y Fo(C-w)168 b Fu(Kill)18 +b(from)d(the)g(cursor)h(to)f(the)g(previous)i(whitespace.)22 +b(This)16 b(is)g(di\013eren)o(t)g(than)f Fo(M-)1777 853 +y Fn(h)p 1789 827 V 1789 855 a Fm(DEL)p 1789 863 V 1860 +853 a Fn(i)315 910 y Fu(b)q(ecause)h(the)f(w)o(ord)g(b)q(oundaries)h +(di\013er.)137 987 y(Here)21 b(is)h(ho)o(w)e(to)g Fk(y)o(ank)j +Fu(the)e(text)f(bac)o(k)h(in)o(to)g(the)f(line.)39 b(Y)l(anking)21 +b(means)g(to)f(cop)o(y)h(the)g(most-)75 1042 y(recen)o(tly-killed)d +(text)d(from)f(the)i(kill)h(bu\013er.)75 1120 y Fo(C-y)168 +b Fu(Y)l(ank)15 b(the)h(most)e(recen)o(tly)i(killed)h(text)e(bac)o(k)g +(in)o(to)g(the)h(bu\013er)f(at)f(the)i(cursor.)75 1198 +y Fo(M-y)168 b Fu(Rotate)16 b(the)h(kill-ring,)j(and)d(y)o(ank)g(the)h +(new)f(top.)26 b(Y)l(ou)17 b(can)h(only)g(do)f(this)h(if)f(the)h(prior) +315 1252 y(command)d(is)h Fo(C-y)f Fu(or)f Fo(M-y)p Fu(.)75 +1361 y Fj(1.2.4)30 b(Readline)20 b(Argumen)n(ts)137 1457 +y Fu(Y)l(ou)15 b(can)g(pass)f(n)o(umeric)i(argumen)o(ts)e(to)g +(Readline)h(commands.)20 b(Sometimes)15 b(the)g(argumen)o(t)e(acts)75 +1511 y(as)20 b(a)f(rep)q(eat)i(coun)o(t,)f(other)g(times)g(it)h(is)f +(the)g Fl(sign)j Fu(of)c(the)h(argumen)o(t)g(that)f(is)i(signi\014can)o +(t.)35 b(If)20 b(y)o(ou)75 1566 y(pass)d(a)f(negativ)o(e)h(argumen)o(t) +f(to)g(a)g(command)h(whic)o(h)h(normally)f(acts)f(in)i(a)e(forw)o(ard)g +(direction,)i(that)75 1621 y(command)g(will)h(act)e(in)i(a)e(bac)o(kw)o +(ard)g(direction.)28 b(F)l(or)17 b(example,)i(to)e(kill)j(text)d(bac)o +(k)g(to)g(the)h(start)e(of)75 1676 y(the)f(line,)i(y)o(ou)e(migh)o(t)g +(t)o(yp)q(e)g(`)p Ft(M--)f(C-k)p Fu('.)137 1742 y(The)h(general)f(w)o +(a)o(y)f(to)h(pass)g(n)o(umeric)h(argumen)o(ts)e(to)g(a)h(command)g(is) +h(to)e(t)o(yp)q(e)h(meta)g(digits)h(b)q(efore)75 1797 +y(the)h(command.)k(If)c(the)f(\014rst)g(`digit')h(t)o(yp)q(ed)f(is)h(a) +g(min)o(us)g(sign)g(\(`)p Ft(-)p Fu('\),)d(then)j(the)f(sign)h(of)f +(the)h(argumen)o(t)75 1852 y(will)21 b(b)q(e)f(negativ)o(e.)31 +b(Once)20 b(y)o(ou)f(ha)o(v)o(e)g(t)o(yp)q(ed)g(one)g(meta)g(digit)h +(to)e(get)h(the)g(argumen)o(t)f(started,)h(y)o(ou)75 +1906 y(can)c(t)o(yp)q(e)f(the)h(remainder)g(of)f(the)g(digits,)h(and)g +(then)g(the)f(command.)20 b(F)l(or)13 b(example,)i(to)f(giv)o(e)h(the)f +Fo(C-d)75 1961 y Fu(command)19 b(an)f(argumen)o(t)g(of)g(10,)h(y)o(ou)f +(could)i(t)o(yp)q(e)f(`)p Ft(M-1)14 b(0)h(C-d)p Fu(',)k(whic)o(h)g +(will)h(delete)g(the)f(next)g(ten)75 2016 y(c)o(haracters)14 +b(on)i(the)f(input)h(line.)75 2125 y Fj(1.2.5)30 b(Searc)n(hing)21 +b(for)f(Commands)h(in)f(the)h(History)137 2220 y Fu(Readline)d(pro)o +(vides)e(commands)g(for)g(searc)o(hing)g(through)g(the)g(command)g +(history)g(for)g(lines)i(con-)75 2275 y(taining)e(a)f(sp)q(eci\014ed)i +(string.)j(There)c(are)e(t)o(w)o(o)g(searc)o(h)h(mo)q(des:)20 +b Fk(incremen)o(tal)e Fu(and)e Fk(non-incremen)o(tal)p +Fu(.)137 2341 y(Incremen)o(tal)e(searc)o(hes)f(b)q(egin)h(b)q(efore)f +(the)g(user)g(has)g(\014nished)h(t)o(yping)f(the)g(searc)o(h)g(string.) +19 b(As)13 b(eac)o(h)75 2396 y(c)o(haracter)k(of)g(the)h(searc)o(h)g +(string)f(is)h(t)o(yp)q(ed,)h(Readline)g(displa)o(ys)f(the)g(next)g(en) +o(try)f(from)g(the)h(history)75 2451 y(matc)o(hing)12 +b(the)g(string)g(t)o(yp)q(ed)g(so)g(far.)18 b(An)13 b(incremen)o(tal)g +(searc)o(h)f(requires)g(only)h(as)f(man)o(y)f(c)o(haracters)g(as)75 +2506 y(needed)16 b(to)d(\014nd)j(the)e(desired)i(history)e(en)o(try)l +(.)19 b(T)l(o)c(searc)o(h)f(bac)o(kw)o(ard)f(in)j(the)e(history)g(for)g +(a)g(particular)75 2560 y(string,)g(t)o(yp)q(e)h Fo(C-r)p +Fu(.)k(T)o(yping)d Fo(C-s)e Fu(searc)o(hes)h(forw)o(ard)e(through)h +(the)h(history)l(.)20 b(The)15 b(c)o(haracters)f(presen)o(t)75 +2615 y(in)20 b(the)f(v)m(alue)h(of)f(the)g Ft(isearch-terminators)d +Fu(v)m(ariable)k(are)f(used)h(to)e(terminate)h(an)g(incremen)o(tal)75 +2670 y(searc)o(h.)31 b(If)19 b(that)f(v)m(ariable)i(has)f(not)f(b)q +(een)i(assigned)g(a)e(v)m(alue,)j(the)1289 2668 y Fn(h)p +1301 2642 70 2 v 1301 2670 a Fm(ESC)p 1301 2678 V 1368 +2668 a Fn(i)1402 2670 y Fu(and)e Fo(C-J)f Fu(c)o(haracters)g(will)p +eop +%%Page: 4 6 +4 5 bop 75 -58 a Fu(4)1322 b(GNU)15 b(Readline)h(Library)75 +149 y(terminate)21 b(an)g(incremen)o(tal)i(searc)o(h.)37 +b Fo(C-g)21 b Fu(will)i(ab)q(ort)e(an)g(incremen)o(tal)h(searc)o(h)f +(and)g(restore)g(the)75 204 y(original)16 b(line.)21 +b(When)15 b(the)f(searc)o(h)g(is)h(terminated,)g(the)f(history)h(en)o +(try)f(con)o(taining)h(the)g(searc)o(h)f(string)75 259 +y(b)q(ecomes)i(the)f(curren)o(t)g(line.)137 325 y(T)l(o)g(\014nd)i +(other)e(matc)o(hing)g(en)o(tries)h(in)h(the)e(history)h(list,)g(t)o +(yp)q(e)f Fo(C-r)g Fu(or)g Fo(C-s)g Fu(as)h(appropriate.)k(This)75 +380 y(will)15 b(searc)o(h)e(bac)o(kw)o(ard)f(or)g(forw)o(ard)g(in)i +(the)f(history)g(for)g(the)g(next)g(en)o(try)g(matc)o(hing)g(the)g +(searc)o(h)g(string)75 434 y(t)o(yp)q(ed)19 b(so)g(far.)30 +b(An)o(y)19 b(other)f(k)o(ey)h(sequence)h(b)q(ound)g(to)e(a)h(Readline) +h(command)e(will)j(terminate)e(the)75 489 y(searc)o(h)10 +b(and)h(execute)g(that)f(command.)18 b(F)l(or)10 b(instance,)i(a)1063 +487 y Fn(h)p 1076 461 76 2 v 1076 489 a Fm(RET)p 1076 +497 V 1149 487 a Fn(i)1174 489 y Fu(will)g(terminate)f(the)g(searc)o(h) +f(and)h(accept)75 544 y(the)k(line,)h(thereb)o(y)f(executing)g(the)g +(command)g(from)f(the)g(history)h(list.)20 b(A)15 b(mo)o(v)o(emen)o(t)f +(command)g(will)75 599 y(terminate)h(the)g(searc)o(h,)g(mak)o(e)g(the)g +(last)g(line)i(found)f(the)f(curren)o(t)g(line,)h(and)g(b)q(egin)g +(editing.)137 665 y(Readline)j(remem)o(b)q(ers)e(the)h(last)f(incremen) +o(tal)i(searc)o(h)e(string.)27 b(If)17 b(t)o(w)o(o)f +Fo(C-r)p Fu(s)h(are)g(t)o(yp)q(ed)h(without)75 719 y(an)o(y)g(in)o +(terv)o(ening)h(c)o(haracters)f(de\014ning)h(a)f(new)h(searc)o(h)f +(string,)g(an)o(y)g(remem)o(b)q(ered)h(searc)o(h)f(string)g(is)75 +774 y(used.)137 840 y(Non-incremen)o(tal)25 b(searc)o(hes)e(read)h(the) +f(en)o(tire)h(searc)o(h)f(string)g(b)q(efore)h(starting)f(to)f(searc)o +(h)i(for)75 895 y(matc)o(hing)d(history)h(lines.)39 b(The)22 +b(searc)o(h)f(string)g(ma)o(y)g(b)q(e)h(t)o(yp)q(ed)f(b)o(y)h(the)f +(user)h(or)e(b)q(e)i(part)f(of)g(the)75 950 y(con)o(ten)o(ts)15 +b(of)f(the)i(curren)o(t)f(line.)75 1074 y Fs(1.3)33 b(Readline)23 +b(Init)h(File)137 1169 y Fu(Although)f(the)g(Readline)h(library)f +(comes)g(with)g(a)f(set)g(of)g(Emacs-lik)o(e)i(k)o(eybindings)g +(installed)75 1224 y(b)o(y)d(default,)h(it)f(is)h(p)q(ossible)g(to)e +(use)i(a)e(di\013eren)o(t)h(set)g(of)f(k)o(eybindings.)39 +b(An)o(y)20 b(user)h(can)g(customize)75 1278 y(programs)15 +b(that)h(use)g(Readline)i(b)o(y)e(putting)g(commands)g(in)i(an)e +Fk(inputrc)k Fu(\014le,)d(con)o(v)o(en)o(tionally)g(in)g(his)75 +1333 y(home)g(directory)l(.)24 b(The)17 b(name)g(of)f(this)h(\014le)g +(is)g(tak)o(en)g(from)e(the)i(v)m(alue)h(of)e(the)h(en)o(vironmen)o(t)g +(v)m(ariable)75 1388 y Ft(INPUTRC)p Fu(.)i(If)c(that)g(v)m(ariable)h +(is)g(unset,)f(the)g(default)h(is)g(`)p Ft(~/.inputrc)p +Fu('.)137 1454 y(When)f(a)g(program)f(whic)o(h)h(uses)g(the)g(Readline) +h(library)g(starts)d(up,)i(the)g(init)h(\014le)g(is)f(read,)g(and)g +(the)75 1509 y(k)o(ey)g(bindings)i(are)e(set.)137 1574 +y(In)f(addition,)h(the)e Ft(C-x)i(C-r)e Fu(command)g(re-reads)h(this)g +(init)g(\014le,)h(th)o(us)e(incorp)q(orating)h(an)o(y)f(c)o(hanges)75 +1629 y(that)h(y)o(ou)h(migh)o(t)g(ha)o(v)o(e)g(made)g(to)g(it.)75 +1737 y Fj(1.3.1)30 b(Readline)20 b(Init)g(File)h(Syn)n(tax)137 +1832 y Fu(There)c(are)g(only)g(a)g(few)f(basic)i(constructs)e(allo)o(w) +o(ed)i(in)f(the)g(Readline)h(init)g(\014le.)26 b(Blank)18 +b(lines)g(are)75 1886 y(ignored.)36 b(Lines)22 b(b)q(eginning)h(with)d +(a)h(`)p Ft(#)p Fu(')e(are)h(commen)o(ts.)35 b(Lines)22 +b(b)q(eginning)h(with)e(a)f(`)p Ft($)p Fu(')f(indicate)75 +1941 y(conditional)c(constructs)f(\(see)g(Section)g(1.3.2)f +([Conditional)h(Init)h(Constructs],)e(page)h(9\).)k(Other)c(lines)75 +1996 y(denote)h(v)m(ariable)i(settings)e(and)h(k)o(ey)f(bindings.)75 +2073 y(V)l(ariable)h(Settings)315 2128 y(Y)l(ou)k(can)h(mo)q(dify)g +(the)f(run-time)h(b)q(eha)o(vior)g(of)e(Readline)j(b)o(y)e(altering)h +(the)f(v)m(alues)h(of)315 2182 y(v)m(ariables)d(in)g(Readline)g(using)f +(the)g Ft(set)g Fu(command)f(within)i(the)f(init)h(\014le.)26 +b(The)17 b(syn)o(tax)315 2237 y(is)f(simple:)435 2300 +y Ft(set)23 b Fk(v)m(ariable)28 b(v)m(alue)315 2366 y +Fu(Here,)14 b(for)f(example,)h(is)g(ho)o(w)f(to)g(c)o(hange)h(from)f +(the)h(default)g(Emacs-lik)o(e)h(k)o(ey)e(binding)j(to)315 +2421 y(use)g Ft(vi)e Fu(line)j(editing)g(commands:)435 +2484 y Ft(set)23 b(editing-mode)g(vi)315 2549 y Fu(V)l(ariable)c(names) +e(and)h(v)m(alues,)h(where)e(appropriate,)h(are)f(recognized)i(without) +e(regard)315 2604 y(to)e(case.)315 2670 y(A)g(great)g(deal)g(of)g +(run-time)h(b)q(eha)o(vior)g(is)g(c)o(hangeable)g(with)f(the)h(follo)o +(wing)f(v)m(ariables.)p eop +%%Page: 5 7 +5 6 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(5)315 149 y Ft(bell-style)555 204 y Fu(Con)o(trols)21 +b(what)h(happ)q(ens)h(when)f(Readline)h(w)o(an)o(ts)e(to)g(ring)i(the)f +(termi-)555 259 y(nal)d(b)q(ell.)32 b(If)19 b(set)f(to)g(`)p +Ft(none)p Fu(',)g(Readline)i(nev)o(er)f(rings)g(the)f(b)q(ell.)32 +b(If)19 b(set)g(to)555 314 y(`)p Ft(visible)p Fu(',)c(Readline)i(uses)g +(a)f(visible)j(b)q(ell)g(if)e(one)f(is)h(a)o(v)m(ailable.)26 +b(If)16 b(set)h(to)555 369 y(`)p Ft(audible)p Fu(')g(\(the)h +(default\),)i(Readline)g(attempts)e(to)g(ring)h(the)g(terminal's)555 +423 y(b)q(ell.)315 504 y Ft(comment-begin)555 559 y Fu(The)c(string)f +(to)g(insert)i(at)d(the)i(b)q(eginning)i(of)d(the)h(line)h(when)f(the)g +Ft(insert-)555 614 y(comment)f Fu(command)h(is)h(executed.)21 +b(The)15 b(default)h(v)m(alue)g(is)g Ft("#")p Fu(.)315 +694 y Ft(completion-ignore-case)555 749 y Fu(If)e(set)f(to)g(`)p +Ft(on)p Fu(',)g(Readline)i(p)q(erforms)e(\014lename)i(matc)o(hing)f +(and)g(completion)555 804 y(in)i(a)f(case-insensitiv)o(e)i(fashion.)k +(The)15 b(default)h(v)m(alue)g(is)g(`)p Ft(off)p Fu('.)315 +884 y Ft(completion-query-items)555 939 y Fu(The)d(n)o(um)o(b)q(er)h +(of)e(p)q(ossible)j(completions)g(that)d(determines)i(when)g(the)f +(user)555 994 y(is)21 b(ask)o(ed)g(whether)g(he)h(w)o(an)o(ts)d(to)i +(see)g(the)g(list)h(of)e(p)q(ossibilitie)q(s.)40 b(If)21 +b(the)555 1049 y(n)o(um)o(b)q(er)14 b(of)f(p)q(ossible)i(completions)f +(is)g(greater)f(than)g(this)h(v)m(alue,)h(Readline)555 +1104 y(will)g(ask)e(the)g(user)h(whether)f(or)g(not)g(he)g(wishes)h(to) +f(view)h(them;)f(otherwise,)555 1158 y(they)f(are)g(simply)i(listed.)20 +b(This)13 b(v)m(ariable)g(m)o(ust)f(b)q(e)h(set)f(to)f(an)h(in)o(teger) +h(v)m(alue)555 1213 y(greater)h(than)h(or)g(equal)h(to)f(0.)k(The)d +(default)f(limit)i(is)f Ft(100)p Fu(.)315 1294 y Ft(convert-meta)555 +1348 y Fu(If)11 b(set)g(to)g(`)p Ft(on)p Fu(',)f(Readline)i(will)h(con) +o(v)o(ert)d(c)o(haracters)h(with)g(the)g(eigh)o(th)h(bit)f(set)555 +1403 y(to)f(an)h Fp(asci)q(i)e Fu(k)o(ey)i(sequence)g(b)o(y)g +(stripping)h(the)e(eigh)o(th)h(bit)h(and)e(pre\014xing)i(an)555 +1456 y Fn(h)p 567 1430 70 2 v 567 1458 a Fm(ESC)p 567 +1466 V 634 1456 a Fn(i)666 1458 y Fu(c)o(haracter,)k(con)o(v)o(erting)h +(them)g(to)f(a)h(meta-pre\014xed)g(k)o(ey)g(sequence.)555 +1513 y(The)e(default)h(v)m(alue)h(is)e(`)p Ft(on)p Fu('.)315 +1593 y Ft(disable-completion)555 1648 y Fu(If)k(set)f(to)f(`)p +Ft(On)p Fu(',)h(Readline)i(will)g(inhibit)g(w)o(ord)e(completion.)30 +b(Completion)555 1703 y(c)o(haracters)12 b(will)j(b)q(e)f(inserted)g +(in)o(to)f(the)g(line)h(as)f(if)h(they)f(had)g(b)q(een)h(mapp)q(ed)555 +1758 y(to)h Ft(self-insert)p Fu(.)j(The)d(default)h(is)g(`)p +Ft(off)p Fu('.)315 1838 y Ft(editing-mode)555 1893 y +Fu(The)f Ft(editing-mode)d Fu(v)m(ariable)k(con)o(trols)e(whic)o(h)h +(default)g(set)f(of)g(k)o(ey)g(bind-)555 1948 y(ings)f(is)g(used.)20 +b(By)12 b(default,)i(Readline)f(starts)f(up)h(in)g(Emacs)f(editing)i +(mo)q(de,)555 2003 y(where)h(the)f(k)o(eystrok)o(es)g(are)g(most)g +(similar)i(to)d(Emacs.)20 b(This)15 b(v)m(ariable)h(can)555 +2058 y(b)q(e)g(set)f(to)f(either)i(`)p Ft(emacs)p Fu(')e(or)h(`)p +Ft(vi)p Fu('.)315 2138 y Ft(enable-keypad)555 2193 y +Fu(When)d(set)f(to)h(`)p Ft(on)p Fu(',)e(Readline)j(will)h(try)d(to)g +(enable)i(the)f(application)h(k)o(eypad)555 2248 y(when)h(it)f(is)h +(called.)21 b(Some)13 b(systems)g(need)h(this)g(to)f(enable)h(the)g +(arro)o(w)e(k)o(eys.)555 2303 y(The)j(default)h(is)g(`)p +Ft(off)p Fu('.)315 2383 y Ft(expand-tilde)555 2438 y +Fu(If)e(set)g(to)f(`)p Ft(on)p Fu(',)f(tilde)k(expansion)e(is)h(p)q +(erformed)f(when)g(Readline)h(attempts)555 2493 y(w)o(ord)g +(completion.)21 b(The)15 b(default)h(is)f(`)p Ft(off)p +Fu('.)555 2560 y(If)g(set)g(to)f(`)p Ft(on)p Fu(',)g(the)g(history)h +(co)q(de)h(attempts)e(to)g(place)i(p)q(oin)o(t)f(at)f(the)h(same)555 +2615 y(lo)q(cation)20 b(on)f(eac)o(h)g(history)h(line)g(retriv)o(ed)g +(with)f Ft(previous-history)e Fu(or)555 2670 y Ft(next-history)p +Fu(.)p eop +%%Page: 6 8 +6 7 bop 75 -58 a Fu(6)1322 b(GNU)15 b(Readline)h(Library)315 +149 y Ft(horizontal-scroll-mode)555 204 y Fu(This)j(v)m(ariable)g(can)f +(b)q(e)g(set)g(to)f(either)i(`)p Ft(on)p Fu(')e(or)g(`)p +Ft(off)p Fu('.)27 b(Setting)19 b(it)f(to)f(`)p Ft(on)p +Fu(')555 259 y(means)c(that)f(the)i(text)e(of)h(the)g(lines)i(b)q(eing) +f(edited)g(will)h(scroll)f(horizon)o(tally)555 314 y(on)i(a)f(single)i +(screen)g(line)g(when)g(they)f(are)f(longer)h(than)g(the)g(width)g(of)g +(the)555 369 y(screen,)e(instead)f(of)g(wrapping)g(on)o(to)f(a)h(new)g +(screen)h(line.)21 b(By)13 b(default,)h(this)555 423 +y(v)m(ariable)j(is)e(set)g(to)g(`)p Ft(off)p Fu('.)315 +506 y Ft(input-meta)555 560 y Fu(If)h(set)f(to)g(`)p +Ft(on)p Fu(',)f(Readline)j(will)h(enable)e(eigh)o(t-bit)h(input)f(\(it) +g(will)h(not)e(clear)555 615 y(the)20 b(eigh)o(th)g(bit)g(in)h(the)f(c) +o(haracters)f(it)h(reads\),)g(regardless)g(of)g(what)f(the)555 +670 y(terminal)i(claims)g(it)f(can)g(supp)q(ort.)34 b(The)20 +b(default)h(v)m(alue)g(is)g(`)p Ft(off)p Fu('.)33 b(The)555 +725 y(name)15 b Ft(meta-flag)f Fu(is)i(a)f(synon)o(ym)g(for)f(this)i(v) +m(ariable.)315 807 y Ft(isearch-terminators)555 862 y +Fu(The)26 b(string)g(of)f(c)o(haracters)g(that)g(should)i(terminate)f +(an)g(incremen)o(tal)555 917 y(searc)o(h)12 b(without)h(subsequen)o +(tly)g(executing)h(the)e(c)o(haracter)g(as)g(a)g(command)555 +971 y(\(see)22 b(Section)h(1.2.5)e([Searc)o(hing],)j(page)e(3\).)40 +b(If)23 b(this)g(v)m(ariable)g(has)f(not)555 1026 y(b)q(een)17 +b(giv)o(en)f(a)g(v)m(alue,)g(the)g(c)o(haracters)1247 +1024 y Fn(h)p 1259 998 70 2 v 1259 1026 a Fm(ESC)p 1259 +1034 V 1326 1024 a Fn(i)1357 1026 y Fu(and)g Fo(C-J)f +Fu(will)i(terminate)f(an)555 1081 y(incremen)o(tal)g(searc)o(h.)315 +1163 y Ft(keymap)96 b Fu(Sets)19 b(Readline's)i(idea)f(of)f(the)g +(curren)o(t)h(k)o(eymap)f(for)f(k)o(ey)i(binding)h(com-)555 +1218 y(mands.)41 b(Acceptable)23 b Ft(keymap)f Fu(names)g(are)f +Ft(emacs)p Fu(,)i Ft(emacs-standard)p Fu(,)555 1273 y +Ft(emacs-meta)p Fu(,)49 b Ft(emacs-ctlx)p Fu(,)g Ft(vi)p +Fu(,)h Ft(vi-move)p Fu(,)f Ft(vi-command)p Fu(,)g(and)555 +1328 y Ft(vi-insert)p Fu(.)31 b Ft(vi)20 b Fu(is)g(equiv)m(alen)o(t)h +(to)e Ft(vi-command)p Fu(;)g Ft(emacs)g Fu(is)h(equiv)m(alen)o(t)555 +1382 y(to)15 b Ft(emacs-standard)p Fu(.)20 b(The)d(default)f(v)m(alue)h +(is)g Ft(emacs)p Fu(.)k(The)16 b(v)m(alue)h(of)f(the)555 +1437 y Ft(editing-mode)e Fu(v)m(ariable)i(also)f(a\013ects)g(the)g +(default)h(k)o(eymap.)315 1519 y Ft(mark-directories)555 +1574 y Fu(If)j(set)g(to)g(`)p Ft(on)p Fu(',)f(completed)i(directory)g +(names)f(ha)o(v)o(e)f(a)h(slash)h(app)q(ended.)555 1629 +y(The)15 b(default)h(is)g(`)p Ft(on)p Fu('.)315 1711 +y Ft(mark-modified-lines)555 1766 y Fu(This)j(v)m(ariable,)g(when)g +(set)e(to)h(`)p Ft(on)p Fu(',)f(causes)h(Readline)h(to)e(displa)o(y)i +(an)f(as-)555 1821 y(terisk)f(\(`)p Ft(*)p Fu('\))e(at)i(the)f(start)g +(of)h(history)f(lines)j(whic)o(h)e(ha)o(v)o(e)g(b)q(een)h(mo)q +(di\014ed.)555 1875 y(This)e(v)m(ariable)g(is)g(`)p Ft(off)p +Fu(')e(b)o(y)h(default.)315 1958 y Ft(mark-symlinked-directories)555 +2012 y Fu(If)23 b(set)f(to)f(`)p Ft(on)p Fu(',)i(completed)g(names)g +(whic)o(h)g(are)f(sym)o(b)q(olic)i(links)f(to)f(di-)555 +2067 y(rectories)h(ha)o(v)o(e)g(a)g(slash)g(app)q(ended)i(\(sub)s(ject) +e(to)f(the)i(v)m(alue)g(of)f Ft(mark-)555 2122 y(directories)p +Fu(\).)18 b(The)d(default)h(is)g(`)p Ft(off)p Fu('.)315 +2204 y Ft(match-hidden-files)555 2259 y Fu(This)c(v)m(ariable,)h(when)e +(set)g(to)g(`)p Ft(on)p Fu(',)f(causes)h(Readline)i(to)d(matc)o(h)h +(\014les)h(whose)555 2314 y(names)22 b(b)q(egin)h(with)g(a)e(`)p +Ft(.)p Fu(')h(\(hidden)h(\014les\))g(when)f(p)q(erforming)h(\014lename) +555 2369 y(completion,)g(unless)f(the)f(leading)h(`)p +Ft(.)p Fu(')e(is)h(supplied)i(b)o(y)e(the)f(user)h(in)h(the)555 +2423 y(\014lename)16 b(to)f(b)q(e)h(completed.)21 b(This)15 +b(v)m(ariable)i(is)f(`)p Ft(on)p Fu(')e(b)o(y)h(default.)315 +2506 y Ft(output-meta)555 2560 y Fu(If)j(set)f(to)g(`)p +Ft(on)p Fu(',)g(Readline)i(will)h(displa)o(y)f(c)o(haracters)d(with)j +(the)e(eigh)o(th)h(bit)555 2615 y(set)g(directly)i(rather)d(than)h(as)g +(a)g(meta-pre\014xed)h(escap)q(e)g(sequence.)30 b(The)555 +2670 y(default)16 b(is)f(`)p Ft(off)p Fu('.)p eop +%%Page: 7 9 +7 8 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(7)315 149 y Ft(page-completions)555 204 y Fu(If)17 +b(set)g(to)f(`)p Ft(on)p Fu(',)g(Readline)i(uses)g(an)e(in)o(ternal)i +Ft(more)p Fu(-lik)o(e)g(pager)f(to)f(displa)o(y)555 259 +y(a)g(screenful)h(of)f(p)q(ossible)i(completions)f(at)f(a)g(time.)23 +b(This)17 b(v)m(ariable)g(is)g(`)p Ft(on)p Fu(')555 314 +y(b)o(y)e(default.)315 395 y Ft(print-completions-horizont)o(ally)555 +450 y Fu(If)d(set)g(to)f(`)p Ft(on)p Fu(',)h(Readline)h(will)g(displa)o +(y)h(completions)f(with)f(matc)o(hes)f(sorted)555 505 +y(horizon)o(tally)23 b(in)f(alphab)q(etical)i(order,)f(rather)e(than)g +(do)o(wn)h(the)g(screen.)555 560 y(The)15 b(default)h(is)g(`)p +Ft(off)p Fu('.)315 641 y Ft(show-all-if-ambiguous)555 +696 y Fu(This)g(alters)e(the)i(default)f(b)q(eha)o(vior)h(of)e(the)h +(completion)h(functions.)21 b(If)15 b(set)555 751 y(to)e(`)p +Ft(on)p Fu(',)g(w)o(ords)g(whic)o(h)h(ha)o(v)o(e)g(more)f(than)g(one)h +(p)q(ossible)i(completion)f(cause)555 806 y(the)20 b(matc)o(hes)f(to)f +(b)q(e)j(listed)f(immediately)h(instead)f(of)f(ringing)i(the)e(b)q +(ell.)555 861 y(The)c(default)h(v)m(alue)h(is)e(`)p Ft(off)p +Fu('.)315 942 y Ft(visible-stats)555 997 y Fu(If)h(set)g(to)f(`)p +Ft(on)p Fu(',)g(a)h(c)o(haracter)f(denoting)h(a)g(\014le's)h(t)o(yp)q +(e)f(is)g(app)q(ended)i(to)d(the)555 1052 y(\014lename)h(when)g +(listing)h(p)q(ossible)g(completions.)j(The)c(default)g(is)f(`)p +Ft(off)p Fu('.)75 1133 y(Key)h(Bindings)315 1188 y(The)21 +b(syn)o(tax)f(for)h(con)o(trolling)h(k)o(ey)f(bindings)h(in)g(the)f +(init)h(\014le)g(is)g(simple.)39 b(First)20 b(y)o(ou)315 +1243 y(need)15 b(to)e(\014nd)h(the)g(name)g(of)g(the)f(command)h(that)f +(y)o(ou)h(w)o(an)o(t)f(to)g(c)o(hange.)19 b(The)14 b(follo)o(wing)315 +1298 y(sections)k(con)o(tain)h(tables)f(of)f(the)h(command)g(name,)g +(the)g(default)h(k)o(eybinding,)h(if)e(an)o(y)l(,)315 +1353 y(and)d(a)g(short)g(description)i(of)d(what)h(the)g(command)g(do)q +(es.)315 1421 y(Once)k(y)o(ou)f(kno)o(w)f(the)h(name)g(of)g(the)g +(command,)g(simply)h(place)g(on)f(a)f(line)j(in)f(the)f(init)315 +1476 y(\014le)g(the)f(name)g(of)f(the)h(k)o(ey)g(y)o(ou)f(wish)i(to)e +(bind)i(the)f(command)g(to,)f(a)g(colon,)i(and)f(then)315 +1530 y(the)f(name)g(of)g(the)g(command.)22 b(The)16 b(name)g(of)g(the)g +(k)o(ey)f(can)i(b)q(e)f(expressed)h(in)g(di\013eren)o(t)315 +1585 y(w)o(a)o(ys,)d(dep)q(ending)j(on)e(what)g(y)o(ou)g(\014nd)h(most) +e(comfortable.)315 1653 y(In)19 b(addition)g(to)e(command)h(names,)g +(readline)i(allo)o(ws)e(k)o(eys)g(to)f(b)q(e)i(b)q(ound)g(to)e(a)h +(string)315 1708 y(that)c(is)i(inserted)g(when)g(the)f(k)o(ey)g(is)h +(pressed)g(\(a)e Fk(macro)r Fu(\).)315 1790 y Fk(k)o(eyname)s +Fu(:)19 b Fk(function-name)g Fu(or)c Fk(macro)555 1845 +y(k)o(eyname)i Fu(is)e(the)f(name)h(of)f(a)g(k)o(ey)g(sp)q(elled)j(out) +d(in)h(English.)21 b(F)l(or)13 b(example:)675 1910 y +Ft(Control-u:)22 b(universal-argument)675 1962 y(Meta-Rubout:)g +(backward-kill-word)675 2014 y(Control-o:)g(">)i(output")555 +2082 y Fu(In)c(the)f(ab)q(o)o(v)o(e)g(example,)i Fo(C-u)e +Fu(is)h(b)q(ound)g(to)f(the)g(function)h Ft(universal-)555 +2137 y(argument)p Fu(,)e Fo(M-DEL)h Fu(is)g(b)q(ound)h(to)e(the)h +(function)h Ft(backward-kill-word)p Fu(,)555 2191 y(and)g +Fo(C-o)f Fu(is)h(b)q(ound)g(to)f(run)h(the)f(macro)g(expressed)h(on)g +(the)f(righ)o(t)h(hand)555 2246 y(side)c(\(that)e(is,)i(to)e(insert)i +(the)f(text)g(`)p Ft(>)f(output)p Fu(')g(in)o(to)i(the)f(line\).)555 +2314 y(A)k(n)o(um)o(b)q(er)f(of)g(sym)o(b)q(olic)i(c)o(haracter)e +(names)g(are)g(recognized)i(while)g(pro-)555 2369 y(cessing)13 +b(this)f(k)o(ey)g(binding)h(syn)o(tax:)18 b Fk(DEL)p +Fu(,)11 b Fk(ESC)p Fu(,)h Fk(ESCAPE)p Fu(,)f Fk(LFD)p +Fu(,)g Fk(NEW-)555 2424 y(LINE)p Fu(,)16 b Fk(RET)p Fu(,)e +Fk(RETURN)p Fu(,)f Fk(R)o(UBOUT)p Fu(,)i Fk(SP)l(A)o(CE)p +Fu(,)g Fk(SPC)p Fu(,)f(and)i Fk(T)l(AB)p Fu(.)315 2506 +y Ft(")p Fk(k)o(eyseq)q Ft(")p Fu(:)k Fk(function-name)e +Fu(or)d Fk(macro)555 2560 y(k)o(eyseq)i Fu(di\013ers)e(from)g +Fk(k)o(eyname)j Fu(ab)q(o)o(v)o(e)d(in)i(that)d(strings)i(denoting)g +(an)f(en-)555 2615 y(tire)i(k)o(ey)g(sequence)h(can)f(b)q(e)g(sp)q +(eci\014ed,)i(b)o(y)e(placing)h(the)f(k)o(ey)g(sequence)h(in)555 +2670 y(double)e(quotes.)j(Some)c Fp(gnu)g Fu(Emacs)f(st)o(yle)h(k)o(ey) +g(escap)q(es)g(can)g(b)q(e)g(used,)g(as)p eop +%%Page: 8 10 +8 9 bop 75 -58 a Fu(8)1322 b(GNU)15 b(Readline)h(Library)555 +149 y(in)i(the)f(follo)o(wing)g(example,)h(but)f(the)g(sp)q(ecial)i(c)o +(haracter)d(names)h(are)f(not)555 204 y(recognized.)675 +270 y Ft("\\C-u":)23 b(universal-argument)675 322 y("\\C-x\\C-r":)f +(re-read-init-file)675 373 y("\\e[11~":)h("Function)f(Key)i(1")555 +442 y Fu(In)33 b(the)f(ab)q(o)o(v)o(e)g(example,)37 b +Fo(C-u)32 b Fu(is)h(again)f(b)q(ound)h(to)f(the)g(function)555 +497 y Ft(universal-argument)19 b Fu(\(just)j(as)f(it)h(w)o(as)f(in)i +(the)f(\014rst)f(example\),)j(`)p Fo(C-x)555 551 y(C-r)p +Fu(')c(is)h(b)q(ound)g(to)f(the)h(function)g Ft(re-read-init-file)p +Fu(,)f(and)g(`)1731 549 y Fn(h)p 1743 523 70 2 v 1743 +551 a Fm(ESC)p 1743 559 V 1810 549 a Fn(i)15 b(h)p 1852 +523 10 2 v 1852 551 a Fm([)p 1852 560 V 1860 549 a Fn(i)555 +604 y(h)p 567 578 18 2 v 567 606 a Fm(1)p 567 614 V 583 +604 a Fn(i)g(h)p 625 578 V 625 606 a Fm(1)p 625 614 V +640 604 a Fn(i)g(h)p 683 578 24 2 v 683 606 a Ft(~)p +683 614 V 704 604 a Fn(i)719 606 y Fu(')g(is)h(b)q(ound)g(to)e(insert)i +(the)f(text)g(`)p Ft(Function)f(Key)g(1)p Fu('.)315 688 +y(The)h(follo)o(wing)h Fp(gnu)e Fu(Emacs)h(st)o(yle)g(escap)q(e)h +(sequences)g(are)e(a)o(v)m(ailable)j(when)e(sp)q(ecifying)315 +743 y(k)o(ey)g(sequences:)315 825 y Fo(\\C-)168 b Fu(con)o(trol)15 +b(pre\014x)315 907 y Fo(\\M-)168 b Fu(meta)15 b(pre\014x)315 +989 y Fo(\\e)192 b Fu(an)15 b(escap)q(e)h(c)o(haracter)315 +1071 y Fo(\\\\)192 b Fu(bac)o(kslash)315 1152 y Fo(\\)p +Ft(")555 1150 y Fn(h)p 567 1124 V 567 1152 a Ft(")p 567 +1160 V 589 1150 a Fn(i)604 1152 y Fu(,)15 b(a)f(double)j(quotation)e +(mark)315 1234 y Fo(\\')555 1232 y Fn(h)p 567 1206 10 +2 v 567 1234 a Fm(')p 567 1242 V 575 1232 a Fn(i)590 +1234 y Fu(,)g(a)f(single)j(quote)e(or)g(ap)q(ostrophe)315 +1316 y(In)f(addition)h(to)f(the)f Fp(gnu)h Fu(Emacs)g(st)o(yle)f(escap) +q(e)i(sequences,)g(a)e(second)i(set)e(of)h(bac)o(kslash)315 +1371 y(escap)q(es)i(is)g(a)o(v)m(ailable:)315 1453 y +Ft(\\a)192 b Fu(alert)15 b(\(b)q(ell\))315 1535 y Ft(\\b)192 +b Fu(bac)o(kspace)315 1617 y Ft(\\d)g Fu(delete)315 1699 +y Ft(\\f)g Fu(form)14 b(feed)315 1781 y Ft(\\n)192 b +Fu(newline)315 1862 y Ft(\\r)g Fu(carriage)15 b(return)315 +1944 y Ft(\\t)192 b Fu(horizon)o(tal)16 b(tab)315 2026 +y Ft(\\v)192 b Fu(v)o(ertical)16 b(tab)315 2108 y Ft(\\)p +Fk(nnn)141 b Fu(the)17 b(eigh)o(t-bit)h(c)o(haracter)f(whose)g(v)m +(alue)i(is)e(the)h(o)q(ctal)f(v)m(alue)i Fk(nnn)f Fu(\(one)f(to)555 +2163 y(three)e(digits\))315 2245 y Ft(\\x)p Fk(HH)124 +b Fu(the)20 b(eigh)o(t-bit)g(c)o(haracter)f(whose)h(v)m(alue)h(is)f +(the)g(hexadecimal)h(v)m(alue)g Fk(HH)555 2300 y Fu(\(one)15 +b(or)g(t)o(w)o(o)f(hex)h(digits\))315 2382 y(When)k(en)o(tering)g(the)g +(text)f(of)g(a)h(macro,)f(single)i(or)e(double)i(quotes)f(m)o(ust)f(b)q +(e)h(used)h(to)315 2436 y(indicate)12 b(a)f(macro)f(de\014nition.)20 +b(Unquoted)11 b(text)f(is)i(assumed)e(to)h(b)q(e)g(a)f(function)i +(name.)18 b(In)315 2491 y(the)11 b(macro)f(b)q(o)q(dy)l(,)i(the)f(bac)o +(kslash)g(escap)q(es)g(describ)q(ed)i(ab)q(o)o(v)o(e)d(are)g(expanded.) +20 b(Bac)o(kslash)315 2546 y(will)i(quote)d(an)o(y)h(other)g(c)o +(haracter)f(in)i(the)f(macro)f(text,)h(including)j(`)p +Ft(")p Fu(')c(and)h(`)p Ft(')p Fu('.)34 b(F)l(or)315 +2601 y(example,)14 b(the)f(follo)o(wing)g(binding)i(will)g(mak)o(e)d(`) +p Fo(C-x)i Ft(\\)p Fu(')f(insert)g(a)g(single)h(`)p Ft(\\)p +Fu(')e(in)o(to)h(the)g(line:)435 2666 y Ft("\\C-x\\\\":)23 +b("\\\\")p eop +%%Page: 9 11 +9 10 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(9)75 149 y Fj(1.3.2)30 b(Conditional)20 b(Init)g(Constructs)137 +246 y Fu(Readline)f(implemen)o(ts)g(a)f(facilit)o(y)g(similar)h(in)g +(spirit)f(to)f(the)h(conditional)h(compilation)g(features)75 +301 y(of)e(the)g(C)g(prepro)q(cessor)g(whic)o(h)i(allo)o(ws)e(k)o(ey)g +(bindings)i(and)f(v)m(ariable)g(settings)f(to)g(b)q(e)h(p)q(erformed)f +(as)75 355 y(the)e(result)h(of)f(tests.)k(There)c(are)g(four)g(parser)g +(directiv)o(es)h(used.)75 435 y Ft($if)168 b Fu(The)16 +b Ft($if)f Fu(construct)g(allo)o(ws)h(bindings)i(to)d(b)q(e)h(made)g +(based)g(on)f(the)h(editing)h(mo)q(de,)f(the)315 490 +y(terminal)k(b)q(eing)g(used,)g(or)f(the)g(application)i(using)e +(Readline.)33 b(The)19 b(text)g(of)f(the)i(test)315 545 +y(extends)c(to)e(the)h(end)h(of)f(the)g(line;)i(no)e(c)o(haracters)f +(are)h(required)i(to)d(isolate)i(it.)315 624 y Ft(mode)144 +b Fu(The)11 b Ft(mode=)e Fu(form)h(of)g(the)h Ft($if)f +Fu(directiv)o(e)h(is)g(used)g(to)f(test)g(whether)h(Readline)555 +679 y(is)k(in)h Ft(emacs)e Fu(or)g Ft(vi)g Fu(mo)q(de.)20 +b(This)c(ma)o(y)e(b)q(e)h(used)g(in)h(conjunction)g(with)f(the)555 +734 y(`)p Ft(set)f(keymap)p Fu(')f(command,)g(for)h(instance,)g(to)f +(set)h(bindings)h(in)g(the)f Ft(emacs-)555 789 y(standard)d +Fu(and)i Ft(emacs-ctlx)e Fu(k)o(eymaps)h(only)i(if)f(Readline)g(is)g +(starting)f(out)555 844 y(in)k Ft(emacs)f Fu(mo)q(de.)315 +923 y Ft(term)144 b Fu(The)14 b Ft(term=)e Fu(form)h(ma)o(y)g(b)q(e)h +(used)g(to)f(include)j(terminal-sp)q(eci\014c)g(k)o(ey)d(bind-)555 +978 y(ings,)19 b(p)q(erhaps)g(to)e(bind)i(the)g(k)o(ey)e(sequences)j +(output)e(b)o(y)g(the)g(terminal's)555 1033 y(function)13 +b(k)o(eys.)18 b(The)13 b(w)o(ord)e(on)h(the)g(righ)o(t)g(side)g(of)g +(the)g(`)p Ft(=)p Fu(')f(is)h(tested)g(against)555 1088 +y(b)q(oth)j(the)g(full)i(name)e(of)f(the)h(terminal)h(and)f(the)g(p)q +(ortion)h(of)e(the)h(terminal)555 1142 y(name)i(b)q(efore)g(the)g +(\014rst)f(`)p Ft(-)p Fu('.)24 b(This)17 b(allo)o(ws)g +Ft(sun)f Fu(to)g(matc)o(h)h(b)q(oth)f Ft(sun)h Fu(and)555 +1197 y Ft(sun-cmd)p Fu(,)d(for)g(instance.)315 1277 y +Ft(application)555 1332 y Fu(The)d Fk(application)i Fu(construct)e(is)g +(used)h(to)e(include)j(application-sp)q(eci)q(\014c)h(set-)555 +1386 y(tings.)19 b(Eac)o(h)12 b(program)f(using)j(the)e(Readline)i +(library)f(sets)f(the)g Fk(application)555 1441 y(name)p +Fu(,)g(and)g(y)o(ou)f(can)h(test)f(for)g(a)g(particular)h(v)m(alue.)20 +b(This)12 b(could)h(b)q(e)f(used)h(to)555 1496 y(bind)18 +b(k)o(ey)e(sequences)i(to)d(functions)j(useful)f(for)f(a)g(sp)q +(eci\014c)i(program.)23 b(F)l(or)555 1551 y(instance,)17 +b(the)g(follo)o(wing)g(command)g(adds)f(a)g(k)o(ey)h(sequence)g(that)f +(quotes)555 1606 y(the)f(curren)o(t)g(or)g(previous)h(w)o(ord)e(in)j +(Bash:)675 1670 y Ft($if)23 b(Bash)675 1722 y(#)h(Quote)f(the)g +(current)g(or)h(previous)f(word)675 1774 y("\\C-xq":)g +("\\eb\\"\\ef\\"")675 1826 y($endif)75 1905 y($endif)96 +b Fu(This)16 b(command,)e(as)h(seen)h(in)g(the)f(previous)h(example,)g +(terminates)f(an)g Ft($if)f Fu(command.)75 1985 y Ft($else)120 +b Fu(Commands)15 b(in)h(this)f(branc)o(h)h(of)e(the)i +Ft($if)e Fu(directiv)o(e)j(are)e(executed)h(if)g(the)f(test)g(fails.)75 +2065 y Ft($include)48 b Fu(This)22 b(directiv)o(e)h(tak)o(es)e(a)h +(single)h(\014lename)g(as)e(an)h(argumen)o(t)f(and)h(reads)f(commands) +315 2120 y(and)e(bindings)j(from)c(that)h(\014le.)33 +b(F)l(or)19 b(example,)i(the)e(follo)o(wing)h(directiv)o(e)h(reads)e +(from)315 2174 y(`)p Ft(/etc/inputrc)p Fu(':)435 2239 +y Ft($include)k(/etc/inputrc)75 2351 y Fj(1.3.3)30 b(Sample)20 +b(Init)h(File)137 2447 y Fu(Here)16 b(is)g(an)f(example)h(of)f(an)g +Fk(inputrc)k Fu(\014le.)i(This)16 b(illustrates)g(k)o(ey)f(binding,)i +(v)m(ariable)f(assignmen)o(t,)75 2502 y(and)f(conditional)i(syn)o(tax.) +p eop +%%Page: 10 12 +10 11 bop 75 -58 a Fu(10)1299 b(GNU)15 b(Readline)h(Library)195 +201 y Ft(#)24 b(This)f(file)g(controls)g(the)h(behaviour)e(of)i(line)f +(input)g(editing)g(for)195 253 y(#)h(programs)e(that)i(use)f(the)h(GNU) +f(Readline)g(library.)47 b(Existing)195 305 y(#)24 b(programs)e +(include)h(FTP,)h(Bash,)f(and)g(GDB.)195 357 y(#)195 +409 y(#)h(You)f(can)h(re-read)f(the)g(inputrc)g(file)g(with)h(C-x)f +(C-r.)195 461 y(#)h(Lines)f(beginning)g(with)g('#')g(are)h(comments.) +195 513 y(#)195 565 y(#)g(First,)f(include)g(any)g(systemwide)g +(bindings)f(and)i(variable)195 616 y(#)g(assignments)e(from)h +(/etc/Inputrc)195 668 y($include)g(/etc/Inputrc)195 772 +y(#)195 824 y(#)h(Set)f(various)g(bindings)g(for)g(emacs)g(mode.)195 +928 y(set)g(editing-mode)g(emacs)195 1032 y($if)g(mode=emacs)195 +1135 y(Meta-Control-h:)46 b(backward-kill-word)21 b(Text)i(after)h(the) +f(function)g(name)g(is)h(ignored)p 1986 1145 21 38 v +195 1239 a(#)195 1291 y(#)g(Arrow)f(keys)g(in)h(keypad)f(mode)195 +1343 y(#)195 1395 y(#"\\M-OD":)190 b(backward-char)195 +1447 y(#"\\M-OC":)g(forward-char)195 1499 y(#"\\M-OA":)g +(previous-history)195 1550 y(#"\\M-OB":)g(next-history)195 +1602 y(#)195 1654 y(#)24 b(Arrow)f(keys)g(in)h(ANSI)f(mode)195 +1706 y(#)195 1758 y("\\M-[D":)190 b(backward-char)195 +1810 y("\\M-[C":)g(forward-char)195 1862 y("\\M-[A":)g +(previous-history)195 1914 y("\\M-[B":)g(next-history)195 +1966 y(#)195 2017 y(#)24 b(Arrow)f(keys)g(in)h(8)g(bit)f(keypad)g(mode) +195 2069 y(#)195 2121 y(#"\\M-\\C-OD":)165 b(backward-char)195 +2173 y(#"\\M-\\C-OC":)g(forward-char)195 2225 y(#"\\M-\\C-OA":)g +(previous-history)195 2277 y(#"\\M-\\C-OB":)g(next-history)195 +2329 y(#)195 2381 y(#)24 b(Arrow)f(keys)g(in)h(8)g(bit)f(ANSI)g(mode) +195 2433 y(#)195 2484 y(#"\\M-\\C-[D":)165 b(backward-char)195 +2536 y(#"\\M-\\C-[C":)g(forward-char)195 2588 y(#"\\M-\\C-[A":)g +(previous-history)195 2640 y(#"\\M-\\C-[B":)g(next-history)p +eop +%%Page: 11 13 +11 12 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(11)195 201 y Ft(C-q:)23 b(quoted-insert)195 305 y($endif)195 +409 y(#)h(An)f(old-style)g(binding.)47 b(This)23 b(happens)g(to)g(be)h +(the)f(default.)195 461 y(TAB:)g(complete)195 565 y(#)h(Macros)f(that)g +(are)h(convenient)e(for)h(shell)h(interaction)195 616 +y($if)f(Bash)195 668 y(#)h(edit)f(the)g(path)195 720 +y("\\C-xp":)g("PATH=${PATH}\\e\\C-e\\C-a\\)o(ef\\C-f")195 +772 y(#)h(prepare)f(to)g(type)h(a)f(quoted)g(word)h(--)195 +824 y(#)g(insert)f(open)g(and)h(close)f(double)g(quotes)195 +876 y(#)h(and)f(move)g(to)h(just)f(after)h(the)f(open)g(quote)195 +928 y("\\C-x\\"":)g("\\"\\"\\C-b")195 980 y(#)h(insert)f(a)g(backslash) +g(\(testing)g(backslash)g(escapes)195 1032 y(#)h(in)f(sequences)g(and)g +(macros\))195 1083 y("\\C-x\\\\":)g("\\\\")195 1135 y(#)h(Quote)f(the)g +(current)g(or)h(previous)f(word)195 1187 y("\\C-xq":)g +("\\eb\\"\\ef\\"")195 1239 y(#)h(Add)f(a)h(binding)f(to)g(refresh)g +(the)h(line,)f(which)g(is)h(unbound)195 1291 y("\\C-xr":)f +(redraw-current-line)195 1343 y(#)h(Edit)f(variable)g(on)g(current)g +(line.)195 1395 y("\\M-\\C-v":)f("\\C-a\\C-k$\\C-y\\M-\\C-e\\C-a\\C-y=) +o(")195 1447 y($endif)195 1550 y(#)i(use)f(a)h(visible)f(bell)g(if)h +(one)f(is)h(available)195 1602 y(set)f(bell-style)g(visible)195 +1706 y(#)h(don't)f(strip)g(characters)g(to)g(7)h(bits)f(when)h(reading) +195 1758 y(set)f(input-meta)g(on)195 1862 y(#)h(allow)f(iso-latin1)f +(characters)h(to)g(be)h(inserted)f(rather)195 1914 y(#)h(than)f +(converted)g(to)g(prefix-meta)g(sequences)195 1966 y(set)g +(convert-meta)g(off)195 2069 y(#)h(display)f(characters)f(with)h(the)h +(eighth)f(bit)g(set)h(directly)195 2121 y(#)g(rather)f(than)g(as)h +(meta-prefixed)e(characters)195 2173 y(set)h(output-meta)g(on)195 +2277 y(#)h(if)f(there)g(are)h(more)f(than)h(150)f(possible)g +(completions)f(for)195 2329 y(#)i(a)f(word,)h(ask)f(the)h(user)f(if)g +(he)h(wants)f(to)h(see)f(all)h(of)f(them)195 2381 y(set)g +(completion-query-items)e(150)195 2484 y(#)j(For)f(FTP)195 +2536 y($if)g(Ftp)195 2588 y("\\C-xg":)g("get)g(\\M-?")195 +2640 y("\\C-xt":)g("put)g(\\M-?")p eop +%%Page: 12 14 +12 13 bop 75 -58 a Fu(12)1299 b(GNU)15 b(Readline)h(Library)195 +149 y Ft("\\M-.":)23 b(yank-last-arg)195 201 y($endif)75 +329 y Fs(1.4)33 b(Bindable)24 b(Readline)f(Commands)137 +425 y Fu(This)17 b(section)f(describ)q(es)h(Readline)g(commands)f(that) +e(ma)o(y)h(b)q(e)i(b)q(ound)f(to)f(k)o(ey)h(sequences.)22 +b(Com-)75 480 y(mand)15 b(names)g(without)h(an)f(accompan)o(ying)g(k)o +(ey)g(sequence)i(are)e(un)o(b)q(ound)h(b)o(y)f(default.)137 +547 y(In)f(the)f(follo)o(wing)h(descriptions,)h Fk(p)q(oin)o(t)f +Fu(refers)f(to)g(the)g(curren)o(t)g(cursor)f(p)q(osition,)j(and)e +Fk(mark)i Fu(refers)75 601 y(to)k(a)g(cursor)g(p)q(osition)h(sa)o(v)o +(ed)f(b)o(y)h(the)f Ft(set-mark)g Fu(command.)32 b(The)20 +b(text)f(b)q(et)o(w)o(een)g(the)h(p)q(oin)o(t)g(and)75 +656 y(mark)15 b(is)g(referred)h(to)e(as)h(the)g Fk(region)p +Fu(.)75 767 y Fj(1.4.1)30 b(Commands)21 b(F)-5 b(or)19 +b(Mo)n(ving)75 888 y Ft(beginning-of-line)13 b(\(C-a\))315 +942 y Fu(Mo)o(v)o(e)h(to)h(the)g(start)f(of)h(the)g(curren)o(t)g(line.) +75 1034 y Ft(end-of-line)f(\(C-e\))315 1088 y Fu(Mo)o(v)o(e)g(to)h(the) +g(end)h(of)f(the)g(line.)75 1179 y Ft(forward-char)f(\(C-f\))315 +1234 y Fu(Mo)o(v)o(e)g(forw)o(ard)g(a)h(c)o(haracter.)75 +1325 y Ft(backward-char)e(\(C-b\))315 1380 y Fu(Mo)o(v)o(e)h(bac)o(k)h +(a)g(c)o(haracter.)75 1471 y Ft(forward-word)f(\(M-f\))315 +1526 y Fu(Mo)o(v)o(e)g(forw)o(ard)g(to)g(the)i(end)g(of)e(the)h(next)h +(w)o(ord.)j(W)l(ords)c(are)f(comp)q(osed)i(of)f(letters)g(and)315 +1581 y(digits.)75 1672 y Ft(backward-word)e(\(M-b\))315 +1727 y Fu(Mo)o(v)o(e)j(bac)o(k)g(to)h(the)f(start)g(of)g(the)h(curren)o +(t)g(or)f(previous)i(w)o(ord.)24 b(W)l(ords)16 b(are)h(comp)q(osed)315 +1782 y(of)e(letters)g(and)g(digits.)75 1873 y Ft(clear-screen)f +(\(C-l\))315 1928 y Fu(Clear)f(the)h(screen)g(and)f(redra)o(w)g(the)g +(curren)o(t)g(line,)i(lea)o(ving)g(the)e(curren)o(t)g(line)i(at)e(the)g +(top)315 1982 y(of)i(the)g(screen.)75 2074 y Ft(redraw-current-line)e +(\(\))315 2128 y Fu(Refresh)i(the)g(curren)o(t)g(line.)22 +b(By)15 b(default,)h(this)f(is)h(un)o(b)q(ound.)75 2239 +y Fj(1.4.2)30 b(Commands)21 b(F)-5 b(or)19 b(Manipulating)i(The)f +(History)75 2360 y Ft(accept-line)14 b(\(Newline)g(or)h(Return\))315 +2414 y Fu(Accept)j(the)g(line)h(regardless)f(of)f(where)h(the)g(cursor) +f(is.)27 b(If)18 b(this)g(line)h(is)g(non-empt)o(y)l(,)f(it)315 +2469 y(ma)o(y)d(b)q(e)i(added)f(to)g(the)g(history)g(list)g(for)g +(future)g(recall)h(with)f Ft(add_history\(\))p Fu(.)k(If)d(this)315 +2524 y(line)g(is)f(a)e(mo)q(di\014ed)j(history)e(line,)i(the)e(history) +g(line)i(is)f(restored)e(to)h(its)g(original)i(state.)75 +2615 y Ft(previous-history)c(\(C-p\))315 2670 y Fu(Mo)o(v)o(e)h(`bac)o +(k')h(through)f(the)i(history)f(list,)g(fetc)o(hing)h(the)f(previous)h +(command.)p eop +%%Page: 13 15 +13 14 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(13)75 149 y Ft(next-history)14 b(\(C-n\))315 204 y +Fu(Mo)o(v)o(e)g(`forw)o(ard')f(through)i(the)h(history)f(list,)g(fetc)o +(hing)h(the)f(next)h(command.)75 307 y Ft(beginning-of-history)c +(\(M-<\))315 362 y Fu(Mo)o(v)o(e)i(to)h(the)g(\014rst)g(line)i(in)f +(the)f(history)l(.)75 465 y Ft(end-of-history)e(\(M->\))315 +520 y Fu(Mo)o(v)o(e)h(to)h(the)g(end)h(of)f(the)g(input)h(history)l(,)f +(i.e.,)g(the)g(line)i(curren)o(tly)f(b)q(eing)g(en)o(tered.)75 +624 y Ft(reverse-search-history)c(\(C-r\))315 678 y Fu(Searc)o(h)k(bac) +o(kw)o(ard)e(starting)h(at)g(the)h(curren)o(t)f(line)j(and)d(mo)o(ving) +h(`up')f(through)g(the)h(his-)315 733 y(tory)e(as)h(necessary)l(.)20 +b(This)c(is)g(an)f(incremen)o(tal)h(searc)o(h.)75 836 +y Ft(forward-search-history)c(\(C-s\))315 891 y Fu(Searc)o(h)j(forw)o +(ard)e(starting)h(at)h(the)f(curren)o(t)h(line)h(and)f(mo)o(ving)g(`do) +o(wn')f(through)g(the)h(the)315 946 y(history)g(as)g(necessary)l(.)20 +b(This)c(is)g(an)f(incremen)o(tal)h(searc)o(h.)75 1049 +y Ft(non-incremental-reverse-se)o(arch-hi)o(story)c(\(M-p\))315 +1104 y Fu(Searc)o(h)k(bac)o(kw)o(ard)e(starting)h(at)g(the)h(curren)o +(t)f(line)j(and)d(mo)o(ving)h(`up')f(through)g(the)h(his-)315 +1159 y(tory)h(as)h(necessary)g(using)h(a)e(non-incremen)o(tal)j(searc)o +(h)e(for)f(a)h(string)g(supplied)i(b)o(y)e(the)315 1214 +y(user.)75 1317 y Ft(non-incremental-forward-se)o(arch-hi)o(story)12 +b(\(M-n\))315 1372 y Fu(Searc)o(h)j(forw)o(ard)e(starting)h(at)h(the)f +(curren)o(t)h(line)h(and)f(mo)o(ving)g(`do)o(wn')f(through)g(the)h(the) +315 1426 y(history)e(as)g(necessary)h(using)g(a)f(non-incremen)o(tal)i +(searc)o(h)e(for)g(a)g(string)g(supplied)j(b)o(y)d(the)315 +1481 y(user.)75 1584 y Ft(history-search-forward)f(\(\))315 +1639 y Fu(Searc)o(h)21 b(forw)o(ard)e(through)i(the)f(history)h(for)f +(the)h(string)g(of)f(c)o(haracters)g(b)q(et)o(w)o(een)h(the)315 +1694 y(start)16 b(of)h(the)h(curren)o(t)g(line)h(and)e(the)h(p)q(oin)o +(t.)28 b(This)18 b(is)g(a)f(non-incremen)o(tal)i(searc)o(h.)27 +b(By)315 1749 y(default,)15 b(this)h(command)f(is)h(un)o(b)q(ound.)75 +1852 y Ft(history-search-backward)c(\(\))315 1907 y Fu(Searc)o(h)18 +b(bac)o(kw)o(ard)e(through)h(the)h(history)f(for)g(the)g(string)h(of)f +(c)o(haracters)f(b)q(et)o(w)o(een)i(the)315 1962 y(start)e(of)h(the)h +(curren)o(t)g(line)h(and)e(the)h(p)q(oin)o(t.)28 b(This)18 +b(is)g(a)f(non-incremen)o(tal)i(searc)o(h.)27 b(By)315 +2016 y(default,)15 b(this)h(command)f(is)h(un)o(b)q(ound.)75 +2120 y Ft(yank-nth-arg)e(\(M-C-y\))315 2174 y Fu(Insert)f(the)g +(\014rst)g(argumen)o(t)f(to)g(the)i(previous)f(command)g(\(usually)h +(the)f(second)h(w)o(ord)e(on)315 2229 y(the)j(previous)h(line\))g(at)e +(p)q(oin)o(t.)21 b(With)15 b(an)g(argumen)o(t)f Fk(n)p +Fu(,)h(insert)g(the)g Fk(n)p Fu(th)g(w)o(ord)g(from)f(the)315 +2284 y(previous)g(command)g(\(the)f(w)o(ords)f(in)j(the)e(previous)i +(command)e(b)q(egin)i(with)e(w)o(ord)g(0\).)19 b(A)315 +2339 y(negativ)o(e)13 b(argumen)o(t)f(inserts)h(the)g +Fk(n)p Fu(th)g(w)o(ord)f(from)g(the)h(end)h(of)e(the)h(previous)g +(command.)75 2442 y Ft(yank-last-arg)g(\(M-.)i(or)g(M-_\))315 +2497 y Fu(Insert)j(last)f(argumen)o(t)g(to)g(the)g(previous)i(command)e +(\(the)g(last)h(w)o(ord)f(of)g(the)g(previous)315 2552 +y(history)e(en)o(try\).)20 b(With)15 b(an)g(argumen)o(t,)g(b)q(eha)o(v) +o(e)g(exactly)h(lik)o(e)g Ft(yank-nth-arg)p Fu(.)j(Succes-)315 +2606 y(siv)o(e)f(calls)g(to)f Ft(yank-last-arg)e Fu(mo)o(v)o(e)i(bac)o +(k)g(through)g(the)g(history)g(list,)i(inserting)f(the)315 +2661 y(last)d(argumen)o(t)g(of)f(eac)o(h)i(line)g(in)g(turn.)p +eop +%%Page: 14 16 +14 15 bop 75 -58 a Fu(14)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fj(1.4.3)30 b(Commands)21 b(F)-5 b(or)19 b(Changing)i(T)-5 +b(ext)75 286 y Ft(delete-char)14 b(\(C-d\))315 341 y +Fu(Delete)20 b(the)g(c)o(haracter)e(at)h(p)q(oin)o(t.)33 +b(If)20 b(p)q(oin)o(t)g(is)g(at)e(the)i(b)q(eginning)i(of)d(the)g +(line,)j(there)315 396 y(are)c(no)h(c)o(haracters)e(in)j(the)e(line,)j +(and)e(the)f(last)h(c)o(haracter)e(t)o(yp)q(ed)i(w)o(as)f(not)g(b)q +(ound)i(to)315 450 y Ft(delete-char)p Fu(,)13 b(then)j(return)f +Fp(eof)p Fu(.)75 552 y Ft(backward-delete-char)d(\(Rubout\))315 +607 y Fu(Delete)k(the)f(c)o(haracter)f(b)q(ehind)j(the)f(cursor.)j(A)c +(n)o(umeric)h(argumen)o(t)e(means)i(to)e(kill)j(the)315 +661 y(c)o(haracters)d(instead)i(of)f(deleting)i(them.)75 +763 y Ft(forward-backward-delete-ch)o(ar)12 b(\(\))315 +818 y Fu(Delete)20 b(the)f(c)o(haracter)f(under)i(the)f(cursor,)h +(unless)g(the)f(cursor)g(is)h(at)e(the)h(end)h(of)f(the)315 +872 y(line,)e(in)g(whic)o(h)g(case)e(the)h(c)o(haracter)g(b)q(ehind)h +(the)f(cursor)g(is)g(deleted.)23 b(By)16 b(default,)h(this)315 +927 y(is)f(not)f(b)q(ound)h(to)e(a)h(k)o(ey)l(.)75 1029 +y Ft(quoted-insert)e(\(C-q)i(or)g(C-v\))315 1083 y Fu(Add)j(the)f(next) +g(c)o(haracter)g(t)o(yp)q(ed)g(to)f(the)i(line)g(v)o(erbatim.)26 +b(This)18 b(is)f(ho)o(w)g(to)g(insert)g(k)o(ey)315 1138 +y(sequences)f(lik)o(e)h Fo(C-q)p Fu(,)d(for)h(example.)75 +1240 y Ft(tab-insert)f(\(M-)401 1238 y Fn(h)p 412 1212 +74 2 v 412 1240 a Fm(T)m(AB)p 412 1247 V 484 1238 a Fn(i)499 +1240 y Ft(\))315 1294 y Fu(Insert)h(a)g(tab)g(c)o(haracter.)75 +1396 y Ft(self-insert)f(\(a,)g(b,)h(A,)g(1,)g(!,)g(...)o(\))315 +1451 y Fu(Insert)g(y)o(ourself.)75 1552 y Ft(transpose-chars)e(\(C-t\)) +315 1607 y Fu(Drag)i(the)h(c)o(haracter)f(b)q(efore)h(the)h(cursor)e +(forw)o(ard)g(o)o(v)o(er)g(the)h(c)o(haracter)f(at)h(the)g(cursor,)315 +1662 y(mo)o(ving)i(the)f(cursor)h(forw)o(ard)e(as)i(w)o(ell.)28 +b(If)18 b(the)g(insertion)h(p)q(oin)o(t)f(is)g(at)f(the)h(end)h(of)e +(the)315 1716 y(line,)c(then)e(this)h(transp)q(oses)e(the)h(last)g(t)o +(w)o(o)f(c)o(haracters)g(of)h(the)g(line.)20 b(Negativ)o(e)11 +b(argumen)o(ts)315 1771 y(ha)o(v)o(e)k(no)g(e\013ect.)75 +1873 y Ft(transpose-words)e(\(M-t\))315 1927 y Fu(Drag)i(the)h(w)o(ord) +g(b)q(efore)g(p)q(oin)o(t)h(past)f(the)g(w)o(ord)f(after)h(p)q(oin)o +(t,)g(mo)o(ving)g(p)q(oin)o(t)h(past)f(that)315 1982 +y(w)o(ord)d(as)h(w)o(ell.)21 b(If)14 b(the)g(insertion)i(p)q(oin)o(t)e +(is)h(at)f(the)g(end)h(of)e(the)i(line,)g(this)g(transp)q(oses)f(the) +315 2037 y(last)h(t)o(w)o(o)f(w)o(ords)g(on)i(the)f(line.)75 +2138 y Ft(upcase-word)f(\(M-u\))315 2193 y Fu(Upp)q(ercase)j(the)f +(curren)o(t)g(\(or)f(follo)o(wing\))h(w)o(ord.)22 b(With)16 +b(a)g(negativ)o(e)g(argumen)o(t,)f(upp)q(er-)315 2248 +y(case)g(the)g(previous)h(w)o(ord,)f(but)g(do)g(not)g(mo)o(v)o(e)f(the) +i(cursor.)75 2349 y Ft(downcase-word)d(\(M-l\))315 2404 +y Fu(Lo)o(w)o(ercase)d(the)h(curren)o(t)g(\(or)f(follo)o(wing\))h(w)o +(ord.)17 b(With)11 b(a)g(negativ)o(e)g(argumen)o(t,)f(lo)o(w)o(ercase) +315 2459 y(the)15 b(previous)h(w)o(ord,)e(but)i(do)f(not)g(mo)o(v)o(e)f +(the)h(cursor.)75 2560 y Ft(capitalize-word)e(\(M-c\))315 +2615 y Fu(Capitalize)f(the)f(curren)o(t)f(\(or)g(follo)o(wing\))h(w)o +(ord.)18 b(With)11 b(a)f(negativ)o(e)h(argumen)o(t,)f(capitalize)315 +2670 y(the)15 b(previous)h(w)o(ord,)e(but)i(do)f(not)g(mo)o(v)o(e)f +(the)h(cursor.)p eop +%%Page: 15 17 +15 16 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(15)75 149 y Ft(overwrite-mode)13 b(\(\))315 204 y Fu(T)l(oggle)j(o)o +(v)o(erwrite)g(mo)q(de.)24 b(With)17 b(an)f(explicit)j(p)q(ositiv)o(e)f +(n)o(umeric)f(argumen)o(t,)f(switc)o(hes)315 259 y(to)10 +b(o)o(v)o(erwrite)g(mo)q(de.)19 b(With)11 b(an)g(explicit)i(non-p)q +(ositiv)o(e)f(n)o(umeric)g(argumen)o(t,)e(switc)o(hes)i(to)315 +314 y(insert)k(mo)q(de.)k(This)c(command)f(a\013ects)g(only)h +Ft(emacs)e Fu(mo)q(de;)h Ft(vi)g Fu(mo)q(de)h(do)q(es)g(o)o(v)o +(erwrite)315 369 y(di\013eren)o(tly)l(.)21 b(Eac)o(h)15 +b(call)h(to)f Ft(readline\(\))f Fu(starts)f(in)k(insert)e(mo)q(de.)315 +436 y(In)g(o)o(v)o(erwrite)f(mo)q(de,)h(c)o(haracters)f(b)q(ound)h(to)f +Ft(self-insert)f Fu(replace)j(the)e(text)h(at)e(p)q(oin)o(t)315 +491 y(rather)20 b(than)h(pushing)h(the)f(text)f(to)g(the)h(righ)o(t.)36 +b(Characters)20 b(b)q(ound)i(to)e Ft(backward-)315 546 +y(delete-char)14 b Fu(replace)i(the)f(c)o(haracter)g(b)q(efore)g(p)q +(oin)o(t)h(with)f(a)g(space.)315 614 y(By)g(default,)h(this)f(command)g +(is)h(un)o(b)q(ound.)75 729 y Fj(1.4.4)30 b(Killing)20 +b(And)h(Y)-5 b(anking)75 853 y Ft(kill-line)14 b(\(C-k\))315 +908 y Fu(Kill)j(the)f(text)e(from)h(p)q(oin)o(t)h(to)e(the)h(end)h(of)f +(the)g(line.)75 1002 y Ft(backward-kill-line)e(\(C-x)h(Rubout\))315 +1057 y Fu(Kill)j(bac)o(kw)o(ard)e(to)f(the)i(b)q(eginning)h(of)e(the)g +(line.)75 1151 y Ft(unix-line-discard)e(\(C-u\))315 1205 +y Fu(Kill)k(bac)o(kw)o(ard)e(from)f(the)i(cursor)e(to)h(the)g(b)q +(eginning)j(of)c(the)i(curren)o(t)f(line.)75 1299 y Ft(kill-whole-line) +e(\(\))315 1354 y Fu(Kill)20 b(all)g(c)o(haracters)d(on)h(the)h(curren) +o(t)f(line,)i(no)e(matter)g(where)g(p)q(oin)o(t)h(is.)29 +b(By)19 b(default,)315 1409 y(this)d(is)f(un)o(b)q(ound.)75 +1503 y Ft(kill-word)f(\(M-d\))315 1558 y Fu(Kill)j(from)d(p)q(oin)o(t)h +(to)f(the)h(end)g(of)f(the)h(curren)o(t)g(w)o(ord,)e(or)i(if)g(b)q(et)o +(w)o(een)g(w)o(ords,)e(to)i(the)f(end)315 1613 y(of)h(the)g(next)g(w)o +(ord.)20 b(W)l(ord)14 b(b)q(oundaries)j(are)e(the)g(same)g(as)g +Ft(forward-word)p Fu(.)75 1707 y Ft(backward-kill-word)e(\(M-)592 +1705 y Fn(h)p 603 1679 73 2 v 603 1707 a Fm(DEL)p 603 +1714 V 674 1705 a Fn(i)689 1707 y Ft(\))315 1761 y Fu(Kill)k(the)d(w)o +(ord)g(b)q(ehind)i(p)q(oin)o(t.)21 b(W)l(ord)14 b(b)q(oundaries)h(are)f +(the)h(same)f(as)g Ft(backward-word)p Fu(.)75 1855 y +Ft(unix-word-rubout)f(\(C-w\))315 1910 y Fu(Kill)18 b(the)e(w)o(ord)f +(b)q(ehind)j(p)q(oin)o(t,)e(using)h(white)f(space)g(as)g(a)f(w)o(ord)g +(b)q(oundary)l(.)23 b(The)16 b(killed)315 1965 y(text)f(is)g(sa)o(v)o +(ed)g(on)g(the)h(kill-ring.)75 2059 y Ft(delete-horizontal-space)c +(\(\))315 2114 y Fu(Delete)k(all)g(spaces)f(and)h(tabs)e(around)i(p)q +(oin)o(t.)k(By)15 b(default,)h(this)f(is)h(un)o(b)q(ound.)75 +2208 y Ft(kill-region)e(\(\))315 2263 y Fu(Kill)j(the)f(text)e(in)i +(the)g(curren)o(t)f(region.)20 b(By)15 b(default,)h(this)f(command)g +(is)h(un)o(b)q(ound.)75 2357 y Ft(copy-region-as-kill)d(\(\))315 +2412 y Fu(Cop)o(y)j(the)i(text)e(in)i(the)f(region)g(to)g(the)g(kill)h +(bu\013er,)f(so)g(it)g(can)g(b)q(e)h(y)o(ank)o(ed)f(righ)o(t)g(a)o(w)o +(a)o(y)l(.)315 2466 y(By)e(default,)h(this)f(command)g(is)h(un)o(b)q +(ound.)75 2560 y Ft(copy-backward-word)d(\(\))315 2615 +y Fu(Cop)o(y)19 b(the)g(w)o(ord)g(b)q(efore)g(p)q(oin)o(t)h(to)e(the)i +(kill)h(bu\013er.)32 b(The)19 b(w)o(ord)g(b)q(oundaries)h(are)f(the)315 +2670 y(same)c(as)g Ft(backward-word)p Fu(.)j(By)d(default,)g(this)h +(command)f(is)h(un)o(b)q(ound.)p eop +%%Page: 16 18 +16 17 bop 75 -58 a Fu(16)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Ft(copy-forward-word)d(\(\))315 204 y Fu(Cop)o(y)i(the)h(w)o(ord) +e(follo)o(wing)j(p)q(oin)o(t)f(to)f(the)g(kill)j(bu\013er.)i(The)c(w)o +(ord)f(b)q(oundaries)i(are)e(the)315 259 y(same)g(as)g +Ft(forward-word)p Fu(.)j(By)d(default,)h(this)f(command)g(is)h(un)o(b)q +(ound.)75 342 y Ft(yank)f(\(C-y\))315 397 y Fu(Y)l(ank)g(the)h(top)f +(of)f(the)i(kill)h(ring)e(in)o(to)g(the)h(bu\013er)f(at)f(p)q(oin)o(t.) +75 481 y Ft(yank-pop)g(\(M-y\))315 535 y Fu(Rotate)i(the)h(kill-ring,)j +(and)d(y)o(ank)g(the)h(new)f(top.)26 b(Y)l(ou)17 b(can)h(only)g(do)f +(this)h(if)f(the)h(prior)315 590 y(command)d(is)h Ft(yank)e +Fu(or)h Ft(yank-pop)p Fu(.)75 693 y Fj(1.4.5)30 b(Sp)r(ecifying)20 +b(Numeric)h(Argumen)n(ts)75 806 y Ft(digit-argument)13 +b(\()p Fo(M-0)p Ft(,)i Fo(M-1)p Ft(,)f(...)h Fo(M--)p +Ft(\))315 861 y Fu(Add)f(this)g(digit)g(to)f(the)h(argumen)o(t)e +(already)i(accum)o(ulating,)g(or)f(start)f(a)h(new)h(argumen)o(t.)315 +915 y Fo(M--)h Fu(starts)f(a)h(negativ)o(e)g(argumen)o(t.)75 +999 y Ft(universal-argument)e(\(\))315 1054 y Fu(This)g(is)h(another)e +(w)o(a)o(y)g(to)g(sp)q(ecify)i(an)f(argumen)o(t.)18 b(If)13 +b(this)g(command)g(is)g(follo)o(w)o(ed)g(b)o(y)g(one)315 +1108 y(or)h(more)h(digits,)g(optionally)h(with)f(a)g(leading)h(min)o +(us)f(sign,)g(those)g(digits)g(de\014ne)h(the)f(ar-)315 +1163 y(gumen)o(t.)k(If)c(the)g(command)f(is)h(follo)o(w)o(ed)g(b)o(y)g +(digits,)g(executing)g Ft(universal-argument)315 1218 +y Fu(again)h(ends)g(the)g(n)o(umeric)h(argumen)o(t,)e(but)h(is)h +(otherwise)f(ignored.)22 b(As)16 b(a)g(sp)q(ecial)h(case,)315 +1273 y(if)g(this)g(command)f(is)h(immediately)h(follo)o(w)o(ed)f(b)o(y) +f(a)g(c)o(haracter)g(that)g(is)h(neither)g(a)f(digit)315 +1328 y(or)d(min)o(us)i(sign,)f(the)g(argumen)o(t)g(coun)o(t)f(for)h +(the)g(next)g(command)g(is)g(m)o(ultiplied)j(b)o(y)d(four.)315 +1382 y(The)19 b(argumen)o(t)f(coun)o(t)g(is)h(initially)j(one,)d(so)f +(executing)i(this)f(function)h(the)e(\014rst)h(time)315 +1437 y(mak)o(es)c(the)h(argumen)o(t)f(coun)o(t)h(four,)f(a)h(second)g +(time)g(mak)o(es)g(the)g(argumen)o(t)f(coun)o(t)g(six-)315 +1492 y(teen,)g(and)g(so)g(on.)20 b(By)15 b(default,)h(this)f(is)h(not)f +(b)q(ound)h(to)f(a)g(k)o(ey)l(.)75 1595 y Fj(1.4.6)30 +b(Letting)20 b(Readline)g(T)n(yp)r(e)h(F)-5 b(or)19 b(Y)-5 +b(ou)75 1708 y Ft(complete)14 b(\()305 1706 y Fn(h)p +317 1680 74 2 v 317 1708 a Fm(T)m(AB)p 317 1715 V 389 +1706 a Fn(i)404 1708 y Ft(\))315 1762 y Fu(A)o(ttempt)c(to)h(p)q +(erform)g(completion)i(on)e(the)g(text)g(b)q(efore)h(p)q(oin)o(t.)19 +b(The)11 b(actual)h(completion)315 1817 y(p)q(erformed)j(is)h +(application-sp)q(eci\014)q(c.)23 b(The)15 b(default)h(is)g(\014lename) +g(completion.)75 1901 y Ft(possible-completions)c(\(M-?\))315 +1955 y Fu(List)k(the)f(p)q(ossible)i(completions)f(of)f(the)g(text)g(b) +q(efore)h(p)q(oin)o(t.)75 2039 y Ft(insert-completions)d(\(M-*\))315 +2093 y Fu(Insert)j(all)g(completions)g(of)f(the)g(text)g(b)q(efore)h(p) +q(oin)o(t)f(that)g(w)o(ould)h(ha)o(v)o(e)f(b)q(een)h(generated)315 +2148 y(b)o(y)f Ft(possible-completions)p Fu(.)75 2232 +y Ft(menu-complete)e(\(\))315 2286 y Fu(Similar)g(to)f +Ft(complete)p Fu(,)f(but)h(replaces)h(the)f(w)o(ord)f(to)g(b)q(e)i +(completed)f(with)h(a)e(single)j(matc)o(h)315 2341 y(from)k(the)h(list) +h(of)e(p)q(ossible)j(completions.)32 b(Rep)q(eated)19 +b(execution)h(of)f Ft(menu-complete)315 2396 y Fu(steps)h(through)g +(the)g(list)h(of)f(p)q(ossible)i(completions,)g(inserting)f(eac)o(h)f +(matc)o(h)f(in)i(turn.)315 2451 y(A)o(t)d(the)g(end)h(of)f(the)h(list)g +(of)f(completions,)i(the)e(b)q(ell)j(is)d(rung)h(\(sub)s(ject)f(to)f +(the)i(setting)315 2506 y(of)f Ft(bell-style)p Fu(\))e(and)i(the)g +(original)h(text)f(is)g(restored.)28 b(An)19 b(argumen)o(t)e(of)g +Fk(n)i Fu(mo)o(v)o(es)e Fk(n)315 2560 y Fu(p)q(ositions)h(forw)o(ard)e +(in)j(the)e(list)h(of)f(matc)o(hes;)h(a)f(negativ)o(e)g(argumen)o(t)g +(ma)o(y)g(b)q(e)h(used)g(to)315 2615 y(mo)o(v)o(e)g(bac)o(kw)o(ard)h +(through)g(the)g(list.)32 b(This)20 b(command)f(is)h(in)o(tended)g(to)f +(b)q(e)h(b)q(ound)g(to)315 2668 y Fn(h)p 327 2642 V 327 +2670 a Fm(T)m(AB)p 327 2678 V 399 2668 a Fn(i)414 2670 +y Fu(,)15 b(but)g(is)h(un)o(b)q(ound)g(b)o(y)f(default.)p +eop +%%Page: 17 19 +17 18 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(17)75 149 y Ft(delete-char-or-list)13 b(\(\))315 204 +y Fu(Deletes)h(the)f(c)o(haracter)g(under)h(the)g(cursor)f(if)h(not)f +(at)g(the)g(b)q(eginning)j(or)d(end)h(of)f(the)g(line)315 +259 y(\(lik)o(e)i Ft(delete-char)p Fu(\).)j(If)d(at)f(the)h(end)g(of)f +(the)g(line,)i(b)q(eha)o(v)o(es)f(iden)o(tically)i(to)d +Ft(possible-)315 314 y(completions)p Fu(.)k(This)e(command)f(is)h(un)o +(b)q(ound)g(b)o(y)f(default.)75 428 y Fj(1.4.7)30 b(Keyb)r(oard)20 +b(Macros)75 551 y Ft(start-kbd-macro)13 b(\(C-x)i(\(\))315 +606 y Fu(Begin)h(sa)o(ving)f(the)h(c)o(haracters)e(t)o(yp)q(ed)i(in)o +(to)f(the)g(curren)o(t)g(k)o(eyb)q(oard)g(macro.)75 699 +y Ft(end-kbd-macro)e(\(C-x)i(\)\))315 754 y Fu(Stop)f(sa)o(ving)f(the)h +(c)o(haracters)f(t)o(yp)q(ed)h(in)o(to)f(the)h(curren)o(t)g(k)o(eyb)q +(oard)f(macro)g(and)h(sa)o(v)o(e)f(the)315 809 y(de\014nition.)75 +902 y Ft(call-last-kbd-macro)g(\(C-x)h(e\))315 957 y +Fu(Re-execute)k(the)g(last)f(k)o(eyb)q(oard)h(macro)f(de\014ned,)i(b)o +(y)e(making)h(the)g(c)o(haracters)e(in)j(the)315 1012 +y(macro)14 b(app)q(ear)i(as)f(if)g(t)o(yp)q(ed)h(at)e(the)i(k)o(eyb)q +(oard.)75 1126 y Fj(1.4.8)30 b(Some)20 b(Miscellaneous)h(Commands)75 +1249 y Ft(re-read-init-file)13 b(\(C-x)h(C-r\))315 1304 +y Fu(Read)d(in)g(the)g(con)o(ten)o(ts)g(of)f(the)h Fk(inputrc)k +Fu(\014le,)d(and)g(incorp)q(orate)f(an)o(y)f(bindings)j(or)e(v)m +(ariable)315 1358 y(assignmen)o(ts)k(found)h(there.)75 +1452 y Ft(abort)e(\(C-g\))315 1507 y Fu(Ab)q(ort)f(the)g(curren)o(t)h +(editing)g(command)f(and)h(ring)f(the)h(terminal's)f(b)q(ell)i(\(sub)s +(ject)e(to)g(the)315 1561 y(setting)i(of)g Ft(bell-style)p +Fu(\).)75 1655 y Ft(do-uppercase-version)d(\(M-a,)j(M-b,)f(M-)p +Fk(x)p Ft(,)h(...\))315 1710 y Fu(If)f(the)g(meta\014ed)g(c)o(haracter) +f Fk(x)k Fu(is)d(lo)o(w)o(ercase,)g(run)g(the)g(command)f(that)h(is)g +(b)q(ound)h(to)e(the)315 1764 y(corresp)q(onding)j(upp)q(ercase)g(c)o +(haracter.)75 1858 y Ft(prefix-meta)e(\()377 1856 y Fn(h)p +389 1830 70 2 v 389 1858 a Fm(ESC)p 389 1866 V 456 1856 +a Fn(i)471 1858 y Ft(\))315 1913 y Fu(Metafy)k(the)h(next)g(c)o +(haracter)f(t)o(yp)q(ed.)30 b(This)20 b(is)f(for)f(k)o(eyb)q(oards)h +(without)g(a)f(meta)g(k)o(ey)l(.)315 1968 y(T)o(yping)e(`)485 +1966 y Fn(h)p 496 1939 V 496 1968 a Fm(ESC)p 496 1975 +V 563 1966 a Fn(i)593 1968 y Ft(f)p Fu(')f(is)h(equiv)m(alen)o(t)h(to)d +(t)o(yping)i Fo(M-f)p Fu(.)75 2061 y Ft(undo)f(\(C-_)f(or)h(C-x)g +(C-u\))315 2116 y Fu(Incremen)o(tal)h(undo,)f(separately)h(remem)o(b)q +(ered)g(for)e(eac)o(h)h(line.)75 2209 y Ft(revert-line)f(\(M-r\))315 +2264 y Fu(Undo)j(all)g(c)o(hanges)g(made)f(to)g(this)h(line.)26 +b(This)17 b(is)g(lik)o(e)h(executing)f(the)g Ft(undo)f +Fu(command)315 2319 y(enough)g(times)f(to)g(get)f(bac)o(k)h(to)g(the)g +(b)q(eginning.)75 2412 y Ft(tilde-expand)f(\(M-~\))315 +2467 y Fu(P)o(erform)g(tilde)j(expansion)f(on)f(the)g(curren)o(t)g(w)o +(ord.)75 2560 y Ft(set-mark)f(\(C-@\))315 2615 y Fu(Set)i(the)h(mark)f +(to)f(the)i(p)q(oin)o(t.)24 b(If)17 b(a)f(n)o(umeric)h(argumen)o(t)f +(is)g(supplied,)j(the)e(mark)e(is)i(set)315 2670 y(to)e(that)f(p)q +(osition.)p eop +%%Page: 18 20 +18 19 bop 75 -58 a Fu(18)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Ft(exchange-point-and-mark)c(\(C-x)j(C-x\))315 +204 y Fu(Sw)o(ap)g(the)h(p)q(oin)o(t)g(with)g(the)g(mark.)k(The)c +(curren)o(t)f(cursor)h(p)q(osition)g(is)g(set)g(to)f(the)g(sa)o(v)o(ed) +315 259 y(p)q(osition,)h(and)f(the)h(old)f(cursor)g(p)q(osition)h(is)g +(sa)o(v)o(ed)f(as)g(the)g(mark.)75 347 y Ft(character-search)e(\(C-]\)) +315 402 y Fu(A)f(c)o(haracter)g(is)h(read)g(and)f(p)q(oin)o(t)h(is)g +(mo)o(v)o(ed)f(to)g(the)g(next)h(o)q(ccurrence)g(of)f(that)g(c)o +(haracter.)315 456 y(A)j(negativ)o(e)h(coun)o(t)f(searc)o(hes)g(for)f +(previous)i(o)q(ccurrences.)75 544 y Ft(character-search-backward)c +(\(M-C-]\))315 599 y Fu(A)22 b(c)o(haracter)g(is)h(read)f(and)h(p)q +(oin)o(t)g(is)g(mo)o(v)o(ed)f(to)g(the)g(previous)h(o)q(ccurrence)h(of) +e(that)315 654 y(c)o(haracter.)d(A)c(negativ)o(e)h(coun)o(t)f(searc)o +(hes)g(for)f(subsequen)o(t)i(o)q(ccurrences.)75 741 y +Ft(insert-comment)d(\(M-#\))315 796 y Fu(Without)18 b(a)f(n)o(umeric)i +(argumen)o(t,)e(the)h(v)m(alue)h(of)f(the)f Ft(comment-begin)f +Fu(v)m(ariable)k(is)e(in-)315 851 y(serted)e(at)f(the)h(b)q(eginning)i +(of)d(the)h(curren)o(t)g(line.)23 b(If)16 b(a)g(n)o(umeric)h(argumen)o +(t)e(is)h(supplied,)315 906 y(this)j(command)f(acts)g(as)f(a)h(toggle:) +26 b(if)19 b(the)f(c)o(haracters)g(at)f(the)i(b)q(eginning)h(of)e(the)g +(line)315 960 y(do)d(not)g(matc)o(h)g(the)g(v)m(alue)i(of)e +Ft(comment-begin)p Fu(,)e(the)i(v)m(alue)i(is)f(inserted,)f(otherwise)h +(the)315 1015 y(c)o(haracters)j(in)i Ft(comment-begin)d +Fu(are)i(deleted)i(from)d(the)h(b)q(eginning)i(of)e(the)g(line.)36 +b(In)315 1070 y(either)16 b(case,)f(the)g(line)i(is)f(accepted)f(as)g +(if)h(a)f(newline)i(had)e(b)q(een)i(t)o(yp)q(ed.)75 1158 +y Ft(dump-functions)c(\(\))315 1213 y Fu(Prin)o(t)g(all)h(of)f(the)g +(functions)h(and)g(their)g(k)o(ey)f(bindings)i(to)d(the)i(Readline)g +(output)f(stream.)315 1267 y(If)j(a)g(n)o(umeric)g(argumen)o(t)f(is)i +(supplied,)h(the)e(output)f(is)i(formatted)d(in)j(suc)o(h)f(a)g(w)o(a)o +(y)f(that)315 1322 y(it)g(can)h(b)q(e)g(made)f(part)f(of)h(an)g +Fk(inputrc)k Fu(\014le.)i(This)16 b(command)f(is)h(un)o(b)q(ound)g(b)o +(y)f(default.)75 1410 y Ft(dump-variables)e(\(\))315 +1465 y Fu(Prin)o(t)e(all)g(of)f(the)h(settable)g(v)m(ariables)h(and)f +(their)g(v)m(alues)h(to)e(the)h(Readline)h(output)e(stream.)315 +1519 y(If)16 b(a)g(n)o(umeric)g(argumen)o(t)f(is)i(supplied,)h(the)e +(output)f(is)i(formatted)d(in)j(suc)o(h)f(a)g(w)o(a)o(y)f(that)315 +1574 y(it)g(can)h(b)q(e)g(made)f(part)f(of)h(an)g Fk(inputrc)k +Fu(\014le.)i(This)16 b(command)f(is)h(un)o(b)q(ound)g(b)o(y)f(default.) +75 1662 y Ft(dump-macros)f(\(\))315 1717 y Fu(Prin)o(t)j(all)h(of)e +(the)h(Readline)h(k)o(ey)f(sequences)h(b)q(ound)g(to)e(macros)g(and)h +(the)g(strings)g(they)315 1771 y(output.)26 b(If)18 b(a)f(n)o(umeric)h +(argumen)o(t)f(is)h(supplied,)i(the)d(output)g(is)h(formatted)e(in)j +(suc)o(h)e(a)315 1826 y(w)o(a)o(y)d(that)g(it)i(can)f(b)q(e)g(made)g +(part)g(of)f(an)h Fk(inputrc)k Fu(\014le.)i(This)15 b(command)g(is)h +(un)o(b)q(ound)g(b)o(y)315 1881 y(default.)75 1969 y +Ft(emacs-editing-mode)d(\(C-e\))315 2024 y Fu(When)j(in)g +Ft(vi)e Fu(command)i(mo)q(de,)f(this)g(causes)h(a)f(switc)o(h)g(to)g +Ft(emacs)f Fu(editing)j(mo)q(de.)75 2111 y Ft(vi-editing-mode)c +(\(M-C-j\))315 2166 y Fu(When)j(in)g Ft(emacs)e Fu(editing)j(mo)q(de,)e +(this)g(causes)h(a)f(switc)o(h)g(to)g Ft(vi)f Fu(editing)j(mo)q(de.)75 +2290 y Fs(1.5)33 b(Readline)23 b(vi)h(Mo)r(de)137 2385 +y Fu(While)13 b(the)f(Readline)i(library)e(do)q(es)g(not)g(ha)o(v)o(e)f +(a)h(full)h(set)f(of)f Ft(vi)g Fu(editing)j(functions,)f(it)f(do)q(es)g +(con)o(tain)75 2440 y(enough)17 b(to)g(allo)o(w)g(simple)h(editing)h +(of)d(the)i(line.)27 b(The)17 b(Readline)h Ft(vi)f Fu(mo)q(de)g(b)q +(eha)o(v)o(es)g(as)g(sp)q(eci\014ed)i(in)75 2495 y(the)c +Fp(posix)g Fu(1003.2)f(standard.)137 2560 y(In)h(order)g(to)f(switc)o +(h)g(in)o(teractiv)o(ely)i(b)q(et)o(w)o(een)f Ft(emacs)e +Fu(and)i Ft(vi)f Fu(editing)i(mo)q(des,)f(use)f(the)h(command)75 +2615 y Fo(M-C-j)j Fu(\(b)q(ound)i(to)e(emacs-editing-mo)q(de)j(when)e +(in)h Ft(vi)f Fu(mo)q(de)g(and)g(to)f(vi-editing-mo)q(de)k(in)e +Ft(emacs)75 2670 y Fu(mo)q(de\).)g(The)15 b(Readline)i(default)f(is)f +Ft(emacs)g Fu(mo)q(de.)p eop +%%Page: 19 21 +19 20 bop 75 -58 a Fu(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(19)137 149 y(When)16 b(y)o(ou)e(en)o(ter)h(a)g(line)i(in)e +Ft(vi)g Fu(mo)q(de,)g(y)o(ou)g(are)f(already)i(placed)g(in)g +(`insertion')f(mo)q(de,)g(as)g(if)g(y)o(ou)75 204 y(had)e(t)o(yp)q(ed)h +(an)f(`)p Ft(i)p Fu('.)18 b(Pressing)608 202 y Fn(h)p +620 176 70 2 v 620 204 a Fm(ESC)p 620 212 V 687 202 a +Fn(i)715 204 y Fu(switc)o(hes)13 b(y)o(ou)g(in)o(to)g(`command')f(mo)q +(de,)i(where)f(y)o(ou)g(can)g(edit)h(the)75 259 y(text)i(of)h(the)g +(line)h(with)g(the)f(standard)f Ft(vi)h Fu(mo)o(v)o(emen)o(t)f(k)o +(eys,)g(mo)o(v)o(e)g(to)h(previous)g(history)g(lines)i(with)75 +314 y(`)p Ft(k)p Fu(')14 b(and)i(subsequen)o(t)f(lines)i(with)f(`)p +Ft(j)p Fu(',)e(and)h(so)g(forth.)p eop +%%Page: 20 22 +20 21 bop 75 -58 a Fu(20)1299 b(GNU)15 b(Readline)h(Library)p +eop +%%Page: 21 23 +21 22 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(21)75 149 y Fq(2)41 b(Programming)28 +b(with)e(GNU)i(Readline)137 267 y Fu(This)18 b(c)o(hapter)f(describ)q +(es)h(the)f(in)o(terface)g(b)q(et)o(w)o(een)h(the)f Fp(gnu)g +Fu(Readline)h(Library)f(and)g(other)g(pro-)75 322 y(grams.)h(If)11 +b(y)o(ou)g(are)g(a)g(programmer,)f(and)i(y)o(ou)f(wish)g(to)g(include)j +(the)d(features)g(found)g(in)i Fp(gnu)e Fu(Readline)75 +377 y(suc)o(h)h(as)f(completion,)h(line)h(editing,)g(and)f(in)o +(teractiv)o(e)g(history)f(manipulation)i(in)f(y)o(our)f(o)o(wn)g +(programs,)75 432 y(this)16 b(section)f(is)h(for)f(y)o(ou.)75 +561 y Fs(2.1)33 b(Basic)22 b(Beha)n(vior)137 658 y Fu(Man)o(y)15 +b(programs)f(pro)o(vide)i(a)f(command)g(line)i(in)o(terface,)e(suc)o(h) +h(as)f Ft(mail)p Fu(,)f Ft(ftp)p Fu(,)h(and)g Ft(sh)p +Fu(.)20 b(F)l(or)15 b(suc)o(h)75 713 y(programs,)e(the)h(default)h(b)q +(eha)o(viour)g(of)f(Readline)i(is)e(su\016cien)o(t.)21 +b(This)14 b(section)h(describ)q(es)h(ho)o(w)e(to)g(use)75 +768 y(Readline)k(in)h(the)e(simplest)h(w)o(a)o(y)e(p)q(ossible,)j(p)q +(erhaps)f(to)f(replace)h(calls)g(in)g(y)o(our)f(co)q(de)h(to)e +Ft(gets\(\))g Fu(or)75 822 y Ft(fgets\(\))p Fu(.)137 +890 y(The)h(function)g Ft(readline\(\))e Fu(prin)o(ts)h(a)g(prompt)g +Fk(prompt)h Fu(and)f(then)h(reads)f(and)h(returns)f(a)g(single)75 +945 y(line)i(of)e(text)g(from)f(the)i(user.)23 b(If)17 +b Fk(prompt)g Fu(is)g Ft(NULL)e Fu(or)h(the)h(empt)o(y)f(string,)g(no)g +(prompt)g(is)h(displa)o(y)o(ed.)75 1000 y(The)i(line)h +Ft(readline)d Fu(returns)i(is)g(allo)q(cated)g(with)g +Ft(malloc\(\))p Fu(;)g(the)g(caller)g(should)h Ft(free\(\))e +Fu(the)g(line)75 1054 y(when)e(it)f(has)g(\014nished)i(with)f(it.)k +(The)15 b(declaration)h(for)f Ft(readline)f Fu(in)i(ANSI)g(C)f(is)195 +1119 y Ft(char)23 b(*readline)g(\(const)g(char)g(*)p +Fk(prompt)q Ft(\);)75 1187 y Fu(So,)15 b(one)g(migh)o(t)g(sa)o(y)195 +1251 y Ft(char)23 b(*line)g(=)h(readline)f(\("Enter)g(a)h(line:)f("\);) +75 1319 y Fu(in)12 b(order)f(to)g(read)h(a)f(line)i(of)e(text)g(from)f +(the)i(user.)19 b(The)11 b(line)j(returned)d(has)h(the)f(\014nal)h +(newline)i(remo)o(v)o(ed,)75 1374 y(so)h(only)h(the)f(text)g(remains.) +137 1441 y(If)21 b Ft(readline)e Fu(encoun)o(ters)h(an)g +Ft(EOF)g Fu(while)i(reading)f(the)f(line,)j(and)d(the)h(line)g(is)g +(empt)o(y)f(at)g(that)75 1496 y(p)q(oin)o(t,)15 b(then)g +Ft(\(char)f(*\)NULL)g Fu(is)h(returned.)21 b(Otherwise,)15 +b(the)g(line)h(is)f(ended)h(just)e(as)h(if)g(a)f(newline)j(had)75 +1551 y(b)q(een)f(t)o(yp)q(ed.)137 1618 y(If)d(y)o(ou)g(w)o(an)o(t)f +(the)h(user)g(to)f(b)q(e)i(able)g(to)e(get)g(at)h(the)g(line)h(later,)f +(\(with)1325 1616 y Fn(h)p 1338 1590 57 2 v 1338 1618 +a Fm(C-p)p 1338 1626 V 1392 1616 a Fn(i)1420 1618 y Fu(for)f +(example\),)i(y)o(ou)f(m)o(ust)75 1673 y(call)j Ft(add_history\(\))e +Fu(to)g(sa)o(v)o(e)h(the)g(line)i(a)o(w)o(a)o(y)d(in)i(a)e +Fk(history)19 b Fu(list)d(of)f(suc)o(h)h(lines.)195 1738 +y Ft(add_history)22 b(\(line\);)75 1805 y Fu(F)l(or)15 +b(full)h(details)g(on)f(the)h(GNU)f(History)g(Library)l(,)g(see)h(the)f +(asso)q(ciated)g(man)o(ual.)137 1873 y(It)h(is)g(preferable)h(to)e(a)o +(v)o(oid)g(sa)o(ving)h(empt)o(y)f(lines)i(on)f(the)g(history)f(list,)i +(since)f(users)g(rarely)g(ha)o(v)o(e)f(a)75 1928 y(burning)h(need)g(to) +e(reuse)h(a)g(blank)g(line.)22 b(Here)15 b(is)g(a)g(function)g(whic)o +(h)h(usefully)h(replaces)e(the)g(standard)75 1983 y Ft(gets\(\))f +Fu(library)i(function,)g(and)f(has)g(the)h(adv)m(an)o(tage)e(of)h(no)g +(static)g(bu\013er)g(to)g(o)o(v)o(er\015o)o(w:)195 2047 +y Ft(/*)24 b(A)f(static)g(variable)g(for)h(holding)e(the)i(line.)f(*/) +195 2099 y(static)g(char)g(*line_read)g(=)h(\(char)f(*\)NULL;)195 +2203 y(/*)h(Read)f(a)h(string,)f(and)g(return)g(a)h(pointer)f(to)g(it.) +267 2255 y(Returns)f(NULL)i(on)f(EOF.)h(*/)195 2307 y(char)f(*)195 +2359 y(rl_gets)g(\(\))195 2411 y({)243 2462 y(/*)g(If)h(the)f(buffer)g +(has)h(already)f(been)g(allocated,)314 2514 y(return)g(the)h(memory)f +(to)g(the)h(free)f(pool.)g(*/)243 2566 y(if)g(\(line_read\))290 +2618 y({)338 2670 y(free)g(\(line_read\);)p eop +%%Page: 22 24 +22 23 bop 75 -58 a Fu(22)1299 b(GNU)15 b(Readline)h(Library)338 +149 y Ft(line_read)23 b(=)h(\(char)f(*\)NULL;)290 201 +y(})243 305 y(/*)g(Get)h(a)f(line)h(from)f(the)h(user.)f(*/)243 +357 y(line_read)f(=)i(readline)f(\(""\);)243 461 y(/*)g(If)h(the)f +(line)h(has)f(any)h(text)f(in)g(it,)314 513 y(save)h(it)f(on)h(the)f +(history.)g(*/)243 565 y(if)g(\(line_read)g(&&)g(*line_read\))290 +616 y(add_history)g(\(line_read\);)243 720 y(return)g(\(line_read\);) +195 772 y(})137 848 y Fu(This)13 b(function)f(giv)o(es)h(the)e(user)h +(the)g(default)h(b)q(eha)o(viour)g(of)1169 846 y Fn(h)p +1181 820 74 2 v 1181 848 a Fm(T)m(AB)p 1181 856 V 1253 +846 a Fn(i)1280 848 y Fu(completion:)19 b(completion)13 +b(on)f(\014le)75 903 y(names.)20 b(If)c(y)o(ou)f(do)g(not)g(w)o(an)o(t) +f(Readline)j(to)d(complete)j(on)e(\014lenames,)h(y)o(ou)f(can)g(c)o +(hange)h(the)f(binding)75 958 y(of)g(the)205 956 y Fn(h)p +217 930 V 217 958 a Fm(T)m(AB)p 217 965 V 289 956 a Fn(i)319 +958 y Fu(k)o(ey)g(with)h Ft(rl_bind_key\(\))p Fu(.)195 +1031 y Ft(int)23 b(rl_bind_key)g(\(int)g Fk(k)o(ey)p +Ft(,)h(rl_command_func_t)d(*)p Fk(function)p Ft(\);)137 +1107 y(rl_bind_key\(\))15 b Fu(tak)o(es)h(t)o(w)o(o)g(argumen)o(ts:)22 +b Fk(k)o(ey)e Fu(is)e(the)e(c)o(haracter)g(that)g(y)o(ou)h(w)o(an)o(t)f +(to)g(bind,)i(and)75 1161 y Fk(function)h Fu(is)f(the)g(address)g(of)g +(the)g(function)g(to)g(call)h(when)f Fk(k)o(ey)k Fu(is)c(pressed.)29 +b(Binding)1628 1159 y Fn(h)p 1641 1133 V 1641 1161 a +Fm(T)m(AB)p 1641 1169 V 1712 1159 a Fn(i)1745 1161 y +Fu(to)17 b Ft(rl_)75 1216 y(insert\(\))f Fu(mak)o(es)422 +1214 y Fn(h)p 434 1188 V 434 1216 a Fm(T)m(AB)p 434 1224 +V 506 1214 a Fn(i)539 1216 y Fu(insert)i(itself.)28 b +Ft(rl_bind_key\(\))15 b Fu(returns)j(non-zero)g(if)g +Fk(k)o(ey)j Fu(is)d(not)f(a)g(v)m(alid)75 1271 y(ASCI)q(I)f(c)o +(haracter)f(co)q(de)h(\(b)q(et)o(w)o(een)f(0)g(and)g(255\).)137 +1347 y(Th)o(us,)g(to)g(disable)h(the)g(default)703 1345 +y Fn(h)p 716 1319 V 716 1347 a Fm(T)m(AB)p 716 1354 V +787 1345 a Fn(i)817 1347 y Fu(b)q(eha)o(vior,)g(the)f(follo)o(wing)h +(su\016ces:)195 1420 y Ft(rl_bind_key)22 b(\('\\t',)h(rl_insert\);)137 +1496 y Fu(This)14 b(co)q(de)g(should)g(b)q(e)g(executed)g(once)g(at)e +(the)h(start)f(of)h(y)o(our)g(program;)f(y)o(ou)h(migh)o(t)g(write)g(a) +g(func-)75 1551 y(tion)k(called)h Ft(initialize_readline\(\))13 +b Fu(whic)o(h)k(p)q(erforms)f(this)h(and)g(other)f(desired)h +(initializations,)75 1605 y(suc)o(h)f(as)e(installing)k(custom)c +(completers)i(\(see)f(Section)h(2.6)f([Custom)f(Completers],)g(page)h +(41\).)75 1756 y Fs(2.2)33 b(Custom)21 b(F)-6 b(unctions)137 +1861 y Fu(Readline)14 b(pro)o(vides)f(man)o(y)e(functions)i(for)f +(manipulating)i(the)e(text)g(of)g(the)g(line,)i(but)e(it)h(isn't)f(p)q +(ossi-)75 1915 y(ble)i(to)f(an)o(ticipate)h(the)f(needs)h(of)f(all)h +(programs.)k(This)13 b(section)h(describ)q(es)h(the)e(v)m(arious)h +(functions)g(and)75 1970 y(v)m(ariables)g(de\014ned)h(within)f(the)f +(Readline)i(library)e(whic)o(h)h(allo)o(w)g(a)e(user)h(program)f(to)h +(add)g(customized)75 2025 y(functionalit)o(y)j(to)f(Readline.)137 +2101 y(Before)j(declaring)i(an)o(y)e(functions)h(that)f(customize)g +(Readline's)h(b)q(eha)o(vior,)h(or)d(using)i(an)o(y)f(func-)75 +2156 y(tionalit)o(y)23 b(Readline)h(pro)o(vides)g(in)f(other)g(co)q +(de,)h(an)f(application)i(writer)d(should)i(include)h(the)e(\014le)75 +2211 y Ft()14 b Fu(in)j(an)o(y)g(\014le)h(that)e +(uses)h(Readline's)g(features.)24 b(Since)19 b(some)d(of)g(the)h +(de\014-)75 2265 y(nitions)g(in)f Ft(readline.h)e Fu(use)i(the)g +Ft(stdio)f Fu(library)l(,)h(the)g(\014le)g Ft()f +Fu(should)h(b)q(e)g(included)j(b)q(efore)75 2320 y Ft(readline.h)p +Fu(.)137 2396 y Ft(readline.h)14 b Fu(de\014nes)i(a)f(C)h(prepro)q +(cessor)f(v)m(ariable)i(that)d(should)i(b)q(e)g(treated)f(as)g(an)g(in) +o(teger,)g Ft(RL_)75 2451 y(READLINE_VERSION)p Fu(,)9 +b(whic)o(h)j(ma)o(y)f(b)q(e)g(used)h(to)e(conditionally)k(compile)e +(application)h(co)q(de)f(dep)q(ending)75 2506 y(on)17 +b(the)h(installed)h(Readline)g(v)o(ersion.)27 b(The)18 +b(v)m(alue)h(is)f(a)f(hexadecimal)i(enco)q(ding)g(of)e(the)h(ma)s(jor)e +(and)75 2560 y(minor)h(v)o(ersion)h(n)o(um)o(b)q(ers)f(of)g(the)g +(library)l(,)h(of)f(the)g(form)f(0x)p Fk(MMmm)p Fu(.)25 +b Fk(MM)c Fu(is)c(the)h(t)o(w)o(o-digit)e(ma)s(jor)75 +2615 y(v)o(ersion)f(n)o(um)o(b)q(er;)f Fk(mm)h Fu(is)g(the)f(t)o(w)o +(o-digit)g(minor)h(v)o(ersion)g(n)o(um)o(b)q(er.)20 b(F)l(or)14 +b(Readline)h(4.2,)f(for)f(example,)75 2670 y(the)i(v)m(alue)i(of)d +Ft(RL_READLINE_VERSION)f Fu(w)o(ould)j(b)q(e)f Ft(0x0402)p +Fu(.)p eop +%%Page: 23 25 +23 24 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(23)75 149 y Fj(2.2.1)30 b(Readline)20 +b(T)n(yp)r(edefs)137 251 y Fu(F)l(or)15 b(readabilt)o(y)l(,)g(w)o(e)g +(declare)i(a)d(n)o(um)o(b)q(er)i(of)f(new)g(ob)s(ject)g(t)o(yp)q(es,)g +(all)h(p)q(oin)o(ters)f(to)g(functions.)137 324 y(The)j(reason)g(for)f +(declaring)i(these)f(new)g(t)o(yp)q(es)g(is)h(to)e(mak)o(e)g(it)h +(easier)h(to)e(write)h(co)q(de)g(describing)75 379 y(p)q(oin)o(ters)e +(to)e(C)h(functions)h(with)g(appropriately)f(protot)o(yp)q(ed)g +(argumen)o(ts)g(and)g(return)g(v)m(alues.)137 452 y(F)l(or)j(instance,) +i(sa)o(y)e(w)o(e)g(w)o(an)o(t)f(to)h(declare)h(a)f(v)m(ariable)i +Fk(func)i Fu(as)c(a)g(p)q(oin)o(ter)h(to)f(a)g(function)h(whic)o(h)75 +507 y(tak)o(es)12 b(t)o(w)o(o)g Ft(int)g Fu(argumen)o(ts)g(and)h +(returns)g(an)g Ft(int)f Fu(\(this)h(is)g(the)g(t)o(yp)q(e)g(of)g(all)g +(of)g(the)g(Readline)h(bindable)75 561 y(functions\).)20 +b(Instead)c(of)f(the)g(classic)h(C)f(declaration)137 +634 y Ft(int)g(\(*func\)\(\);)75 707 y Fu(or)g(the)g(ANSI-C)h(st)o(yle) +f(declaration)137 780 y Ft(int)g(\(*func\)\(int,)f(int\);)75 +853 y Fu(w)o(e)h(ma)o(y)f(write)137 926 y Ft(rl_command_func_t)f +(*func;)137 999 y Fu(The)j(full)g(list)g(of)f(function)h(p)q(oin)o(ter) +g(t)o(yp)q(es)f(a)o(v)m(ailable)i(is)75 1087 y Ft(typedef)d(int)h +(rl_command_func_t)e(\(int,)h(int\);)75 1157 y(typedef)g(char)h +(*rl_compentry_func_t)d(\(const)j(char)f(*,)h(int\);)75 +1227 y(typedef)f(char)h(**rl_completion_func_t)d(\(const)i(char)h(*,)g +(int,)f(int\);)75 1297 y(typedef)g(char)h(*rl_quote_func_t)e(\(char)h +(*,)h(int,)g(char)f(*\);)75 1367 y(typedef)g(char)h(*rl_dequote_func_t) +d(\(char)j(*,)g(int\);)75 1437 y(typedef)f(int)h(rl_compignore_func_t)d +(\(char)j(**\);)75 1507 y(typedef)f(void)h(rl_compdisp_func_t)d(\(char) +j(**,)g(int,)f(int\);)75 1577 y(typedef)g(int)h(rl_hook_func_t)e +(\(void\);)75 1647 y(typedef)h(int)h(rl_getc_func_t)e(\(FILE)i(*\);)75 +1717 y(typedef)f(int)h(rl_linebuf_func_t)e(\(char)h(*,)h(int\);)75 +1787 y(typedef)f(int)h(rl_intfunc_t)e(\(int\);)75 1857 +y(#define)h(rl_ivoidfunc_t)f(rl_hook_func_t)75 1927 y(typedef)h(int)h +(rl_icpfunc_t)e(\(char)i(*\);)75 1997 y(typedef)f(int)h(rl_icppfunc_t)e +(\(char)i(**\);)75 2067 y(typedef)f(void)h(rl_voidfunc_t)e(\(void\);)75 +2137 y(typedef)h(void)h(rl_vintfunc_t)e(\(int\);)75 2208 +y(typedef)h(void)h(rl_vcpfunc_t)e(\(char)i(*\);)75 2278 +y(typedef)f(void)h(rl_vcppfunc_t)e(\(char)i(**\);)75 +2386 y Fj(2.2.2)30 b(W)-5 b(riting)20 b(a)h(New)f(F)-5 +b(unction)137 2488 y Fu(In)17 b(order)f(to)f(write)h(new)h(functions)g +(for)e(Readline,)i(y)o(ou)f(need)h(to)e(kno)o(w)h(the)g(calling)i(con)o +(v)o(en)o(tions)75 2542 y(for)g(k)o(eyb)q(oard-in)o(v)o(ok)o(ed)h +(functions,)g(and)g(the)f(names)h(of)f(the)g(v)m(ariables)i(that)d +(describ)q(e)k(the)d(curren)o(t)75 2597 y(state)c(of)h(the)g(line)i +(read)e(so)g(far.)137 2670 y(The)h(calling)h(sequence)f(for)f(a)f +(command)i Ft(foo)e Fu(lo)q(oks)i(lik)o(e)p eop +%%Page: 24 26 +24 25 bop 75 -58 a Fu(24)1299 b(GNU)15 b(Readline)h(Library)195 +149 y Ft(int)23 b(foo)h(\(int)f(count,)g(int)h(key\))75 +221 y Fu(where)18 b Fk(coun)o(t)h Fu(is)f(the)g(n)o(umeric)h(argumen)o +(t)e(\(or)h(1)f(if)i(defaulted\))f(and)g Fk(k)o(ey)k +Fu(is)d(the)f(k)o(ey)g(that)f(in)o(v)o(ok)o(ed)75 276 +y(this)f(function.)137 348 y(It)c(is)g(completely)h(up)f(to)f(the)g +(function)i(as)e(to)g(what)g(should)h(b)q(e)g(done)g(with)g(the)g(n)o +(umeric)g(argumen)o(t.)75 403 y(Some)20 b(functions)h(use)f(it)g(as)g +(a)g(rep)q(eat)g(coun)o(t,)g(some)g(as)g(a)f(\015ag,)i(and)f(others)g +(to)f(c)o(ho)q(ose)h(alternate)75 457 y(b)q(eha)o(vior)i(\(refreshing)g +(the)g(curren)o(t)f(line)j(as)d(opp)q(osed)h(to)f(refreshing)i(the)e +(screen,)j(for)d(example\).)75 512 y(Some)c(c)o(ho)q(ose)f(to)g(ignore) +h(it.)24 b(In)18 b(general,)f(if)g(a)f(function)h(uses)g(the)g(n)o +(umeric)h(argumen)o(t)d(as)i(a)f(rep)q(eat)75 567 y(coun)o(t,)e(it)g +(should)h(b)q(e)f(able)h(to)e(do)h(something)h(useful)g(with)f(b)q(oth) +g(negativ)o(e)g(and)g(p)q(ositiv)o(e)h(argumen)o(ts.)75 +622 y(A)o(t)g(the)g(v)o(ery)g(least,)g(it)g(should)h(b)q(e)g(a)o(w)o +(are)e(that)h(it)g(can)g(b)q(e)h(passed)g(a)f(negativ)o(e)g(argumen)o +(t.)137 693 y(A)f(command)g(function)h(should)g(return)e(0)h(if)g(its)g +(action)h(completes)f(successfully)l(,)i(and)e(a)g(non-zero)75 +748 y(v)m(alue)i(if)g(some)f(error)f(o)q(ccurs.)75 888 +y Fs(2.3)33 b(Readline)23 b(V)-6 b(ariables)137 989 y +Fu(These)16 b(v)m(ariables)g(are)f(a)o(v)m(ailable)i(to)e(function)h +(writers.)1773 1120 y(V)l(ariable)-1861 b Fi(char)20 +b(*)f Fh(rl)p 286 1120 18 3 v 21 w(line)p 395 1120 V +23 w(bu\013er)195 1174 y Fu(This)d(is)g(the)g(line)h(gathered)f(so)f +(far.)20 b(Y)l(ou)c(are)f(w)o(elcome)h(to)f(mo)q(dify)h(the)g(con)o +(ten)o(ts)f(of)g(the)h(line,)195 1229 y(but)i(see)g(Section)h(2.4.5)d +([Allo)o(wing)i(Undoing],)h(page)e(32.)27 b(The)18 b(function)h +Ft(rl_extend_line_)195 1284 y(buffer)14 b Fu(is)i(a)o(v)m(ailable)h(to) +d(increase)j(the)e(memory)f(allo)q(cated)j(to)d Ft(rl_line_buffer)p +Fu(.)1773 1414 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p +215 1414 V 21 w(p)r(oin)n(t)195 1469 y Fu(The)15 b(o\013set)g(of)f(the) +i(curren)o(t)f(cursor)g(p)q(osition)h(in)g Ft(rl_line_buffer)d +Fu(\(the)i Fl(p)n(oint)t Fu(\).)1773 1600 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1600 V 21 w(end)195 1655 y +Fu(The)14 b(n)o(um)o(b)q(er)g(of)g(c)o(haracters)f(presen)o(t)h(in)h +Ft(rl_line_buffer)p Fu(.)i(When)e Ft(rl_point)e Fu(is)h(at)f(the)h(end) +195 1709 y(of)h(the)g(line,)i Ft(rl_point)d Fu(and)h +Ft(rl_end)f Fu(are)h(equal.)1773 1840 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1840 V 21 w(mark)195 1895 y +Fu(The)f Fk(mark)h Fu(\(sa)o(v)o(ed)e(p)q(osition\))h(in)g(the)g +(curren)o(t)f(line.)31 b(If)19 b(set,)g(the)f(mark)g(and)h(p)q(oin)o(t) +g(de\014ne)g(a)195 1950 y Fl(r)n(e)n(gion)p Fu(.)1773 +2080 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 2080 +V 21 w(done)195 2135 y Fu(Setting)11 b(this)g(to)g(a)f(non-zero)h(v)m +(alue)h(causes)f(Readline)h(to)f(return)f(the)h(curren)o(t)g(line)h +(immediately)l(.)1773 2265 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 2265 V 21 w(n)n(um)p 347 2265 V 19 w(c)n(hars)p +496 2265 V 20 w(to)p 567 2265 V 21 w(read)195 2320 y +Fu(Setting)d(this)g(to)f(a)g(p)q(ositiv)o(e)h(v)m(alue)h(b)q(efore)f +(calling)h Ft(readline\(\))d Fu(causes)h(Readline)i(to)e(return)195 +2375 y(after)h(accepting)i(that)e(man)o(y)g(c)o(haracters,)h(rather)f +(than)h(reading)g(up)g(to)f(a)h(c)o(haracter)f(b)q(ound)195 +2430 y(to)e Ft(accept-line)p Fu(.)1773 2560 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 2560 V 21 w(p)r(ending)p 436 +2560 V 20 w(input)195 2615 y Fu(Setting)13 b(this)g(to)f(a)g(v)m(alue)i +(mak)o(es)e(it)h(the)f(next)h(k)o(eystrok)o(e)f(read.)19 +b(This)13 b(is)g(a)f(w)o(a)o(y)g(to)f(stu\013)h(a)h(single)195 +2670 y(c)o(haracter)h(in)o(to)i(the)f(input)h(stream.)p +eop +%%Page: 25 27 +25 26 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(25)1773 149 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 149 18 3 v 21 w(dispatc)n(hing)195 204 +y Fu(Set)12 b(to)g(a)f(non-zero)i(v)m(alue)g(if)g(a)f(function)h(is)f +(b)q(eing)i(called)f(from)f(a)f(k)o(ey)h(binding;)j(zero)d(otherwise.) +195 259 y(Application)20 b(functions)e(can)g(test)g(this)g(to)f(disco)o +(v)o(er)h(whether)g(they)g(w)o(ere)g(called)h(directly)g(or)195 +314 y(b)o(y)c(Readline's)h(dispatc)o(hing)h(mec)o(hanism.)1773 +423 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 423 +V 21 w(erase)p 363 423 V 20 w(empt)n(y)p 540 423 V 20 +w(line)195 478 y Fu(Setting)j(this)h(to)e(a)h(non-zero)g(v)m(alue)h +(causes)f(Readline)i(to)d(completely)i(erase)f(the)g(curren)o(t)195 +533 y(line,)g(including)h(an)o(y)c(prompt,)h(an)o(y)g(time)g(a)f +(newline)j(is)e(t)o(yp)q(ed)g(as)f(the)h(only)g(c)o(haracter)f(on)195 +588 y(an)e(otherwise-empt)o(y)g(line.)31 b(The)18 b(cursor)g(is)h(mo)o +(v)o(ed)e(to)h(the)g(b)q(eginning)i(of)e(the)g(newly-blank)195 +643 y(line.)1773 752 y(V)l(ariable)-1861 b Fi(char)20 +b(*)f Fh(rl)p 286 752 V 21 w(prompt)195 807 y Fu(The)13 +b(prompt)g(Readline)h(uses.)20 b(This)13 b(is)h(set)f(from)f(the)h +(argumen)o(t)g(to)f Ft(readline\(\))p Fu(,)g(and)h(should)195 +862 y(not)g(b)q(e)h(assigned)g(to)f(directly)l(.)21 b(The)14 +b Ft(rl_set_prompt\(\))d Fu(function)j(\(see)g(Section)g(2.4.6)e +([Redis-)195 917 y(pla)o(y],)j(page)g(33\))f(ma)o(y)h(b)q(e)g(used)h +(to)f(mo)q(dify)h(the)f(prompt)g(string)g(after)f(calling)j +Ft(readline\(\))p Fu(.)1773 1026 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1026 V 21 w(already)p 419 1026 +V 21 w(prompted)195 1081 y Fu(If)e(an)g(application)i(wishes)f(to)f +(displa)o(y)h(the)f(prompt)g(itself,)h(rather)f(than)g(ha)o(v)o(e)g +(Readline)h(do)195 1136 y(it)e(the)f(\014rst)g(time)h +Ft(readline\(\))e Fu(is)i(called,)h(it)e(should)i(set)e(this)h(v)m +(ariable)g(to)f(a)g(non-zero)h(v)m(alue)195 1191 y(after)h(displa)o +(ying)j(the)e(prompt.)31 b(The)19 b(prompt)g(m)o(ust)f(also)h(b)q(e)h +(passed)f(as)f(the)h(argumen)o(t)g(to)195 1245 y Ft(readline\(\))c +Fu(so)h(the)h(redispla)o(y)g(functions)h(can)e(up)q(date)h(the)g +(displa)o(y)h(prop)q(erly)l(.)24 b(The)17 b(calling)195 +1300 y(application)g(is)f(resp)q(onsible)h(for)d(managing)h(the)h(v)m +(alue;)g(Readline)g(nev)o(er)g(sets)e(it.)1773 1410 y(V)l(ariable)-1861 +b Fi(const)20 b(char)g(*)f Fh(rl)p 436 1410 V 21 w(library)p +625 1410 V 21 w(v)n(ersion)195 1465 y Fu(The)c(v)o(ersion)h(n)o(um)o(b) +q(er)f(of)g(this)h(revision)g(of)f(the)g(library)l(.)1773 +1574 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 1574 +V 21 w(readline)p 434 1574 V 22 w(v)n(ersion)195 1629 +y Fu(An)d(in)o(teger)h(enco)q(ding)g(the)f(curren)o(t)g(v)o(ersion)g +(of)g(the)g(library)l(.)27 b(The)17 b(enco)q(ding)h(is)g(of)f(the)g +(form)195 1684 y(0x)p Fk(MMmm)p Fu(,)g(where)i Fk(MM)j +Fu(is)d(the)f(t)o(w)o(o-digit)g(ma)s(jor)f(v)o(ersion)i(n)o(um)o(b)q +(er,)g(and)f Fk(mm)g Fu(is)h(the)f(t)o(w)o(o-)195 1738 +y(digit)i(minor)e(v)o(ersion)h(n)o(um)o(b)q(er.)31 b(F)l(or)18 +b(example,)i(for)e(Readline-4.2,)i Ft(rl_readline_version)195 +1793 y Fu(w)o(ould)c(ha)o(v)o(e)e(the)i(v)m(alue)g(0x0402.)1773 +1903 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 1903 +V 21 w(gn)n(u)p 327 1903 V 20 w(readline)p 545 1903 V +22 w(p)195 1958 y Fu(Alw)o(a)o(ys)15 b(set)g(to)f(1,)h(denoting)h(that) +e(this)i(is)g Fp(gnu)f Fu(readline)h(rather)f(than)g(some)g(em)o +(ulation.)1773 2067 y(V)l(ariable)-1861 b Fi(const)20 +b(char)g(*)f Fh(rl)p 436 2067 V 21 w(terminal)p 668 2067 +V 21 w(name)195 2122 y Fu(The)14 b(terminal)h(t)o(yp)q(e,)f(used)h(for) +e(initialization.)23 b(If)14 b(not)f(set)h(b)o(y)g(the)g(application,)i +(Readline)f(sets)195 2177 y(this)h(to)e(the)h(v)m(alue)i(of)e(the)g +Ft(TERM)g Fu(en)o(vironmen)o(t)g(v)m(ariable)i(the)e(\014rst)g(time)g +(it)h(is)f(called.)1773 2286 y(V)l(ariable)-1861 b Fi(const)20 +b(char)g(*)f Fh(rl)p 436 2286 V 21 w(readline)p 655 2286 +V 22 w(name)195 2341 y Fu(This)d(v)m(ariable)h(is)f(set)g(to)f(a)g +(unique)i(name)f(b)o(y)f(eac)o(h)h(application)h(using)f(Readline.)23 +b(The)16 b(v)m(alue)195 2396 y(allo)o(ws)e(conditional)i(parsing)e(of)g +(the)g(inputrc)h(\014le)g(\(see)f(Section)h(1.3.2)d([Conditional)j +(Init)g(Con-)195 2451 y(structs],)f(page)h(9\).)1773 +2560 y(V)l(ariable)-1861 b Fi(FILE)20 b(*)f Fh(rl)p 286 +2560 V 21 w(instream)195 2615 y Fu(The)i(stdio)f(stream)g(from)g(whic)o +(h)h(Readline)h(reads)e(input.)37 b(If)21 b Ft(NULL)p +Fu(,)g(Readline)h(defaults)f(to)195 2670 y Fk(stdin)p +Fu(.)p eop +%%Page: 26 28 +26 27 bop 75 -58 a Fu(26)1299 b(GNU)15 b(Readline)h(Library)1773 +149 y(V)l(ariable)-1861 b Fi(FILE)20 b(*)f Fh(rl)p 286 +149 18 3 v 21 w(outstream)195 204 y Fu(The)e(stdio)h(stream)e(to)h +(whic)o(h)h(Readline)g(p)q(erforms)f(output.)26 b(If)18 +b Ft(NULL)p Fu(,)e(Readline)j(defaults)f(to)195 259 y +Fk(stdout)p Fu(.)1773 381 y(V)l(ariable)-1861 b Fi(rl_command_func_t)22 +b(*)d Fh(rl)p 626 381 V 21 w(last)p 735 381 V 21 w(func)195 +436 y Fu(The)f(address)f(of)g(the)g(last)h(command)f(function)h +(Readline)h(executed.)27 b(Ma)o(y)17 b(b)q(e)h(used)g(to)f(test)195 +490 y(whether)e(or)g(not)g(a)g(function)h(is)f(b)q(eing)i(executed)f(t) +o(wice)g(in)g(succession,)g(for)e(example.)1773 612 y(V)l(ariable)-1861 +b Fi(rl_hook_func_t)21 b(*)e Fh(rl)p 547 612 V 22 w(startup)p +752 612 V 19 w(ho)r(ok)195 667 y Fu(If)e(non-zero,)h(this)g(is)f(the)h +(address)f(of)f(a)h(function)h(to)f(call)h(just)f(b)q(efore)g +Ft(readline)f Fu(prin)o(ts)i(the)195 722 y(\014rst)d(prompt.)1773 +844 y(V)l(ariable)-1861 b Fi(rl_hook_func_t)21 b(*)e +Fh(rl)p 547 844 V 22 w(pre)p 651 844 V 20 w(input)p 804 +844 V 21 w(ho)r(ok)195 898 y Fu(If)f(non-zero,)g(this)g(is)h(the)f +(address)f(of)h(a)f(function)i(to)e(call)i(after)e(the)h(\014rst)f +(prompt)g(has)h(b)q(een)195 953 y(prin)o(ted)e(and)f(just)g(b)q(efore)h +Ft(readline)e Fu(starts)g(reading)h(input)i(c)o(haracters.)1773 +1075 y(V)l(ariable)-1861 b Fi(rl_hook_func_t)21 b(*)e +Fh(rl)p 547 1075 V 22 w(ev)n(en)n(t)p 701 1075 V 22 w(ho)r(ok)195 +1130 y Fu(If)i(non-zero,)g(this)g(is)g(the)f(address)g(of)g(a)g +(function)h(to)f(call)i(p)q(erio)q(dically)h(when)e(Readline)g(is)195 +1184 y(w)o(aiting)15 b(for)f(terminal)h(input.)21 b(By)14 +b(default,)h(this)g(will)i(b)q(e)e(called)h(at)e(most)g(ten)g(times)h +(a)f(second)195 1239 y(if)i(there)f(is)h(no)f(k)o(eyb)q(oard)g(input.) +1773 1361 y(V)l(ariable)-1861 b Fi(rl_getc_func_t)21 +b(*)e Fh(rl)p 547 1361 V 22 w(getc)p 671 1361 V 21 w(function)195 +1416 y Fu(If)c(non-zero,)h(Readline)g(will)h(call)f(indirectly)i +(through)d(this)g(p)q(oin)o(ter)h(to)f(get)f(a)h(c)o(haracter)g(from) +195 1471 y(the)k(input)i(stream.)31 b(By)19 b(default,)h(it)g(is)g(set) +f(to)f Ft(rl_getc)p Fu(,)h(the)g(default)h(Readline)h(c)o(haracter)195 +1525 y(input)16 b(function)g(\(see)f(Section)h(2.4.8)e([Character)g +(Input],)h(page)g(34\).)1773 1647 y(V)l(ariable)-1861 +b Fi(rl_voidfunc_t)21 b(*)e Fh(rl)p 521 1647 V 21 w(redispla)n(y)p +765 1647 V 22 w(function)195 1702 y Fu(If)f(non-zero,)h(Readline)g +(will)h(call)f(indirectly)h(through)e(this)g(p)q(oin)o(ter)h(to)e(up)q +(date)i(the)f(displa)o(y)195 1757 y(with)c(the)f(curren)o(t)h(con)o +(ten)o(ts)f(of)g(the)g(editing)i(bu\013er.)k(By)14 b(default,)g(it)g +(is)g(set)f(to)g Ft(rl_redisplay)p Fu(,)195 1812 y(the)i(default)h +(Readline)h(redispla)o(y)f(function)g(\(see)f(Section)h(2.4.6)e +([Redispla)o(y],)h(page)g(33\).)1773 1933 y(V)l(ariable)-1861 +b Fi(rl_vintfunc_t)21 b(*)e Fh(rl)p 521 1933 V 21 w(prep)p +656 1933 V 21 w(term)p 798 1933 V 19 w(function)195 1988 +y Fu(If)12 b(non-zero,)h(Readline)g(will)h(call)f(indirectly)h(through) +e(this)g(p)q(oin)o(ter)h(to)e(initialize)k(the)e(terminal.)195 +2043 y(The)19 b(function)g(tak)o(es)f(a)g(single)i(argumen)o(t,)e(an)h +Ft(int)f Fu(\015ag)g(that)g(sa)o(ys)g(whether)g(or)h(not)f(to)g(use)195 +2098 y(eigh)o(t-bit)g(c)o(haracters.)25 b(By)17 b(default,)h(this)f(is) +h(set)e(to)h Ft(rl_prep_terminal)e Fu(\(see)i(Section)h(2.4.9)195 +2152 y([T)l(erminal)e(Managemen)o(t],)d(page)i(35\).)1773 +2274 y(V)l(ariable)-1861 b Fi(rl_voidfunc_t)21 b(*)e +Fh(rl)p 521 2274 V 21 w(deprep)p 714 2274 V 21 w(term)p +856 2274 V 19 w(function)195 2329 y Fu(If)g(non-zero,)g(Readline)g +(will)h(call)g(indirectly)g(through)e(this)h(p)q(oin)o(ter)f(to)g +(reset)g(the)h(terminal.)195 2384 y(This)f(function)g(should)h(undo)f +(the)f(e\013ects)h(of)f Ft(rl_prep_term_function)p Fu(.)24 +b(By)17 b(default,)i(this)195 2439 y(is)d(set)f(to)f +Ft(rl_deprep_terminal)f Fu(\(see)i(Section)h(2.4.9)e([T)l(erminal)i +(Managemen)o(t],)d(page)i(35\).)1773 2560 y(V)l(ariable)-1861 +b Fi(Keymap)20 b Fh(rl)p 293 2560 V 21 w(executing)p +551 2560 V 22 w(k)n(eymap)195 2615 y Fu(This)f(v)m(ariable)g(is)f(set)g +(to)g(the)g(k)o(eymap)f(\(see)h(Section)h(2.4.2)e([Keymaps],)g(page)h +(29\))f(in)i(whic)o(h)195 2670 y(the)c(curren)o(tly)h(executing)g +(readline)h(function)f(w)o(as)f(found.)p eop +%%Page: 27 29 +27 28 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(27)1773 149 y(V)l(ariable)-1861 b Fi(Keymap)20 +b Fh(rl)p 293 149 18 3 v 21 w(binding)p 501 149 V 22 +w(k)n(eymap)195 204 y Fu(This)f(v)m(ariable)g(is)f(set)g(to)g(the)g(k)o +(eymap)f(\(see)h(Section)h(2.4.2)e([Keymaps],)g(page)h(29\))f(in)i +(whic)o(h)195 259 y(the)c(last)g(k)o(ey)g(binding)j(o)q(ccurred.)1773 +383 y(V)l(ariable)-1861 b Fi(char)20 b(*)f Fh(rl)p 286 +383 V 21 w(executing)p 544 383 V 22 w(macro)195 438 y +Fu(This)d(v)m(ariable)g(is)g(set)f(to)g(the)g(text)g(of)f(an)o(y)h +(curren)o(tly-executing)i(macro.)1773 562 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 562 V 21 w(readline)p 434 562 +V 22 w(state)195 617 y Fu(A)d(v)m(ariable)i(with)e(bit)h(v)m(alues)h +(that)d(encapsulate)i(the)g(curren)o(t)f(Readline)h(state.)25 +b(A)18 b(bit)f(is)h(set)195 671 y(with)h(the)g Ft(RL_SETSTATE)f +Fu(macro,)h(and)g(unset)g(with)g(the)g Ft(RL_UNSETSTATE)e +Fu(macro.)31 b(Use)19 b(the)195 726 y Ft(RL_ISSTATE)e +Fu(macro)h(to)g(test)g(whether)h(a)f(particular)i(state)d(bit)j(is)f +(set.)30 b(Curren)o(t)18 b(state)g(bits)195 781 y(include:)195 +864 y Ft(RL_STATE_NONE)435 919 y Fu(Readline)e(has)g(not)e(y)o(et)h(b)q +(een)h(called,)h(nor)e(has)g(it)g(b)q(egun)h(to)f(in)o(tialize.)195 +1001 y Ft(RL_STATE_INITIALIZING)435 1056 y Fu(Readline)h(is)g +(initializi)q(ng)i(its)d(in)o(ternal)h(data)f(structures.)195 +1138 y Ft(RL_STATE_INITIALIZED)435 1192 y Fu(Readline)h(has)g +(completed)g(its)f(initialization.)195 1274 y Ft(RL_STATE_TERMPREPPED) +435 1329 y Fu(Readline)h(has)e(mo)q(di\014ed)i(the)e(terminal)h(mo)q +(des)g(to)e(do)i(its)f(o)o(wn)g(input)h(and)g(redis-)435 +1384 y(pla)o(y)l(.)195 1466 y Ft(RL_STATE_READCMD)435 +1521 y Fu(Readline)h(is)g(reading)g(a)f(command)g(from)f(the)i(k)o(eyb) +q(oard.)195 1603 y Ft(RL_STATE_METANEXT)435 1658 y Fu(Readline)g(is)g +(reading)g(more)f(input)h(after)e(reading)i(the)f(meta-pre\014x)h(c)o +(haracter.)195 1740 y Ft(RL_STATE_DISPATCHING)435 1794 +y Fu(Readline)g(is)g(dispatc)o(hing)h(to)d(a)h(command.)195 +1876 y Ft(RL_STATE_MOREINPUT)435 1931 y Fu(Readline)h(is)g(reading)g +(more)f(input)h(while)h(executing)f(an)f(editing)i(command.)195 +2013 y Ft(RL_STATE_ISEARCH)435 2068 y Fu(Readline)f(is)g(p)q(erforming) +g(an)f(incremen)o(tal)h(history)f(searc)o(h.)195 2150 +y Ft(RL_STATE_NSEARCH)435 2205 y Fu(Readline)h(is)g(p)q(erforming)g(a)f +(non-incremen)o(tal)h(history)g(searc)o(h.)195 2287 y +Ft(RL_STATE_SEARCH)435 2342 y Fu(Readline)11 b(is)g(searc)o(hing)g(bac) +o(kw)o(ard)e(or)h(forw)o(ard)f(through)h(the)g(history)g(for)f(a)h +(string.)195 2424 y Ft(RL_STATE_NUMERICARG)435 2478 y +Fu(Readline)16 b(is)g(reading)g(a)f(n)o(umeric)h(argumen)o(t.)195 +2560 y Ft(RL_STATE_MACROINPUT)435 2615 y Fu(Readline)d(is)g(curren)o +(tly)g(getting)f(its)g(input)h(from)e(a)h(previously-de\014ned)j(k)o +(eyb)q(oard)435 2670 y(macro.)p eop +%%Page: 28 30 +28 29 bop 75 -58 a Fu(28)1299 b(GNU)15 b(Readline)h(Library)195 +149 y Ft(RL_STATE_MACRODEF)435 204 y Fu(Readline)g(is)g(curren)o(tly)g +(reading)g(c)o(haracters)e(de\014ning)j(a)e(k)o(eyb)q(oard)g(macro.)195 +286 y Ft(RL_STATE_OVERWRITE)435 341 y Fu(Readline)h(is)g(in)g(o)o(v)o +(erwrite)f(mo)q(de.)195 423 y Ft(RL_STATE_COMPLETING)435 +478 y Fu(Readline)h(is)g(p)q(erforming)g(w)o(ord)e(completion.)195 +560 y Ft(RL_STATE_SIGHANDLER)435 615 y Fu(Readline)i(is)g(curren)o(tly) +g(executing)g(the)f(readline)i(signal)f(handler.)195 +697 y Ft(RL_STATE_UNDOING)435 752 y Fu(Readline)g(is)g(p)q(erforming)g +(an)f(undo.)195 834 y Ft(RL_STATE_DONE)435 889 y Fu(Readline)g(has)f +(read)g(a)f(k)o(ey)h(sequence)h(b)q(ound)g(to)e Ft(accept-line)f +Fu(and)i(is)h(ab)q(out)f(to)435 944 y(return)h(the)g(line)i(to)e(the)g +(caller.)1773 1068 y(V)l(ariable)-1861 b Fi(int)20 b +Fh(rl)p 215 1068 18 3 v 21 w(explicit)p 417 1068 V 24 +w(arg)195 1123 y Fu(Set)f(to)g(a)g(non-zero)h(v)m(alue)h(if)e(an)h +(explicit)h(n)o(umeric)g(argumen)o(t)d(w)o(as)h(sp)q(eci\014ed)i(b)o(y) +f(the)f(user.)195 1178 y(Only)d(v)m(alid)h(in)f(a)f(bindable)i(command) +f(function.)1773 1302 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 1302 V 21 w(n)n(umeric)p 437 1302 V 20 +w(arg)195 1357 y Fu(Set)j(to)f(the)g(v)m(alue)i(of)f(an)o(y)f(n)o +(umeric)h(argumen)o(t)f(explicitly)k(sp)q(eci\014ed)f(b)o(y)d(the)h +(user)g(b)q(efore)195 1412 y(executing)14 b(the)f(curren)o(t)g +(Readline)h(function.)20 b(Only)14 b(v)m(alid)h(in)f(a)f(bindable)i +(command)d(function.)1773 1536 y(V)l(ariable)-1861 b +Fi(int)20 b Fh(rl)p 215 1536 V 21 w(editing)p 407 1536 +V 22 w(mo)r(de)195 1591 y Fu(Set)13 b(to)f(a)g(v)m(alue)i(denoting)f +(Readline's)g(curren)o(t)g(editing)h(mo)q(de.)19 b(A)12 +b(v)m(alue)i(of)e Fk(1)k Fu(means)d(Readline)195 1646 +y(is)j(curren)o(tly)f(in)h(emacs)g(mo)q(de;)f Fk(0)j +Fu(means)d(that)g(vi)h(mo)q(de)f(is)h(activ)o(e.)75 1781 +y Fs(2.4)33 b(Readline)23 b(Con)n(v)n(enience)g(F)-6 +b(unctions)75 1927 y Fj(2.4.1)30 b(Naming)20 b(a)g(F)-5 +b(unction)137 2025 y Fu(The)20 b(user)g(can)g(dynamically)i(c)o(hange)e +(the)g(bindings)i(of)d(k)o(eys)h(while)h(using)g(Readline.)35 +b(This)20 b(is)75 2080 y(done)f(b)o(y)f(represen)o(ting)h(the)g +(function)g(with)g(a)f(descriptiv)o(e)i(name.)29 b(The)19 +b(user)f(is)h(able)h(to)d(t)o(yp)q(e)i(the)75 2135 y(descriptiv)o(e)e +(name)e(when)h(referring)f(to)g(the)g(function.)21 b(Th)o(us,)14 +b(in)i(an)f(init)i(\014le,)f(one)f(migh)o(t)g(\014nd)195 +2202 y Ft(Meta-Rubout:)46 b(backward-kill-word)137 2272 +y Fu(This)21 b(binds)g(the)f(k)o(eystrok)o(e)661 2270 +y Fn(h)p 673 2244 209 2 v 673 2272 a Fm(Meta-Rub)q(out)p +673 2279 V 879 2270 a Fn(i)914 2272 y Fu(to)g(the)g(function)g +Fl(descriptively)k Fu(named)c Ft(backward-)75 2326 y(kill-word)p +Fu(.)29 b(Y)l(ou,)19 b(as)f(the)h(programmer,)f(should)i(bind)f(the)g +(functions)h(y)o(ou)e(write)h(to)e(descriptiv)o(e)75 +2381 y(names)e(as)g(w)o(ell.)21 b(Readline)16 b(pro)o(vides)g(a)f +(function)h(for)e(doing)i(that:)1762 2506 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 2506 18 3 v 21 w(add)p 328 +2506 V 20 w(defun)i Fg(\()p Ft(const)14 b(char)h(*name,)f +(rl_command_func_t)283 2560 y(*function,)f(int)i(key)p +Fg(\))195 2615 y Fu(Add)j Fk(name)i Fu(to)d(the)h(list)h(of)e(named)h +(functions.)28 b(Mak)o(e)17 b Fk(function)h Fu(b)q(e)g(the)g(function)h +(that)d(gets)195 2670 y(called.)21 b(If)16 b Fk(k)o(ey)j +Fu(is)d(not)e(-1,)h(then)h(bind)g(it)g(to)e Fk(function)i +Fu(using)g Ft(rl_bind_key\(\))p Fu(.)p eop +%%Page: 29 31 +29 30 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(29)137 149 y(Using)16 b(this)f(function)h(alone)g(is)f +(su\016cien)o(t)h(for)f(most)f(applications.)21 b(It)15 +b(is)h(the)f(recommended)h(w)o(a)o(y)75 204 y(to)d(add)h(a)f(few)g +(functions)h(to)f(the)h(default)g(functions)g(that)f(Readline)i(has)e +(built)i(in.)20 b(If)14 b(y)o(ou)f(need)h(to)f(do)75 +259 y(something)k(other)g(than)f(adding)i(a)e(function)i(to)e +(Readline,)i(y)o(ou)f(ma)o(y)f(need)i(to)e(use)h(the)g(underlying)75 +314 y(functions)f(describ)q(ed)h(b)q(elo)o(w.)75 442 +y Fj(2.4.2)30 b(Selecting)20 b(a)h(Keymap)137 546 y Fu(Key)16 +b(bindings)i(tak)o(e)c(place)j(on)e(a)g Fk(k)o(eymap)p +Fu(.)21 b(The)15 b(k)o(eymap)h(is)f(the)h(asso)q(ciation)g(b)q(et)o(w)o +(een)g(the)f(k)o(eys)75 601 y(that)f(the)g(user)g(t)o(yp)q(es)g(and)h +(the)f(functions)h(that)f(get)g(run.)19 b(Y)l(ou)c(can)f(mak)o(e)g(y)o +(our)g(o)o(wn)f(k)o(eymaps,)h(cop)o(y)75 656 y(existing)i(k)o(eymaps,)f +(and)g(tell)h(Readline)h(whic)o(h)f(k)o(eymap)f(to)f(use.)1762 +797 y(F)l(unction)-1861 b Fi(Keymap)20 b Fh(rl)p 293 +797 18 3 v 21 w(mak)n(e)p 445 797 V 20 w(bare)p 575 797 +V 20 w(k)n(eymap)j Fg(\()p Ft(void)p Fg(\))195 851 y +Fu(Returns)12 b(a)f(new,)i(empt)o(y)f(k)o(eymap.)18 b(The)13 +b(space)f(for)f(the)i(k)o(eymap)e(is)i(allo)q(cated)g(with)f +Ft(malloc\(\))p Fu(;)195 906 y(the)j(caller)i(should)f(free)f(it)h(b)o +(y)f(calling)i Ft(rl_discard_keymap\(\))12 b Fu(when)k(done.)1762 +1047 y(F)l(unction)-1861 b Fi(Keymap)20 b Fh(rl)p 293 +1047 V 21 w(cop)n(y)p 428 1047 V 21 w(k)n(eymap)j Fg(\()p +Ft(Keymap)14 b(map)p Fg(\))195 1102 y Fu(Return)h(a)g(new)g(k)o(eymap)g +(whic)o(h)h(is)g(a)f(cop)o(y)g(of)g Fk(map)p Fu(.)1762 +1243 y(F)l(unction)-1861 b Fi(Keymap)20 b Fh(rl)p 293 +1243 V 21 w(mak)n(e)p 445 1243 V 20 w(k)n(eymap)j Fg(\()p +Ft(void)p Fg(\))195 1298 y Fu(Return)16 b(a)f(new)i(k)o(eymap)e(with)i +(the)f(prin)o(ting)h(c)o(haracters)e(b)q(ound)i(to)e(rl)p +1457 1298 14 2 v 17 w(insert,)h(the)g(lo)o(w)o(ercase)195 +1353 y(Meta)11 b(c)o(haracters)f(b)q(ound)i(to)f(run)h(their)f(equiv)m +(alen)o(ts,)j(and)d(the)h(Meta)e(digits)i(b)q(ound)g(to)f(pro)q(duce) +195 1407 y(n)o(umeric)16 b(argumen)o(ts.)1762 1548 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 1548 18 3 v 21 w(discard)p +441 1548 V 21 w(k)n(eymap)i Fg(\()p Ft(Keymap)14 b(keymap)p +Fg(\))195 1603 y Fu(F)l(ree)h(the)h(storage)d(asso)q(ciated)j(with)f +Fk(k)o(eymap)p Fu(.)137 1711 y(Readline)24 b(has)f(sev)o(eral)g(in)o +(ternal)g(k)o(eymaps.)42 b(These)23 b(functions)g(allo)o(w)g(y)o(ou)f +(to)g(c)o(hange)h(whic)o(h)75 1766 y(k)o(eymap)15 b(is)h(activ)o(e.) +1762 1907 y(F)l(unction)-1861 b Fi(Keymap)20 b Fh(rl)p +293 1907 V 21 w(get)p 391 1907 V 21 w(k)n(eymap)i Fg(\()p +Ft(void)p Fg(\))195 1962 y Fu(Returns)15 b(the)g(curren)o(tly)h(activ)o +(e)f(k)o(eymap.)1762 2103 y(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 2103 V 21 w(set)p 333 2103 V 21 w(k)n(eymap)i +Fg(\()p Ft(Keymap)14 b(keymap)p Fg(\))195 2158 y Fu(Mak)o(es)g +Fk(k)o(eymap)j Fu(the)e(curren)o(tly)h(activ)o(e)f(k)o(eymap.)1762 +2298 y(F)l(unction)-1861 b Fi(Keymap)20 b Fh(rl)p 293 +2298 V 21 w(get)p 391 2298 V 21 w(k)n(eymap)p 605 2298 +V 20 w(b)n(y)p 685 2298 V 21 w(name)i Fg(\()p Ft(const)14 +b(char)g(*name)p Fg(\))195 2353 y Fu(Return)i(the)h(k)o(eymap)f(matc)o +(hing)h Fk(name)p Fu(.)24 b Fk(name)19 b Fu(is)e(one)g(whic)o(h)g(w)o +(ould)g(b)q(e)h(supplied)h(in)e(a)f Ft(set)195 2408 y(keymap)e +Fu(inputrc)j(line)f(\(see)g(Section)g(1.3)e([Readline)i(Init)g(File],)g +(page)f(4\).)1762 2549 y(F)l(unction)-1861 b Fi(char)20 +b(*)f Fh(rl)p 286 2549 V 21 w(get)p 384 2549 V 21 w(k)n(eymap)p +598 2549 V 20 w(name)i Fg(\()p Ft(Keymap)14 b(keymap)p +Fg(\))195 2604 y Fu(Return)i(the)h(name)g(matc)o(hing)f +Fk(k)o(eymap)p Fu(.)24 b Fk(name)19 b Fu(is)e(one)g(whic)o(h)g(w)o +(ould)g(b)q(e)h(supplied)h(in)e(a)f Ft(set)195 2659 y(keymap)e +Fu(inputrc)j(line)f(\(see)g(Section)g(1.3)e([Readline)i(Init)g(File],)g +(page)f(4\).)p eop +%%Page: 30 32 +30 31 bop 75 -58 a Fu(30)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fj(2.4.3)30 b(Binding)20 b(Keys)137 244 y Fu(Key)13 +b(sequences)g(are)e(asso)q(ciate)h(with)h(functions)f(through)g(the)g +(k)o(eymap.)19 b(Readline)13 b(has)f(sev)o(eral)g(in-)75 +299 y(ternal)j(k)o(eymaps:)k Ft(emacs_standard_keymap)p +Fu(,)11 b Ft(emacs_meta_keymap)p Fu(,)h Ft(emacs_ctlx_keymap)p +Fu(,)g Ft(vi_)75 354 y(movement_keymap)p Fu(,)20 b(and)i +Ft(vi_insertion_keymap)p Fu(.)35 b Ft(emacs_standard_keymap)18 +b Fu(is)k(the)f(default,)75 408 y(and)15 b(the)h(examples)g(in)g(this)f +(man)o(ual)h(assume)f(that.)137 474 y(Since)h Ft(readline\(\))c +Fu(installs)j(a)f(set)f(of)h(default)g(k)o(ey)g(bindings)h(the)f +(\014rst)g(time)g(it)g(is)g(called,)i(there)d(is)75 529 +y(alw)o(a)o(ys)j(the)g(danger)g(that)g(a)g(custom)g(binding)i +(installed)g(b)q(efore)f(the)f(\014rst)g(call)i(to)d +Ft(readline\(\))g Fu(will)75 584 y(b)q(e)f(o)o(v)o(erridden.)19 +b(An)13 b(alternate)g(mec)o(hanism)h(is)f(to)f(install)i(custom)f(k)o +(ey)g(bindings)h(in)g(an)f(initialization)75 638 y(function)19 +b(assigned)h(to)d(the)i Ft(rl_startup_hook)e Fu(v)m(ariable)j(\(see)e +(Section)h(2.3)f([Readline)i(V)l(ariables],)75 693 y(page)15 +b(24\).)137 759 y(These)h(functions)g(manage)e(k)o(ey)i(bindings.)1762 +868 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 868 +18 3 v 21 w(bind)p 347 868 V 21 w(k)n(ey)k Fg(\()p Ft(int)14 +b(key,)h(rl_command_func_t)d(*function)p Fg(\))195 922 +y Fu(Binds)18 b Fk(k)o(ey)i Fu(to)c Fk(function)h Fu(in)h(the)e(curren) +o(tly)h(activ)o(e)g(k)o(eymap.)23 b(Returns)16 b(non-zero)h(in)g(the)g +(case)195 977 y(of)e(an)g(in)o(v)m(alid)i Fk(k)o(ey)p +Fu(.)1762 1086 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 1086 V 21 w(bind)p 347 1086 V 21 w(k)n(ey)p 452 1086 +V 21 w(in)p 520 1086 V 22 w(map)h Fg(\()p Ft(int)14 b(key,)h +(rl_command_func_t)e(*function,)283 1141 y(Keymap)h(map)p +Fg(\))195 1196 y Fu(Bind)i Fk(k)o(ey)j Fu(to)c Fk(function)h +Fu(in)g Fk(map)p Fu(.)k(Returns)14 b(non-zero)i(in)g(the)f(case)g(of)g +(an)g(in)o(v)m(alid)j Fk(k)o(ey)p Fu(.)1762 1304 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1304 V 21 w(un)n(bind)p 409 +1304 V 21 w(k)n(ey)k Fg(\()p Ft(int)14 b(key)p Fg(\))195 +1359 y Fu(Bind)19 b Fk(k)o(ey)j Fu(to)c(the)g(n)o(ull)i(function)f(in)g +(the)f(curren)o(tly)g(activ)o(e)h(k)o(eymap.)28 b(Returns)18 +b(non-zero)g(in)195 1414 y(case)d(of)g(error.)1762 1523 +y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 1523 V +21 w(un)n(bind)p 409 1523 V 21 w(k)n(ey)p 514 1523 V +21 w(in)p 582 1523 V 22 w(map)h Fg(\()p Ft(int)14 b(key,)h(Keymap)f +(map)p Fg(\))195 1577 y Fu(Bind)i Fk(k)o(ey)j Fu(to)c(the)g(n)o(ull)i +(function)f(in)g Fk(map)p Fu(.)k(Returns)14 b(non-zero)i(in)g(case)f +(of)g(error.)1762 1686 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 1686 V 21 w(un)n(bind)p 409 1686 V 21 w(function)p +635 1686 V 21 w(in)p 703 1686 V 21 w(map)h Fg(\()p Ft +(rl_command_func_t)13 b(*function,)283 1741 y(Keymap)h(map)p +Fg(\))195 1796 y Fu(Un)o(bind)j(all)f(k)o(eys)f(that)f(execute)i +Fk(function)g Fu(in)g Fk(map)p Fu(.)1762 1905 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1905 V 21 w(un)n(bind)p 409 +1905 V 21 w(command)p 674 1905 V 17 w(in)p 738 1905 V +22 w(map)h Fg(\()p Ft(const)14 b(char)h(*command,)f(Keymap)283 +1959 y(map)p Fg(\))195 2014 y Fu(Un)o(bind)j(all)f(k)o(eys)f(that)f +(are)h(b)q(ound)h(to)f Fk(command)i Fu(in)f Fk(map)p +Fu(.)1762 2123 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 2123 V 21 w(set)p 307 2123 V 20 w(k)n(ey)k Fg(\()p +Ft(const)14 b(char)h(*keyseq,)f(rl_command_func_t)f(*function,)283 +2178 y(Keymap)h(map)p Fg(\))195 2232 y Fu(Bind)g(the)e(k)o(ey)h +(sequence)h(represen)o(ted)f(b)o(y)f(the)h(string)f Fk(k)o(eyseq)i +Fu(to)e(the)g(function)i Fk(function)p Fu(.)19 b(This)195 +2287 y(mak)o(es)13 b(new)g(k)o(eymaps)g(as)f(necessary)l(.)20 +b(The)13 b(initial)j(k)o(eymap)c(in)i(whic)o(h)g(to)f(do)g(bindings)i +(is)f Fk(map)p Fu(.)1762 2396 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 2396 V 21 w(generic)p 413 2396 V 21 w(bind)j +Fg(\()p Ft(int)15 b(type,)f(const)h(char)f(*keyseq,)g(char)h(*data,)283 +2451 y(Keymap)f(map)p Fg(\))195 2506 y Fu(Bind)h(the)e(k)o(ey)h +(sequence)h(represen)o(ted)e(b)o(y)h(the)g(string)f Fk(k)o(eyseq)i +Fu(to)d(the)i(arbitrary)f(p)q(oin)o(ter)h Fk(data)p Fu(.)195 +2560 y Fk(t)o(yp)q(e)j Fu(sa)o(ys)c(what)h(kind)h(of)f(data)g(is)g(p)q +(oin)o(ted)i(to)d(b)o(y)h Fk(data)p Fu(;)g(this)h(can)f(b)q(e)h(a)f +(function)h(\()p Ft(ISFUNC)p Fu(\),)d(a)195 2615 y(macro)i(\()p +Ft(ISMACR)p Fu(\),)f(or)h(a)h(k)o(eymap)f(\()p Ft(ISKMAP)p +Fu(\).)k(This)e(mak)o(es)e(new)h(k)o(eymaps)f(as)h(necessary)l(.)20 +b(The)195 2670 y(initial)d(k)o(eymap)e(in)h(whic)o(h)g(to)f(do)g +(bindings)i(is)f Fk(map)p Fu(.)p eop +%%Page: 31 33 +31 32 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(31)1762 149 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 149 18 3 v 21 w(parse)p 369 149 V 19 w(and)p +480 149 V 21 w(bind)j Fg(\()p Ft(char)14 b(*line)p Fg(\))195 +204 y Fu(P)o(arse)g Fk(line)19 b Fu(as)14 b(if)h(it)g(had)g(b)q(een)h +(read)f(from)f(the)g Ft(inputrc)g Fu(\014le)i(and)f(p)q(erform)f(an)o +(y)h(k)o(ey)f(bindings)195 259 y(and)h(v)m(ariable)i(assignmen)o(ts)e +(found)h(\(see)f(Section)h(1.3)e([Readline)i(Init)g(File],)g(page)f +(4\).)1762 359 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 359 V 21 w(read)p 346 359 V 20 w(init)p 450 359 V +22 w(\014le)k Fg(\()p Ft(const)14 b(char)h(*filename)p +Fg(\))195 414 y Fu(Read)g(k)o(eybindings)j(and)e(v)m(ariable)h +(assignmen)o(ts)f(from)f Fk(\014lename)k Fu(\(see)d(Section)g(1.3)f +([Readline)195 469 y(Init)h(File],)g(page)f(4\).)75 571 +y Fj(2.4.4)30 b(Asso)r(ciating)20 b(F)-5 b(unction)20 +b(Names)h(and)f(Bindings)137 664 y Fu(These)11 b(functions)h(allo)o(w)e +(y)o(ou)h(to)f(\014nd)h(out)f(what)g(k)o(eys)h(in)o(v)o(ok)o(e)f(named) +h(functions)h(and)e(the)h(functions)75 718 y(in)o(v)o(ok)o(ed)j(b)o(y)g +(a)f(particular)h(k)o(ey)g(sequence.)21 b(Y)l(ou)14 b(ma)o(y)f(also)g +(asso)q(ciate)h(a)g(new)g(function)g(name)g(with)g(an)75 +773 y(arbitrary)h(function.)1762 873 y(F)l(unction)-1861 +b Fi(rl_command_func_t)22 b(*)d Fh(rl)p 626 873 V 21 +w(named)p 814 873 V 19 w(function)k Fg(\()p Ft(const)14 +b(char)h(*name)p Fg(\))195 928 y Fu(Return)g(the)g(function)h(with)g +(name)f Fk(name)p Fu(.)1762 1028 y(F)l(unction)-1861 +b Fi(rl_command_func_t)22 b(*)d Fh(rl)p 626 1028 V 21 +w(function)p 852 1028 V 21 w(of)p 920 1028 V 20 w(k)n(eyseq)24 +b Fg(\()p Ft(const)14 b(char)283 1083 y(*keyseq,)g(Keymap)g(map,)h(int) +f(*type)p Fg(\))195 1138 y Fu(Return)i(the)g(function)h(in)o(v)o(ok)o +(ed)g(b)o(y)f Fk(k)o(eyseq)h Fu(in)g(k)o(eymap)f Fk(map)p +Fu(.)23 b(If)17 b Fk(map)g Fu(is)g Ft(NULL)p Fu(,)f(the)g(curren)o(t) +195 1193 y(k)o(eymap)i(is)h(used.)31 b(If)18 b Fk(t)o(yp)q(e)j +Fu(is)e(not)g Ft(NULL)p Fu(,)f(the)g(t)o(yp)q(e)h(of)f(the)h(ob)s(ject) +f(is)h(returned)g(in)g(the)f Ft(int)195 1247 y Fu(v)m(ariable)f(it)e(p) +q(oin)o(ts)h(to)e(\(one)h(of)g Ft(ISFUNC)p Fu(,)f Ft(ISKMAP)p +Fu(,)g(or)h Ft(ISMACR)p Fu(\).)1762 1347 y(F)l(unction)-1861 +b Fi(char)20 b(**)f Fh(rl)p 312 1347 V 21 w(in)n(v)n(oking)p +541 1347 V 23 w(k)n(eyseqs)k Fg(\()p Ft(rl_command_func_t)13 +b(*function)p Fg(\))195 1402 y Fu(Return)i(an)h(arra)o(y)e(of)h +(strings)h(represen)o(ting)g(the)g(k)o(ey)f(sequences)i(used)f(to)f(in) +o(v)o(ok)o(e)h Fk(function)g Fu(in)195 1457 y(the)f(curren)o(t)g(k)o +(eymap.)1762 1557 y(F)l(unction)-1861 b Fi(char)20 b(**)f +Fh(rl)p 312 1557 V 21 w(in)n(v)n(oking)p 541 1557 V 23 +w(k)n(eyseqs)p 750 1557 V 21 w(in)p 818 1557 V 22 w(map)i +Fg(\()p Ft(rl_command_func_t)283 1612 y(*function,)13 +b(Keymap)i(map)p Fg(\))195 1667 y Fu(Return)g(an)h(arra)o(y)e(of)h +(strings)h(represen)o(ting)g(the)g(k)o(ey)f(sequences)i(used)f(to)f(in) +o(v)o(ok)o(e)h Fk(function)g Fu(in)195 1722 y(the)f(k)o(eymap)g +Fk(map)p Fu(.)1762 1822 y(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 1822 V 21 w(function)p 467 1822 V 21 w(dump)r(er)g +Fg(\()p Ft(int)15 b(readable)p Fg(\))195 1876 y Fu(Prin)o(t)g(the)f +(readline)j(function)e(names)g(and)f(the)h(k)o(ey)g(sequences)g(curren) +o(tly)g(b)q(ound)h(to)e(them)h(to)195 1931 y Ft(rl_outstream)p +Fu(.)j(If)c Fk(readable)j Fu(is)d(non-zero,)g(the)g(list)g(is)h +(formatted)d(in)j(suc)o(h)f(a)f(w)o(a)o(y)g(that)g(it)h(can)195 +1986 y(b)q(e)i(made)f(part)g(of)f(an)i Ft(inputrc)e Fu(\014le)i(and)f +(re-read.)1762 2086 y(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 2086 V 21 w(list)p 337 2086 V 22 w(funmap)p +550 2086 V 18 w(names)h Fg(\()p Ft(void)p Fg(\))195 2141 +y Fu(Prin)o(t)15 b(the)g(names)h(of)e(all)j(bindable)g(Readline)f +(functions)g(to)f Ft(rl_outstream)p Fu(.)1762 2241 y(F)l(unction)-1861 +b Fi(const)20 b(char)g(**)f Fh(rl)p 462 2241 V 21 w(funmap)p +674 2241 V 18 w(names)i Fg(\()p Ft(void)p Fg(\))195 2296 +y Fu(Return)13 b(a)f(NULL)i(terminated)g(arra)o(y)d(of)i(kno)o(wn)g +(function)g(names.)20 b(The)13 b(arra)o(y)f(is)h(sorted.)19 +b(The)195 2351 y(arra)o(y)11 b(itself)j(is)f(allo)q(cated,)h(but)f(not) +f(the)h(strings)f(inside.)21 b(Y)l(ou)13 b(should)h Ft(free\(\))d +Fu(the)i(arra)o(y)e(when)195 2405 y(y)o(ou)k(are)g(done,)g(but)g(not)g +(the)g(p)q(oin)o(ters.)1762 2506 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 2506 V 21 w(add)p 328 2506 +V 20 w(funmap)p 539 2506 V 18 w(en)n(try)j Fg(\()p Ft(const)14 +b(char)h(*name,)f(rl_command_func_t)283 2560 y(*function)p +Fg(\))195 2615 y Fu(Add)j Fk(name)i Fu(to)d(the)g(list)h(of)f(bindable) +j(Readline)f(command)e(names,)g(and)h(mak)o(e)f Fk(function)h +Fu(the)195 2670 y(function)f(to)f(b)q(e)g(called)i(when)f +Fk(name)i Fu(is)d(in)o(v)o(ok)o(ed.)p eop +%%Page: 32 34 +32 33 bop 75 -58 a Fu(32)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fj(2.4.5)30 b(Allo)n(wing)21 b(Undoing)137 251 +y Fu(Supp)q(orting)14 b(the)g(undo)f(command)g(is)h(a)f(painless)h +(thing,)g(and)f(mak)o(es)g(y)o(our)f(functions)i(m)o(uc)o(h)f(more)75 +306 y(useful.)21 b(It)15 b(is)h(certainly)g(easy)f(to)g(try)f +(something)i(if)f(y)o(ou)g(kno)o(w)g(y)o(ou)g(can)g(undo)h(it.)137 +378 y(If)21 b(y)o(our)f(function)h(simply)h(inserts)f(text)e(once,)j +(or)e(deletes)h(text)f(once,)i(and)f(uses)f Ft(rl_insert_)75 +433 y(text\(\))13 b Fu(or)h Ft(rl_delete_text\(\))d Fu(to)j(do)f(it,)h +(then)h(undoing)g(is)f(already)g(done)h(for)e(y)o(ou)h(automatically)l +(.)137 506 y(If)d(y)o(ou)f(do)g(m)o(ultiple)i(insertions)f(or)f(m)o +(ultiple)i(deletions,)g(or)e(an)o(y)g(com)o(bination)h(of)f(these)g(op) +q(erations,)75 560 y(y)o(ou)19 b(should)h(group)e(them)h(together)g(in) +o(to)g(one)g(op)q(eration.)31 b(This)20 b(is)f(done)h(with)f +Ft(rl_begin_undo_)75 615 y(group\(\))14 b Fu(and)i Ft +(rl_end_undo_group\(\))p Fu(.)137 688 y(The)g(t)o(yp)q(es)f(of)g(ev)o +(en)o(ts)g(that)f(can)h(b)q(e)h(undone)g(are:)195 757 +y Ft(enum)23 b(undo_code)g({)h(UNDO_DELETE,)e(UNDO_INSERT,)g +(UNDO_BEGIN,)g(UNDO_END)h(};)137 830 y Fu(Notice)16 b(that)e +Ft(UNDO_DELETE)g Fu(means)h(to)g(insert)g(some)g(text,)f(and)i +Ft(UNDO_INSERT)d Fu(means)i(to)g(delete)75 885 y(some)e(text.)19 +b(That)14 b(is,)g(the)g(undo)g(co)q(de)g(tells)h(what)e(to)h(undo,)g +(not)f(ho)o(w)g(to)g(undo)i(it.)k Ft(UNDO_BEGIN)13 b +Fu(and)75 939 y Ft(UNDO_END)h Fu(are)h(tags)f(added)i(b)o(y)f +Ft(rl_begin_undo_group\(\))d Fu(and)k Ft(rl_end_undo_group\(\))p +Fu(.)1762 1072 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 1072 18 3 v 21 w(b)r(egin)p 372 1072 V 20 w(undo)p +517 1072 V 20 w(group)h Fg(\()p Ft(void)p Fg(\))195 1127 +y Fu(Begins)16 b(sa)o(ving)g(undo)g(information)f(in)i(a)e(group)g +(construct.)20 b(The)c(undo)g(information)g(usually)195 +1182 y(comes)21 b(from)f(calls)i(to)e Ft(rl_insert_text\(\))e +Fu(and)j Ft(rl_delete_text\(\))p Fu(,)f(but)h(could)g(b)q(e)h(the)195 +1237 y(result)16 b(of)e(calls)j(to)d Ft(rl_add_undo\(\))p +Fu(.)1762 1370 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 1370 V 21 w(end)p 326 1370 V 20 w(undo)p 471 1370 +V 20 w(group)h Fg(\()p Ft(void)p Fg(\))195 1424 y Fu(Closes)15 +b(the)f(curren)o(t)h(undo)g(group)f(started)g(with)g +Ft(rl_begin_undo_group)f(\(\))p Fu(.)19 b(There)c(should)195 +1479 y(b)q(e)h(one)f(call)i(to)d Ft(rl_end_undo_group\(\))f +Fu(for)h(eac)o(h)h(call)i(to)d Ft(rl_begin_undo_group\(\))p +Fu(.)1762 1612 y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p +241 1612 V 21 w(add)p 354 1612 V 20 w(undo)i Fg(\()p +Ft(enum)14 b(undo_code)g(what,)g(int)h(start,)g(int)f(end,)h(char)283 +1667 y(*text)p Fg(\))195 1722 y Fu(Remem)o(b)q(er)i(ho)o(w)f(to)h(undo) +g(an)g(ev)o(en)o(t)g(\(according)g(to)g Fk(what)q Fu(\).)24 +b(The)17 b(a\013ected)g(text)f(runs)i(from)195 1776 y +Fk(start)d Fu(to)g Fk(end)p Fu(,)g(and)g(encompasses)h +Fk(text)p Fu(.)1762 1909 y(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 1909 V 21 w(free)p 356 1909 V 20 w(undo)p +501 1909 V 20 w(list)k Fg(\()p Ft(void)p Fg(\))195 1964 +y Fu(F)l(ree)15 b(the)h(existing)g(undo)f(list.)1762 +2097 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 2097 +V 21 w(do)p 297 2097 V 20 w(undo)i Fg(\()p Ft(void)p +Fg(\))195 2152 y Fu(Undo)12 b(the)f(\014rst)g(thing)h(on)g(the)f(undo)h +(list.)19 b(Returns)11 b Ft(0)h Fu(if)g(there)f(w)o(as)g(nothing)h(to)e +(undo,)j(non-zero)195 2206 y(if)j(something)f(w)o(as)f(undone.)137 +2309 y(Finally)l(,)j(if)f(y)o(ou)f(neither)i(insert)f(nor)f(delete)i +(text,)e(but)g(directly)i(mo)q(dify)f(the)g(existing)g(text)g(\(e.g.,) +75 2364 y(c)o(hange)j(its)h(case\),)g(call)g Ft(rl_modifying\(\))e +Fu(once,)i(just)f(b)q(efore)h(y)o(ou)f(mo)q(dify)h(the)f(text.)32 +b(Y)l(ou)20 b(m)o(ust)75 2419 y(supply)c(the)g(indices)h(of)e(the)g +(text)g(range)g(that)f(y)o(ou)h(are)g(going)g(to)g(mo)q(dify)l(.)1762 +2552 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 2552 +V 21 w(mo)r(difying)h Fg(\()p Ft(int)15 b(start,)f(int)h(end)p +Fg(\))195 2606 y Fu(T)l(ell)22 b(Readline)f(to)e(sa)o(v)o(e)h(the)g +(text)g(b)q(et)o(w)o(een)g Fk(start)g Fu(and)g Fk(end)j +Fu(as)c(a)h(single)h(undo)g(unit.)35 b(It)20 b(is)195 +2661 y(assumed)15 b(that)g(y)o(ou)g(will)i(subsequen)o(tly)f(mo)q(dify) +g(that)e(text.)p eop +%%Page: 33 35 +33 34 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(33)75 149 y Fj(2.4.6)30 b(Redispla)n(y)1762 +302 y Fu(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 +302 18 3 v 21 w(redispla)n(y)k Fg(\()p Ft(void)p Fg(\))195 +356 y Fu(Change)19 b(what's)f(displa)o(y)o(ed)i(on)f(the)g(screen)g(to) +f(re\015ect)i(the)f(curren)o(t)f(con)o(ten)o(ts)h(of)f +Ft(rl_line_)195 411 y(buffer)p Fu(.)1762 534 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 534 V 21 w(forced)p 390 534 +V 20 w(up)r(date)p 584 534 V 20 w(displa)n(y)k Fg(\()p +Ft(void)p Fg(\))195 589 y Fu(F)l(orce)c(the)g(line)h(to)e(b)q(e)i(up)q +(dated)f(and)g(redispla)o(y)o(ed,)i(whether)e(or)g(not)f(Readline)i +(thinks)g(the)195 644 y(screen)16 b(displa)o(y)g(is)g(correct.)1762 +767 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 767 +V 21 w(on)p 297 767 V 20 w(new)p 416 767 V 21 w(line)k +Fg(\()p Ft(void)p Fg(\))195 822 y Fu(T)l(ell)16 b(the)f(up)q(date)h +(functions)g(that)e(w)o(e)g(ha)o(v)o(e)h(mo)o(v)o(ed)f(on)o(to)g(a)h +(new)g(\(empt)o(y\))f(line,)i(usually)h(after)195 877 +y(ouputting)f(a)e(newline.)1762 1000 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1000 V 21 w(on)p 297 1000 V +20 w(new)p 416 1000 V 21 w(line)p 525 1000 V 22 w(with)p +657 1000 V 22 w(prompt)h Fg(\()p Ft(void)p Fg(\))195 +1055 y Fu(T)l(ell)14 b(the)e(up)q(date)h(functions)g(that)f(w)o(e)g(ha) +o(v)o(e)g(mo)o(v)o(ed)f(on)o(to)h(a)g(new)g(line,)i(with)f +Fk(rl)p 1556 1055 14 2 v 17 w(prompt)g Fu(already)195 +1109 y(displa)o(y)o(ed.)21 b(This)15 b(could)g(b)q(e)g(used)g(b)o(y)f +(applications)i(that)e(w)o(an)o(t)f(to)h(output)g(the)g(prompt)g +(string)195 1164 y(themselv)o(es,)g(but)g(still)h(need)g(Readline)g(to) +e(kno)o(w)g(the)h(prompt)f(string)h(length)g(for)f(redispla)o(y)l(.)21 +b(It)195 1219 y(should)16 b(b)q(e)g(used)g(after)e(setting)i +Fk(rl)p 795 1219 V 16 w(already)p 956 1219 V 17 w(prompted)p +Fu(.)1762 1342 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 1342 18 3 v 21 w(reset)p 357 1342 V 20 w(line)p 465 +1342 V 23 w(state)j Fg(\()p Ft(void)p Fg(\))195 1397 +y Fu(Reset)17 b(the)g(displa)o(y)i(state)d(to)h(a)g(clean)h(state)f +(and)g(redispla)o(y)i(the)e(curren)o(t)g(line)i(starting)e(on)g(a)195 +1452 y(new)e(line.)1762 1575 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 1575 V 21 w(crlf)j Fg(\()p Ft(void)p Fg(\))195 +1630 y Fu(Mo)o(v)o(e)14 b(the)h(cursor)g(to)g(the)g(start)f(of)h(the)g +(next)g(screen)h(line.)1762 1753 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1753 V 21 w(sho)n(w)p 359 1753 +V 20 w(c)n(har)j Fg(\()p Ft(int)14 b(c)p Fg(\))195 1807 +y Fu(Displa)o(y)j(c)o(haracter)e Fk(c)20 b Fu(on)c Ft(rl_outstream)p +Fu(.)21 b(If)c(Readline)g(has)f(not)g(b)q(een)i(set)e(to)f(displa)o(y)j +(meta)195 1862 y(c)o(haracters)12 b(directly)l(,)j(this)e(will)i(con)o +(v)o(ert)d(meta)h(c)o(haracters)f(to)g(a)h(meta-pre\014xed)g(k)o(ey)g +(sequence.)195 1917 y(This)j(is)f(in)o(tended)i(for)e(use)g(b)o(y)g +(applications)i(whic)o(h)f(wish)g(to)f(do)g(their)g(o)o(wn)g(redispla)o +(y)l(.)1762 2040 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 2040 V 21 w(message)g Fg(\()p Ft(const)14 b(char)h(*,)g(...)p +Fg(\))195 2095 y Fu(The)c(argumen)o(ts)e(are)h(a)g(format)f(string)h +(as)g(w)o(ould)h(b)q(e)g(supplied)i(to)c Ft(printf)p +Fu(,)h(p)q(ossibly)i(con)o(taining)195 2150 y(con)o(v)o(ersion)22 +b(sp)q(eci\014cations)i(suc)o(h)f(as)e(`)p Ft(\045d)p +Fu(',)i(and)f(an)o(y)g(additional)h(argumen)o(ts)e(necessary)i(to)195 +2205 y(satisfy)d(the)h(con)o(v)o(ersion)g(sp)q(eci\014cations.)38 +b(The)21 b(resulting)h(string)e(is)i(displa)o(y)o(ed)g(in)f(the)g +Fk(ec)o(ho)195 2259 y(area)p Fu(.)e(The)d(ec)o(ho)f(area)g(is)g(also)g +(used)h(to)f(displa)o(y)h(n)o(umeric)g(argumen)o(ts)f(and)g(searc)o(h)g +(strings.)1762 2382 y(F)l(unction)-1861 b Fi(int)20 b +Fh(rl)p 215 2382 V 21 w(clear)p 354 2382 V 21 w(message)h +Fg(\()p Ft(void)p Fg(\))195 2437 y Fu(Clear)15 b(the)h(message)e(in)i +(the)g(ec)o(ho)f(area.)1762 2560 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 2560 V 21 w(sa)n(v)n(e)p 365 +2560 V 21 w(prompt)h Fg(\()p Ft(void)p Fg(\))195 2615 +y Fu(Sa)o(v)o(e)g(the)h(lo)q(cal)g(Readline)h(prompt)e(displa)o(y)i +(state)e(in)h(preparation)f(for)g(displa)o(ying)j(a)d(new)195 +2670 y(message)15 b(in)h(the)f(message)g(area)f(with)i +Ft(rl_message\(\))p Fu(.)p eop +%%Page: 34 36 +34 35 bop 75 -58 a Fu(34)1299 b(GNU)15 b(Readline)h(Library)1762 +149 y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 149 +18 3 v 21 w(restore)p 436 149 V 20 w(prompt)g Fg(\()p +Ft(void)p Fg(\))195 204 y Fu(Restore)g(the)i(lo)q(cal)g(Readline)h +(prompt)e(displa)o(y)h(state)f(sa)o(v)o(ed)g(b)o(y)g(the)g(most)g +(recen)o(t)g(call)i(to)195 259 y Ft(rl_save_prompt)p +Fu(.)1762 369 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 369 V 21 w(expand)p 416 369 V 20 w(prompt)h Fg(\()p +Ft(char)14 b(*prompt)p Fg(\))195 423 y Fu(Expand)22 b(an)o(y)f(sp)q +(ecial)i(c)o(haracter)e(sequences)h(in)g Fk(prompt)g +Fu(and)g(set)f(up)h(the)f(lo)q(cal)i(Readline)195 478 +y(prompt)17 b(redispla)o(y)i(v)m(ariables.)30 b(This)18 +b(function)h(is)f(called)i(b)o(y)e Ft(readline\(\))p +Fu(.)26 b(It)18 b(ma)o(y)f(also)h(b)q(e)195 533 y(called)12 +b(to)e(expand)h(the)g(primary)g(prompt)f(if)h(the)f Ft +(rl_on_new_line_with_prompt\(\))d Fu(function)195 588 +y(or)12 b Ft(rl_already_prompted)e Fu(v)m(ariable)k(is)g(used.)19 +b(It)13 b(returns)g(the)f(n)o(um)o(b)q(er)i(of)e(visible)j(c)o +(haracters)195 643 y(on)g(the)g(last)h(line)g(of)f(the)g(\(p)q(ossibly) +i(m)o(ulti-line\))g(prompt.)1762 752 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 752 V 21 w(set)p 307 752 V +20 w(prompt)h Fg(\()p Ft(const)14 b(char)h(*prompt)p +Fg(\))195 807 y Fu(Mak)o(e)e(Readline)i(use)e Fk(prompt)h +Fu(for)f(subsequen)o(t)h(redispla)o(y)l(.)21 b(This)14 +b(calls)g Ft(rl_expand_prompt\(\))195 862 y Fu(to)h(expand)g(the)h +(prompt)e(and)i(sets)f Ft(rl_prompt)f Fu(to)g(the)h(result.)75 +970 y Fj(2.4.7)30 b(Mo)r(difying)20 b(T)-5 b(ext)1762 +1108 y Fu(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 +1108 V 21 w(insert)p 378 1108 V 21 w(text)k Fg(\()p Ft(const)14 +b(char)g(*text)p Fg(\))195 1163 y Fu(Insert)i Fk(text)g +Fu(in)o(to)g(the)g(line)h(at)f(the)g(curren)o(t)f(cursor)h(p)q +(osition.)22 b(Returns)16 b(the)g(n)o(um)o(b)q(er)g(of)f(c)o(har-)195 +1218 y(acters)g(inserted.)1762 1328 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1328 V 21 w(delete)p 383 1328 +V 22 w(text)k Fg(\()p Ft(int)14 b(start,)h(int)f(end)p +Fg(\))195 1382 y Fu(Delete)19 b(the)g(text)g(b)q(et)o(w)o(een)g +Fk(start)g Fu(and)g Fk(end)i Fu(in)f(the)f(curren)o(t)f(line.)33 +b(Returns)18 b(the)h(n)o(um)o(b)q(er)g(of)195 1437 y(c)o(haracters)14 +b(deleted.)1762 1547 y(F)l(unction)-1861 b Fi(char)20 +b(*)f Fh(rl)p 286 1547 V 21 w(cop)n(y)p 421 1547 V 21 +w(text)24 b Fg(\()p Ft(int)14 b(start,)h(int)g(end)p +Fg(\))195 1602 y Fu(Return)g(a)g(cop)o(y)g(of)g(the)g(text)f(b)q(et)o +(w)o(een)i Fk(start)f Fu(and)g Fk(end)j Fu(in)e(the)f(curren)o(t)g +(line.)1762 1711 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 1711 V 21 w(kill)p 311 1711 V 23 w(text)k Fg(\()p +Ft(int)14 b(start,)h(int)g(end)p Fg(\))195 1766 y Fu(Cop)o(y)i(the)g +(text)f(b)q(et)o(w)o(een)i Fk(start)f Fu(and)g Fk(end)i +Fu(in)f(the)f(curren)o(t)g(line)i(to)e(the)g(kill)i(ring,)e(app)q +(ending)195 1821 y(or)f(prep)q(ending)k(to)c(the)h(last)g(kill)i(if)e +(the)g(last)g(command)g(w)o(as)f(a)h(kill)i(command.)25 +b(The)17 b(text)f(is)195 1876 y(deleted.)26 b(If)17 b +Fk(start)g Fu(is)g(less)g(than)g Fk(end)p Fu(,)g(the)g(text)g(is)g(app) +q(ended,)h(otherwise)f(prep)q(ended.)27 b(If)17 b(the)195 +1930 y(last)e(command)g(w)o(as)g(not)f(a)h(kill,)i(a)e(new)g(kill)i +(ring)f(slot)f(is)h(used.)1762 2040 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 2040 V 21 w(push)p 355 2040 +V 19 w(macro)p 529 2040 V 19 w(input)k Fg(\()p Ft(char)14 +b(*macro)p Fg(\))195 2095 y Fu(Cause)g Fk(macro)i Fu(to)d(b)q(e)i +(inserted)g(in)o(to)f(the)g(line,)i(as)e(if)g(it)h(had)f(b)q(een)h(in)o +(v)o(ok)o(ed)g(b)o(y)f(a)g(k)o(ey)g(b)q(ound)h(to)195 +2150 y(a)g(macro.)k(Not)c(esp)q(ecially)i(useful;)f(use)g +Ft(rl_insert_text\(\))d Fu(instead.)75 2257 y Fj(2.4.8)30 +b(Character)21 b(Input)1762 2396 y Fu(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 2396 V 21 w(read)p 346 2396 +V 20 w(k)n(ey)k Fg(\()p Ft(void)p Fg(\))195 2451 y Fu(Return)14 +b(the)h(next)g(c)o(haracter)f(a)o(v)m(ailable)i(from)e(Readline's)i +(curren)o(t)f(input)g(stream.)k(This)d(han-)195 2506 +y(dles)f(input)g(inserted)f(in)o(to)g(the)g(input)h(stream)e(via)h +Fk(rl)p 1117 2506 14 2 v 17 w(p)q(ending)p 1290 2506 +V 18 w(input)i Fu(\(see)e(Section)h(2.3)e([Read-)195 +2560 y(line)21 b(V)l(ariables],)g(page)f(24\))f(and)h +Ft(rl_stuff_char\(\))p Fu(,)e(macros,)h(and)h(c)o(haracters)f(read)h +(from)195 2615 y(the)d(k)o(eyb)q(oard.)25 b(While)19 +b(w)o(aiting)e(for)f(input,)j(this)e(function)h(will)h(call)f(an)o(y)e +(function)i(assigned)195 2670 y(to)d(the)g Ft(rl_event_hook)e +Fu(v)m(ariable.)p eop +%%Page: 35 37 +35 36 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(35)1762 149 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 149 18 3 v 21 w(getc)j Fg(\()p Ft(FILE)14 +b(*stream)p Fg(\))195 204 y Fu(Return)c(the)h(next)g(c)o(haracter)f(a)o +(v)m(ailable)i(from)e Fk(stream)p Fu(,)g(whic)o(h)i(is)f(assumed)f(to)g +(b)q(e)i(the)e(k)o(eyb)q(oard.)1762 342 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 342 V 21 w(stu\013)p 346 342 +V 20 w(c)n(har)j Fg(\()p Ft(int)15 b(c)p Fg(\))195 397 +y Fu(Insert)i Fk(c)i Fu(in)o(to)d(the)h(Readline)h(input)f(stream.)23 +b(It)16 b(will)i(b)q(e)f Ft(")p Fu(read)p Ft(")g Fu(b)q(efore)f +(Readline)i(attempts)195 452 y(to)13 b(read)g(c)o(haracters)g(from)f +(the)i(terminal)g(with)g Ft(rl_read_key\(\))p Fu(.)j(Up)d(to)f(512)f(c) +o(haracters)h(ma)o(y)195 507 y(b)q(e)j(pushed)g(bac)o(k.)k +Ft(rl_stuff_char)14 b Fu(returns)h(1)g(if)h(the)f(c)o(haracter)g(w)o +(as)f(successfully)j(inserted;)195 562 y(0)e(otherwise.)1762 +700 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 700 +V 21 w(execute)p 423 700 V 22 w(next)j Fg(\()p Ft(int)15 +b(c)p Fg(\))195 754 y Fu(Mak)o(e)i Fk(c)k Fu(b)q(e)d(the)g(next)g +(command)g(to)f(b)q(e)i(executed)f(when)h Ft(rl_read_key\(\))d +Fu(is)i(called.)29 b(This)195 809 y(sets)15 b Fk(rl)p +317 809 14 2 v 17 w(p)q(ending)p 490 809 V 18 w(input)p +Fu(.)1762 947 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 947 18 3 v 21 w(clear)p 354 947 V 21 w(p)r(ending)p +575 947 V 21 w(input)j Fg(\()p Ft(void)p Fg(\))195 1002 +y Fu(Unset)f Fk(rl)p 365 1002 14 2 v 16 w(p)q(ending)p +537 1002 V 19 w(input)p Fu(,)h(e\013ectiv)o(ely)g(negating)e(the)h +(e\013ect)f(of)g(an)o(y)h(previous)g(call)h(to)d Ft(rl_)195 +1057 y(execute_next\(\))p Fu(.)29 b(This)19 b(w)o(orks)f(only)h(if)h +(the)e(p)q(ending)j(input)f(has)f(not)f(already)h(b)q(een)h(read)195 +1112 y(with)c Ft(rl_read_key\(\))p Fu(.)1762 1250 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1250 18 3 v 21 w(set)p 307 +1250 V 20 w(k)n(eyb)r(oard)p 558 1250 V 21 w(input)p +712 1250 V 21 w(timeout)i Fg(\()p Ft(int)15 b(u)p Fg(\))195 +1305 y Fu(While)21 b(w)o(aiting)g(for)e(k)o(eyb)q(oard)h(input)h(in)g +Ft(rl_read_key\(\))p Fu(,)e(Readline)i(will)h(w)o(ait)e(for)f +Fk(u)h Fu(mi-)195 1360 y(croseconds)h(for)e(input)j(b)q(efore)f +(calling)h(an)o(y)e(function)h(assigned)g(to)f Ft(rl_event_hook)p +Fu(.)34 b(The)195 1414 y(default)16 b(w)o(aiting)f(p)q(erio)q(d)i(is)e +(one-ten)o(th)h(of)e(a)h(second.)21 b(Returns)14 b(the)i(old)f(timeout) +h(v)m(alue.)75 1540 y Fj(2.4.9)30 b(T)-5 b(erminal)20 +b(Managemen)n(t)1762 1708 y Fu(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 1708 V 21 w(prep)p 376 1708 V 20 w(terminal)j +Fg(\()p Ft(int)14 b(meta_flag)p Fg(\))195 1762 y Fu(Mo)q(dify)22 +b(the)f(terminal)h(settings)f(for)g(Readline's)h(use,)h(so)d +Ft(readline\(\))g Fu(can)i(read)f(a)g(single)195 1817 +y(c)o(haracter)15 b(at)g(a)g(time)i(from)d(the)i(k)o(eyb)q(oard.)22 +b(The)16 b Fk(meta)p 1192 1817 14 2 v 15 w(\015ag)k Fu(argumen)o(t)15 +b(should)h(b)q(e)h(non-zero)195 1872 y(if)f(Readline)g(should)g(read)f +(eigh)o(t-bit)i(input.)1762 2010 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 2010 18 3 v 21 w(deprep)p +434 2010 V 20 w(terminal)j Fg(\()p Ft(void)p Fg(\))195 +2065 y Fu(Undo)16 b(the)g(e\013ects)f(of)h Ft(rl_prep_terminal\(\))p +Fu(,)d(lea)o(ving)k(the)e(terminal)i(in)g(the)e(state)g(in)i(whic)o(h) +195 2120 y(it)e(w)o(as)g(b)q(efore)g(the)h(most)e(recen)o(t)h(call)i +(to)d Ft(rl_prep_terminal\(\))p Fu(.)1762 2258 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 2258 V 21 w(tt)n(y)p 334 2258 +V 22 w(set)p 427 2258 V 20 w(default)p 620 2258 V 21 +w(bindings)k Fg(\()p Ft(Keymap)14 b(kmap)p Fg(\))195 +2313 y Fu(Read)k(the)h(op)q(erating)f(system's)g(terminal)h(editing)h +(c)o(haracters)e(\(as)f(w)o(ould)i(b)q(e)g(displa)o(y)o(ed)h(b)o(y)195 +2367 y Ft(stty)p Fu(\))14 b(to)h(their)h(Readline)g(equiv)m(alen)o(ts.) +22 b(The)15 b(bindings)i(are)e(p)q(erformed)g(in)h Fk(kmap)p +Fu(.)1762 2506 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 2506 V 21 w(reset)p 357 2506 V 20 w(terminal)j Fg(\()p +Ft(const)15 b(char)f(*terminal_name)p Fg(\))195 2560 +y Fu(Reinitialize)h(Readline's)e(idea)g(of)f(the)g(terminal)h(settings) +g(using)g Fk(terminal)p 1491 2560 14 2 v 17 w(name)h +Fu(as)e(the)h(termi-)195 2615 y(nal)k(t)o(yp)q(e)f(\(e.g.,)f +Ft(vt100)p Fu(\).)21 b(If)c Fk(terminal)p 878 2615 V +17 w(name)i Fu(is)d Ft(NULL)p Fu(,)g(the)g(v)m(alue)h(of)f(the)g +Ft(TERM)g Fu(en)o(vironmen)o(t)195 2670 y(v)m(ariable)h(is)e(used.)p +eop +%%Page: 36 38 +36 37 bop 75 -58 a Fu(36)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fj(2.4.10)29 b(Utilit)n(y)22 b(F)-5 b(unctions)1762 +287 y Fu(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 +287 18 3 v 21 w(replace)p 438 287 V 22 w(line)k Fg(\()p +Ft(const)14 b(char)h(*text,)f(int)h(clear_undo)p Fg(\))195 +342 y Fu(Replace)20 b(the)g(con)o(ten)o(ts)f(of)g Ft(rl_line_buffer)f +Fu(with)i Fk(text)p Fu(.)33 b(The)20 b(p)q(oin)o(t)g(and)g(mark)f(are)h +(pre-)195 397 y(serv)o(ed,)13 b(if)h(p)q(ossible.)21 +b(If)13 b Fk(clear)p 712 397 14 2 v 17 w(undo)j Fu(is)d(non-zero,)h +(the)f(undo)g(list)h(asso)q(ciated)g(with)f(the)g(curren)o(t)195 +452 y(line)k(is)f(cleared.)1762 561 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 561 18 3 v 21 w(extend)p 404 +561 V 21 w(line)p 513 561 V 22 w(bu\013er)j Fg(\()p Ft(int)15 +b(len)p Fg(\))195 616 y Fu(Ensure)g(that)g Ft(rl_line_buffer)e +Fu(has)i(enough)g(space)h(to)e(hold)i Fk(len)g Fu(c)o(haracters,)e(p)q +(ossibly)i(real-)195 670 y(lo)q(cating)g(it)f(if)h(necessary)l(.)1762 +779 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 779 +V 21 w(initiali)q(z)q(e)26 b Fg(\()p Ft(void)p Fg(\))195 +834 y Fu(Initialize)21 b(or)d(re-initialize)k(Readline's)d(in)o(ternal) +h(state.)28 b(It's)18 b(not)g(strictly)h(necessary)g(to)f(call)195 +889 y(this;)d Ft(readline\(\))f Fu(calls)i(it)g(b)q(efore)f(reading)h +(an)o(y)f(input.)1762 998 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 998 V 21 w(ding)j Fg(\()p Ft(void)p Fg(\))195 +1053 y Fu(Ring)15 b(the)g(terminal)h(b)q(ell,)h(ob)q(eying)f(the)g +(setting)f(of)g Ft(bell-style)p Fu(.)1762 1162 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1162 V 21 w(alphab)r(etic)k +Fg(\()p Ft(int)14 b(c)p Fg(\))195 1217 y Fu(Return)h(1)g(if)g +Fk(c)j Fu(is)e(an)f(alphab)q(etic)i(c)o(haracter.)1762 +1325 y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 1325 +V 21 w(displa)n(y)p 435 1325 V 22 w(matc)n(h)p 611 1325 +V 20 w(list)25 b Fg(\()p Ft(char)14 b(**matches,)g(int)g(len,)h(int)g +(max)p Fg(\))195 1380 y Fu(A)i(con)o(v)o(enience)i(function)f(for)f +(displa)o(ying)i(a)e(list)h(of)e(strings)h(in)i(columnar)e(format)f(on) +h(Read-)195 1435 y(line's)h(output)f(stream.)23 b Ft(matches)16 +b Fu(is)h(the)g(list)h(of)e(strings,)h(in)g(argv)f(format,)g(suc)o(h)h +(as)f(a)h(list)g(of)195 1490 y(completion)c(matc)o(hes.)19 +b Ft(len)11 b Fu(is)i(the)f(n)o(um)o(b)q(er)h(of)e(strings)h(in)h +Ft(matches)p Fu(,)f(and)g Ft(max)g Fu(is)g(the)h(length)f(of)195 +1545 y(the)h(longest)g(string)g(in)h Ft(matches)p Fu(.)19 +b(This)13 b(function)h(uses)f(the)h(setting)f(of)f Ft +(print-completions-)195 1599 y(horizontally)k Fu(to)i(select)h(ho)o(w)e +(the)i(matc)o(hes)e(are)h(displa)o(y)o(ed)h(\(see)g(Section)g(1.3.1)d +([Readline)195 1654 y(Init)g(File)g(Syn)o(tax],)e(page)h(4\).)137 +1742 y(The)i(follo)o(wing)f(are)g(implemen)o(ted)i(as)e(macros,)f +(de\014ned)i(in)g Ft(chardefs.h)p Fu(.)k(Applications)d(should)75 +1796 y(refrain)d(from)g(using)h(them.)1762 1905 y(F)l(unction)-1861 +b Fi(int)p 176 1905 V 40 w Fh(rl)p 235 1905 V 21 w(upp)r(ercase)p +506 1905 V 20 w(p)23 b Fg(\()p Ft(int)14 b(c)p Fg(\))195 +1960 y Fu(Return)h(1)g(if)g Fk(c)j Fu(is)e(an)f(upp)q(ercase)i(alphab)q +(etic)f(c)o(haracter.)1762 2069 y(F)l(unction)-1861 b +Fi(int)p 176 2069 V 40 w Fh(rl)p 235 2069 V 21 w(lo)n(w)n(ercase)p +489 2069 V 23 w(p)22 b Fg(\()p Ft(int)15 b(c)p Fg(\))195 +2124 y Fu(Return)g(1)g(if)g Fk(c)j Fu(is)e(a)f(lo)o(w)o(ercase)g +(alphab)q(etic)i(c)o(haracter.)1762 2233 y(F)l(unction)-1861 +b Fi(int)p 176 2233 V 40 w Fh(rl)p 235 2233 V 21 w(digit)p +369 2233 V 22 w(p)23 b Fg(\()p Ft(int)14 b(c)p Fg(\))195 +2288 y Fu(Return)h(1)g(if)g Fk(c)j Fu(is)e(a)f(n)o(umeric)h(c)o +(haracter.)1762 2397 y(F)l(unction)-1861 b Fi(int)p 176 +2397 V 40 w Fh(rl)p 235 2397 V 21 w(to)p 307 2397 V 21 +w(upp)r(er)21 b Fg(\()p Ft(int)15 b(c)p Fg(\))195 2451 +y Fu(If)d Fk(c)j Fu(is)d(a)g(lo)o(w)o(ercase)f(alphab)q(etic)j(c)o +(haracter,)d(return)h(the)g(corresp)q(onding)h(upp)q(ercase)g(c)o +(haracter.)1762 2560 y(F)l(unction)-1861 b Fi(int)p 176 +2560 V 40 w Fh(rl)p 235 2560 V 21 w(to)p 307 2560 V 21 +w(lo)n(w)n(er)24 b Fg(\()p Ft(int)15 b(c)p Fg(\))195 +2615 y Fu(If)g Fk(c)i Fu(is)e(an)f(upp)q(ercase)i(alphab)q(etic)g(c)o +(haracter,)e(return)g(the)h(corresp)q(onding)g(lo)o(w)o(ercase)f(c)o +(harac-)195 2670 y(ter.)p eop +%%Page: 37 39 +37 38 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(37)1762 149 y(F)l(unction)-1861 b Fi(int)p +176 149 18 3 v 40 w Fh(rl)p 235 149 V 21 w(digit)p 369 +149 V 22 w(v)m(alue)24 b Fg(\()p Ft(int)15 b(c)p Fg(\))195 +204 y Fu(If)g Fk(c)k Fu(is)c(a)g(n)o(um)o(b)q(er,)g(return)g(the)h(v)m +(alue)g(it)g(represen)o(ts.)75 325 y Fj(2.4.11)29 b(Miscellaneous)22 +b(F)-5 b(unctions)1762 484 y Fu(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 484 V 21 w(macro)p 391 484 V 19 w(bind)j +Fg(\()p Ft(const)14 b(char)g(*keyseq,)h(const)f(char)h(*macro,)283 +539 y(Keymap)f(map)p Fg(\))195 593 y Fu(Bind)f(the)f(k)o(ey)f(sequence) +i Fk(k)o(eyseq)g Fu(to)e(in)o(v)o(ok)o(e)g(the)h(macro)f +Fk(macro)p Fu(.)18 b(The)12 b(binding)h(is)f(p)q(erformed)g(in)195 +648 y Fk(map)p Fu(.)19 b(When)14 b Fk(k)o(eyseq)h Fu(is)f(in)o(v)o(ok)o +(ed,)g(the)g Fk(macro)i Fu(will)f(b)q(e)f(inserted)h(in)o(to)f(the)g +(line.)21 b(This)14 b(function)195 703 y(is)i(deprecated;)f(use)h +Ft(rl_generic_bind\(\))d Fu(instead.)1762 833 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 833 V 21 w(macro)p 417 833 +V 19 w(dump)r(er)g Fg(\()p Ft(int)15 b(readable)p Fg(\))195 +888 y Fu(Prin)o(t)f(the)f(k)o(ey)h(sequences)g(b)q(ound)h(to)e(macros)g +(and)g(their)h(v)m(alues,)h(using)f(the)g(curren)o(t)g(k)o(eymap,)195 +943 y(to)h Ft(rl_outstream)p Fu(.)k(If)d Fk(readable)j +Fu(is)d(non-zero,)g(the)g(list)g(is)g(formatted)f(in)h(suc)o(h)g(a)f(w) +o(a)o(y)g(that)g(it)195 997 y(can)g(b)q(e)h(made)f(part)g(of)g(an)g +Ft(inputrc)f Fu(\014le)i(and)g(re-read.)1762 1127 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1127 V 21 w(v)m(ariable)p 431 +1127 V 22 w(bind)j Fg(\()p Ft(const)14 b(char)g(*variable,)g(const)h +(char)f(*value)p Fg(\))195 1182 y Fu(Mak)o(e)22 b(the)g(Readline)i(v)m +(ariable)g Fk(v)m(ariable)j Fu(ha)o(v)o(e)22 b Fk(v)m(alue)p +Fu(.)43 b(This)23 b(b)q(eha)o(v)o(es)g(as)f(if)h(the)f(readline)195 +1237 y(command)12 b(`)p Ft(set)j Fk(v)m(ariable)k(v)m(alue)s +Fu(')12 b(had)h(b)q(een)g(executed)h(in)f(an)f Ft(inputrc)g +Fu(\014le)h(\(see)f(Section)i(1.3.1)195 1292 y([Readline)i(Init)g(File) +h(Syn)o(tax],)d(page)h(4\).)1762 1422 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 1422 V 21 w(v)m(ariable)p +457 1422 V 22 w(dump)r(er)g Fg(\()p Ft(int)14 b(readable)p +Fg(\))195 1476 y Fu(Prin)o(t)g(the)h(readline)h(v)m(ariable)f(names)g +(and)f(their)h(curren)o(t)f(v)m(alues)i(to)d Ft(rl_outstream)p +Fu(.)18 b(If)d Fk(read-)195 1531 y(able)20 b Fu(is)e(non-zero,)f(the)g +(list)h(is)g(formatted)e(in)h(suc)o(h)h(a)e(w)o(a)o(y)g(that)h(it)g +(can)g(b)q(e)h(made)f(part)f(of)h(an)195 1586 y Ft(inputrc)d +Fu(\014le)i(and)g(re-read.)1762 1716 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1716 V 21 w(set)p 307 1716 +V 20 w(paren)p 469 1716 V 20 w(blink)p 613 1716 V 23 +w(timeout)i Fg(\()p Ft(int)15 b(u)p Fg(\))195 1771 y +Fu(Set)e(the)f(time)h(in)o(terv)m(al)h(\(in)f(microseconds\))g(that)f +(Readline)i(w)o(aits)e(when)h(sho)o(wing)f(a)h(balancing)195 +1826 y(c)o(haracter)h(when)i Ft(blink-matching-paren)d +Fu(has)i(b)q(een)h(enabled.)1762 1956 y(F)l(unction)-1861 +b Fi(char)20 b(*)f Fh(rl)p 286 1956 V 21 w(get)p 384 +1956 V 21 w(termcap)j Fg(\()p Ft(const)14 b(char)g(*cap)p +Fg(\))195 2010 y Fu(Retriev)o(e)f(the)h(string)f(v)m(alue)i(of)e(the)h +(termcap)f(capabilit)o(y)i Fk(cap)p Fu(.)k(Readline)c(fetc)o(hes)f(the) +f(termcap)195 2065 y(en)o(try)j(for)h(the)f(curren)o(t)h(terminal)h +(name)e(and)h(uses)g(those)g(capabilities)i(to)d(mo)o(v)o(e)g(around)h +(the)195 2120 y(screen)11 b(line)h(and)f(p)q(erform)f(other)g +(terminal-sp)q(eci\014c)k(op)q(erations,)d(lik)o(e)h(erasing)e(a)h +(line.)20 b(Readline)195 2175 y(do)q(es)e(not)f(use)h(all)g(of)f(a)g +(terminal's)h(capabilities,)i(and)e(this)g(function)g(will)h(return)f +(v)m(alues)h(for)195 2230 y(only)d(those)f(capabilities)i(Readline)g +(uses.)75 2350 y Fj(2.4.12)29 b(Alternate)21 b(In)n(terface)137 +2451 y Fu(An)i(alternate)f(in)o(terface)h(is)g(a)o(v)m(ailable)h(to)d +(plain)j Ft(readline\(\))p Fu(.)40 b(Some)22 b(applications)i(need)g +(to)75 2506 y(in)o(terlea)o(v)o(e)15 b(k)o(eyb)q(oard)f(I/O)h(with)g +(\014le,)h(device,)f(or)f(windo)o(w)h(system)f(I/O,)h(t)o(ypically)h(b) +o(y)e(using)h(a)g(main)75 2560 y(lo)q(op)f(to)g Ft(select\(\))e +Fu(on)i(v)m(arious)g(\014le)h(descriptors.)20 b(T)l(o)14 +b(accomo)q(date)f(this)h(need,)h(readline)g(can)f(also)g(b)q(e)75 +2615 y(in)o(v)o(ok)o(ed)i(as)f(a)g(`callbac)o(k')h(function)h(from)d +(an)i(ev)o(en)o(t)f(lo)q(op.)22 b(There)16 b(are)f(functions)h(a)o(v)m +(ailable)i(to)c(mak)o(e)75 2670 y(this)i(easy)l(.)p eop +%%Page: 38 40 +38 39 bop 75 -58 a Fu(38)1299 b(GNU)15 b(Readline)h(Library)1762 +149 y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 149 +18 3 v 21 w(callbac)n(k)p 458 149 V 23 w(handler)p 670 +149 V 21 w(install)25 b Fg(\()p Ft(const)14 b(char)h(*prompt,)283 +204 y(rl_vcpfunc_t)e(*lhandler)p Fg(\))195 259 y Fu(Set)f(up)h(the)g +(terminal)g(for)f(readline)i(I/O)f(and)f(displa)o(y)i(the)e(initial)j +(expanded)e(v)m(alue)h(of)e Fk(prompt)p Fu(.)195 314 +y(Sa)o(v)o(e)j(the)h(v)m(alue)h(of)f Fk(lhandler)21 b +Fu(to)15 b(use)h(as)f(a)h(function)h(to)e(call)i(when)f(a)g(complete)g +(line)i(of)d(input)195 369 y(has)g(b)q(een)h(en)o(tered.)21 +b(The)15 b(function)h(tak)o(es)e(the)i(text)e(of)h(the)g(line)i(as)e +(an)g(argumen)o(t.)1762 480 y(F)l(unction)-1861 b Fi(void)20 +b Fh(rl)p 241 480 V 21 w(callbac)n(k)p 458 480 V 23 w(read)p +591 480 V 20 w(c)n(har)j Fg(\()p Ft(void)p Fg(\))195 +535 y Fu(Whenev)o(er)17 b(an)g(application)h(determines)g(that)e(k)o +(eyb)q(oard)h(input)h(is)f(a)o(v)m(ailable,)i(it)e(should)h(call)195 +590 y Ft(rl_callback_read_char\(\))p Fu(,)8 b(whic)o(h)k(will)g(read)f +(the)g(next)g(c)o(haracter)f(from)g(the)h(curren)o(t)g(input)195 +645 y(source.)38 b(If)21 b(that)g(c)o(haracter)f(completes)i(the)f +(line,)j Ft(rl_callback_read_char)18 b Fu(will)23 b(in)o(v)o(ok)o(e)195 +699 y(the)18 b Fk(lhandler)k Fu(function)d(sa)o(v)o(ed)e(b)o(y)h +Ft(rl_callback_handler_insta)o(ll)d Fu(to)i(pro)q(cess)h(the)g(line.) +195 754 y(Before)13 b(calling)i(the)f Fk(lhandler)k Fu(function,)c(the) +g(terminal)g(settings)f(are)g(reset)g(to)g(the)g(v)m(alues)i(they)195 +809 y(had)g(b)q(efore)g(calling)i Ft(rl_callback_handler_insta)o(ll)p +Fu(.)g(If)e(the)g Fk(lhandler)20 b Fu(function)15 b(returns,)195 +864 y(the)d(terminal)i(settings)e(are)g(mo)q(di\014ed)i(for)d +(Readline's)i(use)g(again.)19 b Ft(EOF)12 b Fu(is)h(indicated)h(b)o(y)e +(calling)195 919 y Fk(lhandler)20 b Fu(with)c(a)f Ft(NULL)f +Fu(line.)1762 1030 y(F)l(unction)-1861 b Fi(void)20 b +Fh(rl)p 241 1030 V 21 w(callbac)n(k)p 458 1030 V 23 w(handler)p +670 1030 V 21 w(remo)n(v)n(e)i Fg(\()p Ft(void)p Fg(\))195 +1085 y Fu(Restore)c(the)g(terminal)i(to)d(its)i(initial)i(state)d(and)g +(remo)o(v)o(e)g(the)h(line)h(handler.)31 b(This)19 b(ma)o(y)f(b)q(e)195 +1140 y(called)i(from)d(within)j(a)d(callbac)o(k)j(as)d(w)o(ell)i(as)f +(indep)q(enden)o(tly)m(.)31 b(If)19 b(the)f Fk(lhandler)23 +b Fu(installed)d(b)o(y)195 1195 y Ft(rl_callback_handler_instal)o(l)d +Fu(do)q(es)i(not)g(exit)h(the)g(program,)e(either)i(this)g(function)g +(or)195 1249 y(the)c(function)g(referred)g(to)f(b)o(y)h(the)g(v)m(alue) +h(of)e Ft(rl_deprep_term_function)d Fu(should)17 b(b)q(e)f(called)195 +1304 y(b)q(efore)f(the)h(program)e(exits)h(to)g(reset)g(the)g(terminal) +h(settings.)75 1413 y Fj(2.4.13)29 b(A)21 b(Readline)g(Example)137 +1508 y Fu(Here)f(is)g(a)f(function)i(whic)o(h)f(c)o(hanges)f(lo)o(w)o +(ercase)h(c)o(haracters)e(to)h(their)h(upp)q(ercase)h(equiv)m(alen)o +(ts,)75 1563 y(and)e(upp)q(ercase)i(c)o(haracters)d(to)h(lo)o(w)o +(ercase.)31 b(If)20 b(this)f(function)h(w)o(as)f(b)q(ound)h(to)f(`)p +Ft(M-c)p Fu(',)f(then)i(t)o(yping)75 1618 y(`)p Ft(M-c)p +Fu(')12 b(w)o(ould)h(c)o(hange)h(the)f(case)g(of)g(the)g(c)o(haracter)g +(under)g(p)q(oin)o(t.)20 b(T)o(yping)14 b(`)p Ft(M-1)g(0)h(M-c)p +Fu(')d(w)o(ould)i(c)o(hange)75 1673 y(the)h(case)g(of)g(the)h(follo)o +(wing)f(10)g(c)o(haracters,)f(lea)o(ving)i(the)f(cursor)g(on)g(the)h +(last)f(c)o(haracter)f(c)o(hanged.)195 1736 y Ft(/*)24 +b(Invert)f(the)g(case)g(of)h(the)f(COUNT)h(following)e(characters.)h +(*/)195 1788 y(int)195 1840 y(invert_case_line)f(\(count,)h(key\))314 +1892 y(int)h(count,)f(key;)195 1944 y({)243 1995 y(register)f(int)i +(start,)f(end,)g(i;)243 2099 y(start)g(=)h(rl_point;)243 +2203 y(if)f(\(rl_point)g(>=)h(rl_end\))290 2255 y(return)f(\(0\);)243 +2359 y(if)g(\(count)g(<)h(0\))290 2411 y({)338 2462 y(direction)f(=)h +(-1;)338 2514 y(count)f(=)h(-count;)290 2566 y(})243 +2618 y(else)290 2670 y(direction)f(=)h(1;)p eop +%%Page: 39 41 +39 40 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(39)243 201 y Ft(/*)23 b(Find)h(the)f(end)h(of)f(the)h +(range)f(to)g(modify.)g(*/)243 253 y(end)g(=)h(start)f(+)h(\(count)f(*) +h(direction\);)243 357 y(/*)f(Force)g(it)h(to)g(be)f(within)g(range.)g +(*/)243 409 y(if)g(\(end)h(>)f(rl_end\))290 461 y(end)h(=)g(rl_end;)243 +513 y(else)f(if)h(\(end)f(<)h(0\))290 565 y(end)g(=)g(0;)243 +668 y(if)f(\(start)g(==)h(end\))290 720 y(return)f(\(0\);)243 +824 y(if)g(\(start)g(>)h(end\))290 876 y({)338 928 y(int)g(temp)f(=)h +(start;)338 980 y(start)f(=)h(end;)338 1032 y(end)g(=)f(temp;)290 +1083 y(})243 1187 y(/*)g(Tell)h(readline)e(that)i(we)f(are)h(modifying) +e(the)i(line,)314 1239 y(so)g(it)f(will)h(save)f(the)h(undo)f +(information.)f(*/)243 1291 y(rl_modifying)g(\(start,)h(end\);)243 +1395 y(for)g(\(i)h(=)f(start;)h(i)f(!=)h(end;)f(i++\))290 +1447 y({)338 1499 y(if)h(\(_rl_uppercase_p)d(\(rl_line_buffer[i]\)\)) +386 1550 y(rl_line_buffer[i])g(=)j(_rl_to_lower)e +(\(rl_line_buffer[i]\);)338 1602 y(else)h(if)h(\(_rl_lowercase_p)e +(\(rl_line_buffer[i]\)\))386 1654 y(rl_line_buffer[i])f(=)j +(_rl_to_upper)e(\(rl_line_buffer[i]\);)290 1706 y(})243 +1758 y(/*)h(Move)h(point)f(to)g(on)h(top)f(of)h(the)f(last)h(character) +e(changed.)h(*/)243 1810 y(rl_point)f(=)i(\(direction)f(==)g(1\))h(?)g +(end)f(-)h(1)g(:)f(start;)243 1862 y(return)g(\(0\);)195 +1914 y(})75 2057 y Fs(2.5)33 b(Readline)23 b(Signal)h(Handling)137 +2159 y Fu(Signals)e(are)f(async)o(hronous)f(ev)o(en)o(ts)h(sen)o(t)f +(to)h(a)f(pro)q(cess)h(b)o(y)g(the)g(Unix)h(k)o(ernel,)g(sometimes)f +(on)75 2213 y(b)q(ehalf)g(of)e(another)h(pro)q(cess.)34 +b(They)20 b(are)g(in)o(tended)h(to)e(indicate)j(exceptional)f(ev)o(en)o +(ts,)f(lik)o(e)h(a)f(user)75 2268 y(pressing)c(the)f(in)o(terrupt)g(k)o +(ey)g(on)g(his)h(terminal,)f(or)g(a)f(net)o(w)o(ork)g(connection)i(b)q +(eing)g(brok)o(en.)k(There)15 b(is)75 2323 y(a)e(class)g(of)g(signals)h +(that)f(can)g(b)q(e)h(sen)o(t)f(to)f(the)i(pro)q(cess)f(curren)o(tly)h +(reading)f(input)i(from)d(the)h(k)o(eyb)q(oard.)75 2378 +y(Since)i(Readline)f(c)o(hanges)g(the)f(terminal)h(attributes)f(when)h +(it)g(is)g(called,)h(it)e(needs)h(to)f(p)q(erform)g(sp)q(ecial)75 +2433 y(pro)q(cessing)i(when)f(suc)o(h)g(a)g(signal)g(is)g(receiv)o(ed)h +(in)g(order)f(to)f(restore)g(the)h(terminal)g(to)f(a)h(sane)g(state,)e +(or)75 2487 y(pro)o(vide)k(application)h(writers)e(with)g(functions)h +(to)f(do)g(so)g(man)o(ually)l(.)137 2560 y(Readline)22 +b(con)o(tains)e(an)g(in)o(ternal)h(signal)g(handler)g(that)f(is)h +(installed)h(for)d(a)h(n)o(um)o(b)q(er)g(of)g(signals)75 +2615 y(\()p Ft(SIGINT)p Fu(,)h Ft(SIGQUIT)p Fu(,)g Ft(SIGTERM)p +Fu(,)g Ft(SIGALRM)p Fu(,)g Ft(SIGTSTP)p Fu(,)g Ft(SIGTTIN)p +Fu(,)h(and)f Ft(SIGTTOU)p Fu(\).)36 b(When)21 b(one)g(of)75 +2670 y(these)16 b(signals)h(is)f(receiv)o(ed,)h(the)f(signal)h(handler) +f(will)i(reset)e(the)g(terminal)g(attributes)g(to)f(those)h(that)p +eop +%%Page: 40 42 +40 41 bop 75 -58 a Fu(40)1299 b(GNU)15 b(Readline)h(Library)75 +149 y(w)o(ere)d(in)i(e\013ect)e(b)q(efore)h Ft(readline\(\))e +Fu(w)o(as)h(called,)i(reset)f(the)f(signal)i(handling)g(to)e(what)g(it) +h(w)o(as)f(b)q(efore)75 204 y Ft(readline\(\))21 b Fu(w)o(as)h(called,) +j(and)e(resend)g(the)g(signal)g(to)f(the)h(calling)h(application.)44 +b(If)23 b(and)f(when)75 259 y(the)17 b(calling)i(application's)f +(signal)g(handler)g(returns,)f(Readline)h(will)h(reinitialize)h(the)d +(terminal)h(and)75 314 y(con)o(tin)o(ue)d(to)e(accept)i(input.)20 +b(When)15 b(a)e Ft(SIGINT)h Fu(is)g(receiv)o(ed,)h(the)g(Readline)g +(signal)g(handler)g(p)q(erforms)75 369 y(some)k(additional)i(w)o(ork,)e +(whic)o(h)h(will)h(cause)f(an)o(y)f(partially-en)o(tered)i(line)g(to)d +(b)q(e)i(ab)q(orted)g(\(see)f(the)75 423 y(description)e(of)d +Ft(rl_free_line_state\(\))f Fu(b)q(elo)o(w\).)137 488 +y(There)g(is)f(an)g(additional)i(Readline)g(signal)f(handler,)g(for)f +Ft(SIGWINCH)p Fu(,)f(whic)o(h)i(the)f(k)o(ernel)h(sends)g(to)e(a)75 +543 y(pro)q(cess)k(whenev)o(er)g(the)f(terminal's)h(size)g(c)o(hanges)f +(\(for)g(example,)h(if)g(a)f(user)h(resizes)g(an)f Ft(xterm)p +Fu(\).)19 b(The)75 598 y(Readline)g Ft(SIGWINCH)e Fu(handler)i(up)q +(dates)f(Readline's)h(in)o(ternal)f(screen)h(size)f(information,)h(and) +f(then)75 653 y(calls)g(an)o(y)f Ft(SIGWINCH)e Fu(signal)j(handler)g +(the)f(calling)i(application)f(has)f(installed.)27 b(Readline)18 +b(calls)g(the)75 708 y(application's)h Ft(SIGWINCH)d +Fu(signal)j(handler)f(without)g(resetting)g(the)f(terminal)i(to)e(its)g +(original)i(state.)75 762 y(If)d(the)g(application's)h(signal)g +(handler)g(do)q(es)g(more)e(than)h(up)q(date)h(its)f(idea)h(of)e(the)h +(terminal)h(size)g(and)75 817 y(return)e(\(for)f(example,)h(a)f +Ft(longjmp)g Fu(bac)o(k)h(to)f(a)h(main)g(pro)q(cessing)g(lo)q(op\),)g +(it)g Fl(must)20 b Fu(call)c Ft(rl_cleanup_)75 872 y(after_signal\(\))d +Fu(\(describ)q(ed)k(b)q(elo)o(w\),)e(to)g(restore)f(the)h(terminal)h +(state.)137 937 y(Readline)g(pro)o(vides)f(t)o(w)o(o)e(v)m(ariables)i +(that)f(allo)o(w)g(application)i(writers)e(to)g(con)o(trol)g(whether)h +(or)e(not)75 992 y(it)k(will)h(catc)o(h)e(certain)h(signals)h(and)f +(act)f(on)g(them)h(when)g(they)f(are)h(receiv)o(ed.)25 +b(It)16 b(is)i(imp)q(ortan)o(t)e(that)75 1047 y(applications)k(c)o +(hange)e(the)h(v)m(alues)g(of)f(these)h(v)m(ariables)g(only)g(when)g +(calling)h Ft(readline\(\))p Fu(,)d(not)h(in)h(a)75 1101 +y(signal)d(handler,)g(so)f(Readline's)h(in)o(ternal)g(signal)g(state)e +(is)i(not)f(corrupted.)1773 1208 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1208 18 3 v 21 w(catc)n(h)p +366 1208 V 22 w(signals)195 1262 y Fu(If)15 b(this)g(v)m(ariable)g(is)g +(non-zero,)g(Readline)h(will)g(install)f(signal)h(handlers)f(for)f +Ft(SIGINT)p Fu(,)f Ft(SIGQUIT)p Fu(,)195 1317 y Ft(SIGTERM)p +Fu(,)h Ft(SIGALRM)p Fu(,)g Ft(SIGTSTP)p Fu(,)f Ft(SIGTTIN)p +Fu(,)h(and)i Ft(SIGTTOU)p Fu(.)195 1382 y(The)f(default)h(v)m(alue)h +(of)d Ft(rl_catch_signals)f Fu(is)j(1.)1773 1488 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1488 V 21 w(catc)n(h)p 366 +1488 V 22 w(sigwinc)n(h)195 1543 y Fu(If)15 b(this)h(v)m(ariable)h(is)e +(non-zero,)g(Readline)i(will)g(install)f(a)f(signal)h(handler)h(for)d +Ft(SIGWINCH)p Fu(.)195 1608 y(The)h(default)h(v)m(alue)h(of)d +Ft(rl_catch_sigwinch)f Fu(is)j(1.)137 1694 y(If)g(an)f(application)j +(do)q(es)d(not)g(wish)i(to)d(ha)o(v)o(e)h(Readline)i(catc)o(h)f(an)o(y) +f(signals,)h(or)f(to)f(handle)j(signals)75 1749 y(other)i(than)g(those) +g(Readline)i(catc)o(hes)e(\()p Ft(SIGHUP)p Fu(,)g(for)g(example\),)h +(Readline)h(pro)o(vides)e(con)o(v)o(enience)75 1804 y(functions)d(to)f +(do)g(the)g(necessary)g(terminal)h(and)g(in)o(ternal)g(state)e(clean)o +(up)i(up)q(on)g(receipt)g(of)f(a)g(signal.)1762 1910 +y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 1910 V +21 w(clean)n(up)p 450 1910 V 22 w(after)p 590 1910 V +20 w(signal)j Fg(\()p Ft(void)p Fg(\))195 1965 y Fu(This)18 +b(function)f(will)i(reset)e(the)g(state)f(of)g(the)h(terminal)h(to)e +(what)h(it)g(w)o(as)f(b)q(efore)h Ft(readline\(\))195 +2019 y Fu(w)o(as)d(called,)i(and)f(remo)o(v)o(e)f(the)g(Readline)i +(signal)g(handlers)g(for)e(all)h(signals,)g(dep)q(ending)i(on)e(the)195 +2074 y(v)m(alues)h(of)f Ft(rl_catch_signals)e Fu(and)i +Ft(rl_catch_sigwinch)p Fu(.)1762 2180 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 2180 V 21 w(free)p 356 2180 +V 20 w(line)p 464 2180 V 23 w(state)j Fg(\()p Ft(void)p +Fg(\))195 2235 y Fu(This)d(will)h(free)f(an)o(y)f(partial)h(state)f +(asso)q(ciated)h(with)g(the)g(curren)o(t)f(input)i(line)g(\(undo)f +(infor-)195 2290 y(mation,)i(an)o(y)f(partial)h(history)f(en)o(try)l(,) +h(an)o(y)f(partially-en)o(tered)i(k)o(eyb)q(oard)e(macro,)h(and)f(an)o +(y)195 2345 y(partially-en)o(tered)k(n)o(umeric)g(argumen)o(t\).)45 +b(This)24 b(should)h(b)q(e)g(called)g(b)q(efore)g Ft(rl_cleanup_)195 +2399 y(after_signal\(\))p Fu(.)36 b(The)22 b(Readline)h(signal)f +(handler)g(for)f Ft(SIGINT)f Fu(calls)j(this)e(to)g(ab)q(ort)g(the)195 +2454 y(curren)o(t)15 b(input)h(line.)1762 2560 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 2560 V 21 w(reset)p 383 2560 +V 20 w(after)p 521 2560 V 21 w(signal)j Fg(\()p Ft(void)p +Fg(\))195 2615 y Fu(This)15 b(will)h(reinitialize)h(the)d(terminal)h +(and)g(reinstall)h(an)o(y)d(Readline)j(signal)f(handlers,)g(dep)q(end-) +195 2670 y(ing)h(on)f(the)g(v)m(alues)i(of)d Ft(rl_catch_signals)f +Fu(and)j Ft(rl_catch_sigwinch)p Fu(.)p eop +%%Page: 41 43 +41 42 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(41)137 149 y(If)20 b(an)g(application)h(do)q(es)f(not)g +(wish)g(Readline)h(to)e(catc)o(h)g Ft(SIGWINCH)p Fu(,)h(it)g(ma)o(y)f +(call)h Ft(rl_resize_)75 204 y(terminal\(\))12 b Fu(or)h +Ft(rl_set_screen_size\(\))e Fu(to)i(force)g(Readline)i(to)e(up)q(date)h +(its)g(idea)g(of)g(the)f(terminal)75 259 y(size)j(when)g(a)f +Ft(SIGWINCH)f Fu(is)h(receiv)o(ed.)1762 360 y(F)l(unction)-1861 +b Fi(void)20 b Fh(rl)p 241 360 18 3 v 21 w(resize)p 401 +360 V 22 w(terminal)j Fg(\()p Ft(void)p Fg(\))195 415 +y Fu(Up)q(date)16 b(Readline's)g(in)o(ternal)g(screen)f(size)i(b)o(y)e +(reading)g(v)m(alues)i(from)d(the)i(k)o(ernel.)1762 516 +y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 516 V +21 w(set)p 333 516 V 21 w(screen)p 510 516 V 20 w(size)k +Fg(\()p Ft(int)15 b(rows,)f(int)h(cols)p Fg(\))195 571 +y Fu(Set)g(Readline's)h(idea)g(of)f(the)g(terminal)h(size)g(to)f +Fk(ro)o(ws)h Fu(ro)o(ws)e(and)i Fk(cols)h Fu(columns.)137 +653 y(If)g(an)g(application)h(do)q(es)f(not)f(w)o(an)o(t)g(to)g +(install)i(a)f Ft(SIGWINCH)e Fu(handler,)j(but)f(is)g(still)h(in)o +(terested)f(in)75 708 y(the)e(screen)h(dimensions,)g(Readline's)h(idea) +e(of)g(the)h(screen)f(size)h(ma)o(y)f(b)q(e)h(queried.)1762 +809 y(F)l(unction)-1861 b Fi(void)20 b Fh(rl)p 241 809 +V 21 w(get)p 339 809 V 21 w(screen)p 516 809 V 20 w(size)k +Fg(\()p Ft(int)15 b(*rows,)f(int)h(*cols)p Fg(\))195 +864 y Fu(Return)g(Readline's)h(idea)f(of)g(the)g(terminal's)g(size)h +(in)g(the)f(v)m(ariables)i(p)q(oin)o(ted)f(to)e(b)o(y)h(the)g(argu-)195 +918 y(men)o(ts.)137 1001 y(The)h(follo)o(wing)g(functions)g(install)g +(and)g(remo)o(v)o(e)e(Readline's)i(signal)g(handlers.)1762 +1102 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 1102 +V 21 w(set)p 307 1102 V 20 w(signals)j Fg(\()p Ft(void)p +Fg(\))195 1157 y Fu(Install)c(Readline's)f(signal)h(handler)f(for)f +Ft(SIGINT)p Fu(,)g Ft(SIGQUIT)p Fu(,)g Ft(SIGTERM)p Fu(,)g +Ft(SIGALRM)p Fu(,)f Ft(SIGTSTP)p Fu(,)195 1211 y Ft(SIGTTIN)p +Fu(,)11 b Ft(SIGTTOU)p Fu(,)g(and)h Ft(SIGWINCH)p Fu(,)e(dep)q(ending)k +(on)e(the)f(v)m(alues)i(of)e Ft(rl_catch_signals)f Fu(and)195 +1266 y Ft(rl_catch_sigwinch)p Fu(.)1762 1367 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 1367 V 21 w(clear)p 354 1367 +V 21 w(signals)j Fg(\()p Ft(void)p Fg(\))195 1422 y Fu(Remo)o(v)o(e)14 +b(all)i(of)f(the)g(Readline)i(signal)f(handlers)g(installed)h(b)o(y)e +Ft(rl_set_signals\(\))p Fu(.)75 1541 y Fs(2.6)33 b(Custom)21 +b(Completers)137 1634 y Fu(T)o(ypically)l(,)e(a)d(program)f(that)h +(reads)h(commands)f(from)g(the)h(user)f(has)h(a)f(w)o(a)o(y)g(of)g +(disam)o(biguating)75 1689 y(commands)i(and)f(data.)27 +b(If)18 b(y)o(our)f(program)g(is)h(one)g(of)f(these,)i(then)f(it)g(can) +f(pro)o(vide)i(completion)g(for)75 1744 y(commands,)14 +b(data,)g(or)g(b)q(oth.)20 b(The)15 b(follo)o(wing)g(sections)g +(describ)q(e)h(ho)o(w)e(y)o(our)g(program)g(and)h(Readline)75 +1798 y(co)q(op)q(erate)g(to)g(pro)o(vide)g(this)h(service.)75 +1901 y Fj(2.6.1)30 b(Ho)n(w)21 b(Completing)f(W)-5 b(orks)137 +1994 y Fu(In)18 b(order)f(to)f(complete)i(some)f(text,)g(the)g(full)i +(list)e(of)g(p)q(ossible)i(completions)f(m)o(ust)f(b)q(e)h(a)o(v)m +(ailable.)75 2049 y(That)e(is,)i(it)f(is)h(not)f(p)q(ossible)h(to)f +(accurately)g(expand)h(a)e(partial)i(w)o(ord)e(without)h(kno)o(wing)g +(all)h(of)f(the)75 2104 y(p)q(ossible)i(w)o(ords)e(whic)o(h)h(mak)o(e)f +(sense)h(in)h(that)d(con)o(text.)26 b(The)18 b(Readline)h(library)f +(pro)o(vides)g(the)g(user)75 2158 y(in)o(terface)f(to)f(completion,)i +(and)e(t)o(w)o(o)g(of)g(the)h(most)f(common)g(completion)i(functions:) +23 b(\014lename)18 b(and)75 2213 y(username.)h(F)l(or)10 +b(completing)i(other)e(t)o(yp)q(es)h(of)f(text,)h(y)o(ou)g(m)o(ust)f +(write)h(y)o(our)f(o)o(wn)h(completion)g(function.)75 +2268 y(This)16 b(section)g(describ)q(es)g(exactly)g(what)f(suc)o(h)g +(functions)h(m)o(ust)f(do,)f(and)i(pro)o(vides)f(an)h(example.)137 +2332 y(There)g(are)f(three)g(ma)s(jor)f(functions)i(used)f(to)g(p)q +(erform)g(completion:)100 2396 y(1.)29 b(The)22 b(user-in)o(terface)g +(function)h Ft(rl_complete\(\))p Fu(.)37 b(This)22 b(function)h(is)f +(called)h(with)f(the)g(same)165 2451 y(argumen)o(ts)17 +b(as)h(other)g(bindable)i(Readline)f(functions:)27 b +Fk(coun)o(t)19 b Fu(and)f Fk(in)o(v)o(oking)p 1556 2451 +14 2 v 17 w(k)o(ey)p Fu(.)28 b(It)19 b(isolates)165 2506 +y(the)g(w)o(ord)f(to)g(b)q(e)i(completed)f(and)g(calls)h +Ft(rl_completion_matches\(\))c Fu(to)i(generate)g(a)h(list)g(of)165 +2560 y(p)q(ossible)e(completions.)22 b(It)16 b(then)g(either)g(lists)g +(the)g(p)q(ossible)h(completions,)g(inserts)f(the)f(p)q(ossible)165 +2615 y(completions,)25 b(or)d(actually)i(p)q(erforms)e(the)g +(completion,)k(dep)q(ending)e(on)f(whic)o(h)g(b)q(eha)o(vior)g(is)165 +2670 y(desired.)p eop +%%Page: 42 44 +42 43 bop 75 -58 a Fu(42)1299 b(GNU)15 b(Readline)h(Library)100 +149 y(2.)29 b(The)17 b(in)o(ternal)h(function)f Ft +(rl_completion_matches\(\))d Fu(uses)j(an)g(application-supplie)q(d)j +Fk(gener-)165 204 y(ator)h Fu(function)e(to)f(generate)g(the)h(list)g +(of)f(p)q(ossible)i(matc)o(hes,)f(and)f(then)h(returns)g(the)f(arra)o +(y)f(of)165 259 y(these)j(matc)o(hes.)32 b(The)20 b(caller)g(should)h +(place)f(the)g(address)f(of)h(its)f(generator)g(function)h(in)g +Ft(rl_)165 314 y(completion_entry_function)p Fu(.)100 +383 y(3.)29 b(The)12 b(generator)e(function)i(is)g(called)h(rep)q +(eatedly)g(from)e Ft(rl_completion_matches\(\))p Fu(,)d(returning)165 +438 y(a)16 b(string)g(eac)o(h)h(time.)24 b(The)17 b(argumen)o(ts)e(to)h +(the)g(generator)g(function)h(are)f Fk(text)h Fu(and)g +Fk(state)p Fu(.)22 b Fk(text)165 493 y Fu(is)17 b(the)f(partial)g(w)o +(ord)f(to)h(b)q(e)h(completed.)23 b Fk(state)18 b Fu(is)e(zero)g(the)g +(\014rst)g(time)g(the)g(function)h(is)g(called,)165 547 +y(allo)o(wing)23 b(the)f(generator)f(to)g(p)q(erform)h(an)o(y)g +(necessary)g(initialization,)k(and)c(a)g(p)q(ositiv)o(e)h(non-)165 +602 y(zero)14 b(in)o(teger)h(for)f(eac)o(h)h(subsequen)o(t)g(call.)21 +b(The)15 b(generator)e(function)j(returns)e Ft(\(char)h(*\)NULL)f +Fu(to)165 657 y(inform)19 b Ft(rl_completion_matches\(\))d +Fu(that)i(there)h(are)g(no)g(more)g(p)q(ossibilities)j(left.)32 +b(Usually)165 712 y(the)19 b(generator)g(function)h(computes)g(the)f +(list)h(of)f(p)q(ossible)i(completions)g(when)e Fk(state)j +Fu(is)d(zero,)165 767 y(and)13 b(returns)g(them)f(one)h(at)f(a)h(time)g +(on)g(subsequen)o(t)g(calls.)20 b(Eac)o(h)13 b(string)f(the)h +(generator)f(function)165 821 y(returns)k(as)f(a)h(matc)o(h)f(m)o(ust)h +(b)q(e)g(allo)q(cated)h(with)g Ft(malloc\(\))p Fu(;)d(Readline)k(frees) +e(the)g(strings)f(when)165 876 y(it)g(has)h(\014nished)g(with)g(them.) +1762 1005 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 +1005 18 3 v 21 w(complete)j Fg(\()p Ft(int)14 b(ignore,)g(int)h +(invoking_key)p Fg(\))195 1059 y Fu(Complete)h(the)f(w)o(ord)g(at)f(or) +h(b)q(efore)h(p)q(oin)o(t.)21 b(Y)l(ou)15 b(ha)o(v)o(e)g(supplied)j +(the)d(function)i(that)d(do)q(es)i(the)195 1114 y(initial)23 +b(simple)f(matc)o(hing)e(selection)i(algorithm)f(\(see)f +Ft(rl_completion_matches\(\))p Fu(\).)33 b(The)195 1169 +y(default)16 b(is)f(to)g(do)g(\014lename)h(completion.)1773 +1298 y(V)l(ariable)-1861 b Fi(rl_compentry_func_t)22 +b(*)d Fh(rl)p 678 1298 V 21 w(completion)p 973 1298 V +21 w(en)n(try)p 1126 1298 V 22 w(function)195 1352 y +Fu(This)i(is)f(a)g(p)q(oin)o(ter)g(to)f(the)h(generator)g(function)g +(for)g Ft(rl_completion_matches\(\))p Fu(.)31 b(If)20 +b(the)195 1407 y(v)m(alue)13 b(of)f Ft(rl_completion_entry_fun)o(ction) +d Fu(is)j Ft(NULL)f Fu(then)h(the)g(default)h(\014lename)g(generator) +195 1462 y(function,)j Ft(rl_filename_completion_f)o(unction)o(\(\))p +Fu(,)c(is)k(used.)75 1582 y Fj(2.6.2)30 b(Completion)20 +b(F)-5 b(unctions)137 1682 y Fu(Here)16 b(is)f(the)h(complete)g(list)g +(of)e(callable)k(completion)e(functions)g(presen)o(t)f(in)h(Readline.) +1762 1810 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 +1810 V 21 w(complete)p 460 1810 V 21 w(in)n(ternal)k +Fg(\()p Ft(int)15 b(what_to_do)p Fg(\))195 1865 y Fu(Complete)k(the)g +(w)o(ord)f(at)g(or)g(b)q(efore)h(p)q(oin)o(t.)31 b Fk(what)p +1108 1865 14 2 v 16 w(to)p 1165 1865 V 16 w(do)21 b Fu(sa)o(ys)d(what)g +(to)g(do)h(with)g(the)g(com-)195 1920 y(pletion.)j(A)16 +b(v)m(alue)h(of)e(`)p Ft(?)p Fu(')g(means)g(list)i(the)e(p)q(ossible)j +(completions.)k(`)p Ft(TAB)p Fu(')14 b(means)i(do)f(standard)195 +1975 y(completion.)22 b(`)p Ft(*)p Fu(')15 b(means)g(insert)h(all)h(of) +e(the)h(p)q(ossible)h(completions.)22 b(`)p Ft(!)p Fu(')15 +b(means)g(to)g(displa)o(y)i(all)195 2029 y(of)g(the)g(p)q(ossible)i +(completions,)f(if)g(there)f(is)h(more)f(than)g(one,)g(as)g(w)o(ell)h +(as)f(p)q(erforming)h(partial)195 2084 y(completion.)1762 +2213 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p 215 2213 +18 3 v 21 w(complete)j Fg(\()p Ft(int)14 b(ignore,)g(int)h +(invoking_key)p Fg(\))195 2268 y Fu(Complete)21 b(the)g(w)o(ord)e(at)h +(or)g(b)q(efore)h(p)q(oin)o(t.)37 b(Y)l(ou)21 b(ha)o(v)o(e)f(supplied)j +(the)d(function)i(that)e(do)q(es)195 2322 y(the)d(initial)h(simple)g +(matc)o(hing)f(selection)h(algorithm)e(\(see)g Ft +(rl_completion_matches\(\))e Fu(and)195 2377 y Ft +(rl_completion_entry_functi)o(on)p Fu(\).)25 b(The)18 +b(default)h(is)f(to)f(do)h(\014lename)h(completion.)29 +b(This)195 2432 y(calls)16 b Ft(rl_complete_internal\(\))c +Fu(with)k(an)f(argumen)o(t)f(dep)q(ending)k(on)d Fk(in)o(v)o(oking)p +1657 2432 14 2 v 17 w(k)o(ey)p Fu(.)1762 2560 y(F)l(unction)-1861 +b Fi(int)20 b Fh(rl)p 215 2560 18 3 v 21 w(p)r(ossible)p +433 2560 V 20 w(completions)j Fg(\()p Ft(int)15 b(count,)f(int)h +(invoking_key)p Fg(\))195 2615 y Fu(List)21 b(the)f(p)q(ossible)i +(completions.)36 b(See)21 b(description)h(of)e Ft(rl_complete)13 +b(\(\))p Fu(.)35 b(This)21 b(calls)g Ft(rl_)195 2670 +y(complete_internal\(\))13 b Fu(with)i(an)g(argumen)o(t)g(of)f(`)p +Ft(?)p Fu('.)p eop +%%Page: 43 45 +43 44 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(43)1762 149 y(F)l(unction)-1861 b Fi(int)20 +b Fh(rl)p 215 149 18 3 v 21 w(insert)p 378 149 V 21 w(completions)j +Fg(\()p Ft(int)14 b(count,)g(int)h(invoking_key)p Fg(\))195 +204 y Fu(Insert)i(the)g(list)h(of)e(p)q(ossible)j(completions)e(in)o +(to)g(the)g(line,)i(deleting)f(the)f(partially-completed)195 +259 y(w)o(ord.)k(See)c(description)g(of)e Ft(rl_complete\(\))p +Fu(.)20 b(This)d(calls)g Ft(rl_complete_internal\(\))c +Fu(with)195 314 y(an)i(argumen)o(t)g(of)f(`)p Ft(*)p +Fu('.)1762 434 y(F)l(unction)-1861 b Fi(int)20 b Fh(rl)p +215 434 V 21 w(completion)p 510 434 V 21 w(mo)r(de)h +Fg(\()p Ft(rl_command_func_t)12 b(*cfunc)p Fg(\))195 +489 y Fu(Returns)25 b(the)g(apppriate)h(v)m(alue)g(to)f(pass)g(to)f +Ft(rl_complete_internal\(\))f Fu(dep)q(ending)k(on)195 +543 y(whether)22 b Fk(cfunc)j Fu(w)o(as)d(called)h(t)o(wice)f(in)h +(succession)g(and)f(the)g(v)m(alue)h(of)f(the)g Ft(show-all-if-)195 +598 y(ambiguous)14 b Fu(v)m(ariable.)21 b(Application-sp)q(ec)q(i\014c) +e(completion)d(functions)g(ma)o(y)f(use)g(this)h(function)195 +653 y(to)f(presen)o(t)g(the)g(same)g(in)o(terface)g(as)g +Ft(rl_complete\(\))p Fu(.)1762 773 y(F)l(unction)-1861 +b Fi(char)20 b(**)f Fh(rl)p 312 773 V 21 w(completion)p +607 773 V 21 w(matc)n(hes)j Fg(\()p Ft(const)15 b(char)f(*text,)283 +828 y(rl_compentry_func_t)e(*entry_func)p Fg(\))195 883 +y Fu(Returns)18 b(an)h(arra)o(y)f(of)g(strings)h(whic)o(h)h(is)g(a)e +(list)i(of)e(completions)i(for)f Fk(text)p Fu(.)30 b(If)19 +b(there)g(are)g(no)195 937 y(completions,)f(returns)g +Ft(NULL)p Fu(.)25 b(The)17 b(\014rst)g(en)o(try)g(in)h(the)f(returned)h +(arra)o(y)e(is)i(the)f(substitution)195 992 y(for)c Fk(text)p +Fu(.)18 b(The)c(remaining)g(en)o(tries)f(are)g(the)h(p)q(ossible)g +(completions.)21 b(The)13 b(arra)o(y)f(is)i(terminated)195 +1047 y(with)i(a)e Ft(NULL)h Fu(p)q(oin)o(ter.)195 1115 +y Fk(en)o(try)p 302 1115 14 2 v 16 w(func)h Fu(is)e(a)f(function)h(of)e +(t)o(w)o(o)g(args,)g(and)i(returns)f(a)f Ft(char)j(*)p +Fu(.)k(The)13 b(\014rst)g(argumen)o(t)f(is)i Fk(text)p +Fu(.)195 1170 y(The)f(second)g(is)f(a)h(state)e(argumen)o(t;)h(it)h(is) +g(zero)f(on)g(the)h(\014rst)f(call,)i(and)e(non-zero)h(on)f(subsequen)o +(t)195 1225 y(calls.)20 b Fk(en)o(try)p 420 1225 V 16 +w(func)15 b Fu(returns)e(a)e Ft(NULL)h Fu(p)q(oin)o(ter)h(to)e(the)i +(caller)g(when)g(there)f(are)g(no)g(more)g(matc)o(hes.)1762 +1345 y(F)l(unction)-1861 b Fi(char)20 b(*)f Fh(rl)p 286 +1345 18 3 v 21 w(\014lename)p 515 1345 V 20 w(completion)p +809 1345 V 21 w(function)k Fg(\()p Ft(const)15 b(char)f(*text,)h(int) +283 1400 y(state)p Fg(\))195 1454 y Fu(A)e(generator)f(function)h(for)g +(\014lename)h(completion)f(in)h(the)f(general)g(case.)19 +b Fk(text)14 b Fu(is)f(a)g(partial)g(\014le-)195 1509 +y(name.)20 b(The)15 b(Bash)f(source)h(is)g(a)g(useful)g(reference)h +(for)e(writing)h(custom)f(completion)i(functions)195 +1564 y(\(the)f(Bash)g(completion)i(functions)e(call)i(this)e(and)h +(other)f(Readline)h(functions\).)1762 1684 y(F)l(unction)-1861 +b Fi(char)20 b(*)f Fh(rl)p 286 1684 V 21 w(username)p +547 1684 V 19 w(completion)p 840 1684 V 21 w(function)k +Fg(\()p Ft(const)14 b(char)g(*text,)283 1739 y(int)g(state)p +Fg(\))195 1794 y Fu(A)g(completion)i(generator)d(for)h(usernames.)19 +b Fk(text)c Fu(con)o(tains)f(a)g(partial)h(username)f(preceded)i(b)o(y) +195 1848 y(a)f(random)g(c)o(haracter)f(\(usually)j(`)p +Ft(~)p Fu('\).)i(As)c(with)g(all)i(completion)f(generators,)e +Fk(state)j Fu(is)f(zero)f(on)195 1903 y(the)g(\014rst)g(call)h(and)g +(non-zero)f(for)g(subsequen)o(t)h(calls.)75 2017 y Fj(2.6.3)30 +b(Completion)20 b(V)-5 b(ariables)1773 2166 y Fu(V)l(ariable)-1861 +b Fi(rl_compentry_func_t)22 b(*)d Fh(rl)p 678 2166 V +21 w(completion)p 973 2166 V 21 w(en)n(try)p 1126 2166 +V 22 w(function)195 2221 y Fu(A)e(p)q(oin)o(ter)g(to)f(the)h(generator) +f(function)h(for)f Ft(rl_completion_matches\(\))p Fu(.)22 +b Ft(NULL)16 b Fu(means)h(to)195 2276 y(use)f Ft +(rl_filename_completion_)o(functio)o(n\(\))p Fu(,)c(the)j(default)h +(\014lename)g(completer.)1773 2396 y(V)l(ariable)-1861 +b Fi(rl_completion_func_t)22 b(*)d Fh(rl)p 704 2396 V +22 w(attempted)p 985 2396 V 20 w(completion)p 1279 2396 +V 21 w(function)195 2451 y Fu(A)e(p)q(oin)o(ter)h(to)f(an)g(alternativ) +o(e)h(function)g(to)f(create)g(matc)o(hes.)26 b(The)18 +b(function)g(is)g(called)h(with)195 2506 y Fk(text)p +Fu(,)11 b Fk(start)p Fu(,)g(and)h Fk(end)p Fu(.)19 b +Fk(start)11 b Fu(and)h Fk(end)i Fu(are)d(indices)i(in)g +Ft(rl_line_buffer)c Fu(de\014ning)k(the)f(b)q(ound-)195 +2560 y(aries)h(of)g Fk(text)p Fu(,)f(whic)o(h)i(is)g(a)e(c)o(haracter)h +(string.)19 b(If)13 b(this)g(function)h(exists)g(and)f(returns)g +Ft(NULL)p Fu(,)f(or)g(if)195 2615 y(this)f(v)m(ariable)i(is)e(set)g(to) +f Ft(NULL)p Fu(,)h(then)g Ft(rl_complete\(\))e Fu(will)k(call)f(the)f +(v)m(alue)h(of)f Ft(rl_completion_)195 2670 y(entry_function)h +Fu(to)i(generate)g(matc)o(hes,)f(otherwise)i(the)f(arra)o(y)f(of)h +(strings)g(returned)g(will)i(b)q(e)p eop +%%Page: 44 46 +44 45 bop 75 -58 a Fu(44)1299 b(GNU)15 b(Readline)h(Library)195 +149 y(used.)j(If)12 b(this)f(function)h(sets)f(the)g +Ft(rl_attempted_completion_over)d Fu(v)m(ariable)k(to)f(a)g(non-zero) +195 204 y(v)m(alue,)18 b(Readline)h(will)f(not)f(p)q(erform)f(its)i +(default)f(completion)h(ev)o(en)f(if)h(this)f(function)h(returns)195 +259 y(no)d(matc)o(hes.)1773 380 y(V)l(ariable)-1861 b +Fi(rl_quote_func_t)21 b(*)f Fh(rl)p 574 380 18 3 v 21 +w(\014lename)p 803 380 V 20 w(quoting)p 1012 380 V 21 +w(function)195 434 y Fu(A)c(p)q(oin)o(ter)h(to)f(a)g(function)h(that)e +(will)j(quote)e(a)g(\014lename)i(in)f(an)f(application-sp)q(eci\014)q +(c)j(fashion.)195 489 y(This)h(is)g(called)i(if)e(\014lename)g +(completion)h(is)f(b)q(eing)h(attempted)e(and)h(one)g(of)f(the)h(c)o +(haracters)195 544 y(in)d Ft(rl_filename_quote_characters)c +Fu(app)q(ears)k(in)g(a)g(completed)g(\014lename.)25 b(The)17 +b(function)195 599 y(is)i(called)i(with)e Fk(text)p Fu(,)g +Fk(matc)o(h)p 722 599 14 2 v 16 w(t)o(yp)q(e)p Fu(,)g(and)g +Fk(quote)p 1059 599 V 17 w(p)q(oin)o(ter)p Fu(.)31 b(The)19 +b Fk(text)h Fu(is)f(the)g(\014lename)h(to)e(b)q(e)195 +654 y(quoted.)39 b(The)21 b Fk(matc)o(h)p 607 654 V 16 +w(t)o(yp)q(e)j Fu(is)e(either)g Ft(SINGLE_MATCH)p Fu(,)f(if)h(there)f +(is)h(only)g(one)g(completion)195 708 y(matc)o(h,)15 +b(or)g Ft(MULT_MATCH)p Fu(.)20 b(Some)c(functions)g(use)g(this)g(to)f +(decide)j(whether)e(or)f(not)g(to)g(insert)h(a)195 763 +y(closing)c(quote)e(c)o(haracter.)18 b(The)11 b Fk(quote)p +877 763 V 16 w(p)q(oin)o(ter)k Fu(is)c(a)f(p)q(oin)o(ter)i(to)e(an)o(y) +g(op)q(ening)i(quote)f(c)o(haracter)195 818 y(the)k(user)h(t)o(yp)q +(ed.)k(Some)15 b(functions)h(c)o(ho)q(ose)f(to)g(reset)g(this)g(c)o +(haracter.)1773 938 y(V)l(ariable)-1861 b Fi(rl_dequote_func_t)22 +b(*)d Fh(rl)p 626 938 18 3 v 21 w(\014lename)p 855 938 +V 20 w(dequoting)p 1122 938 V 21 w(function)195 993 y +Fu(A)c(p)q(oin)o(ter)g(to)f(a)h(function)g(that)g(will)h(remo)o(v)o(e)e +(application-sp)q(eci\014)q(c)k(quoting)d(c)o(haracters)f(from)195 +1048 y(a)i(\014lename)h(b)q(efore)g(completion)g(is)g(attempted,)f(so)f +(those)h(c)o(haracters)g(do)g(not)g(in)o(terfere)h(with)195 +1103 y(matc)o(hing)i(the)g(text)g(against)f(names)h(in)h(the)f +(\014lesystem.)33 b(It)19 b(is)g(called)i(with)e Fk(text)p +Fu(,)g(the)g(text)195 1158 y(of)i(the)g(w)o(ord)g(to)g(b)q(e)h +(dequoted,)h(and)e Fk(quote)p 1009 1158 14 2 v 17 w(c)o(har)p +Fu(,)h(whic)o(h)g(is)g(the)f(quoting)h(c)o(haracter)f(that)195 +1212 y(delimits)d(the)e(\014lename)i(\(usually)f(`)p +Ft(')p Fu(')f(or)f(`)p Ft(")p Fu('\).)22 b(If)17 b Fk(quote)p +1187 1212 V 16 w(c)o(har)i Fu(is)e(zero,)f(the)g(\014lename)i(w)o(as)d +(not)195 1267 y(in)h(an)f(em)o(b)q(edded)i(string.)1773 +1388 y(V)l(ariable)-1861 b Fi(rl_linebuf_func_t)22 b(*)d +Fh(rl)p 626 1388 18 3 v 21 w(c)n(har)p 754 1388 V 21 +w(is)p 813 1388 V 21 w(quoted)p 1005 1388 V 21 w(p)195 +1443 y Fu(A)f(p)q(oin)o(ter)h(to)f(a)g(function)h(to)f(call)i(that)d +(determines)j(whether)e(or)g(not)g(a)g(sp)q(eci\014c)j(c)o(haracter)195 +1497 y(in)d(the)f(line)i(bu\013er)e(is)h(quoted,)g(according)f(to)g +(whatev)o(er)f(quoting)i(mec)o(hanism)g(the)f(program)195 +1552 y(calling)d(Readline)g(uses.)19 b(The)13 b(function)g(is)g(called) +h(with)f(t)o(w)o(o)e(argumen)o(ts:)17 b Fk(text)p Fu(,)12 +b(the)h(text)f(of)g(the)195 1607 y(line,)17 b(and)e Fk(index)p +Fu(,)i(the)e(index)i(of)e(the)g(c)o(haracter)g(in)h(the)g(line.)22 +b(It)15 b(is)h(used)g(to)f(decide)i(whether)e(a)195 1662 +y(c)o(haracter)f(found)i(in)g Ft(rl_completer_word_break_)o(charact)o +(ers)c Fu(should)k(b)q(e)g(used)g(to)e(break)195 1717 +y(w)o(ords)g(for)h(the)g(completer.)1773 1837 y(V)l(ariable)-1861 +b Fi(rl_compignore_func_t)22 b(*)d Fh(rl)p 704 1837 V +22 w(ignore)p 881 1837 V 20 w(some)p 1028 1837 V 19 w(completions)p +1344 1837 V 21 w(function)195 1892 y Fu(This)g(function,)i(if)e +(de\014ned,)i(is)e(called)h(b)o(y)f(the)g(completer)g(when)h(real)f +(\014lename)h(completion)195 1947 y(is)e(done,)f(after)f(all)i(the)f +(matc)o(hing)g(names)g(ha)o(v)o(e)g(b)q(een)h(generated.)25 +b(It)17 b(is)h(passed)f(a)g Ft(NULL)f Fu(ter-)195 2001 +y(minated)g(arra)o(y)e(of)h(matc)o(hes.)20 b(The)c(\014rst)f(elemen)o +(t)h(\()p Ft(matches[0])p Fu(\))d(is)j(the)g(maximal)g(substring)195 +2056 y(common)e(to)g(all)h(matc)o(hes.)k(This)c(function)g(can)g +(re-arrange)f(the)g(list)h(of)f(matc)o(hes)g(as)g(required,)195 +2111 y(but)h(eac)o(h)h(elemen)o(t)g(deleted)g(from)f(the)g(arra)o(y)f +(m)o(ust)g(b)q(e)i(freed.)1773 2232 y(V)l(ariable)-1861 +b Fi(rl_icppfunc_t)21 b(*)e Fh(rl)p 521 2232 V 21 w(directory)p +769 2232 V 22 w(completion)p 1065 2232 V 21 w(ho)r(ok)195 +2286 y Fu(This)k(function,)i(if)e(de\014ned,)j(is)d(allo)o(w)o(ed)g(to) +f(mo)q(dify)h(the)g(directory)g(p)q(ortion)g(of)f(\014lenames)195 +2341 y(Readline)e(completes.)29 b(It)19 b(is)f(called)i(with)f(the)f +(address)h(of)e(a)h(string)h(\(the)f(curren)o(t)g(directory)195 +2396 y(name\))g(as)g(an)h(argumen)o(t,)f(and)h(ma)o(y)f(mo)q(dify)h +(that)f(string.)30 b(If)19 b(the)f(string)h(is)g(replaced)h(with)195 +2451 y(a)g(new)g(string,)h(the)f(old)g(v)m(alue)h(should)g(b)q(e)g +(freed.)34 b(An)o(y)20 b(mo)q(di\014ed)i(directory)e(name)g(should)195 +2506 y(ha)o(v)o(e)14 b(a)g(trailing)i(slash.)k(The)15 +b(mo)q(di\014ed)h(v)m(alue)g(will)g(b)q(e)f(displa)o(y)o(ed)h(as)e +(part)g(of)h(the)f(completion,)195 2560 y(replacing)h(the)g(directory)f +(p)q(ortion)g(of)g(the)g(pathname)g(the)h(user)f(t)o(yp)q(ed.)20 +b(It)14 b(returns)g(an)g(in)o(teger)195 2615 y(that)i(should)h(b)q(e)g +(non-zero)g(if)g(the)g(function)g(mo)q(di\014es)h(its)e(directory)h +(argumen)o(t.)23 b(It)17 b(could)g(b)q(e)195 2670 y(used)f(to)e(expand) +i(sym)o(b)q(olic)h(links)f(or)f(shell)i(v)m(ariables)f(in)g(pathnames.) +p eop +%%Page: 45 47 +45 46 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(45)1773 149 y(V)l(ariable)-1861 b Fi +(rl_compdisp_func_t)22 b(*)d Fh(rl)p 652 149 18 3 v 21 +w(completion)p 947 149 V 21 w(displa)n(y)p 1141 149 V +22 w(matc)n(hes)p 1366 149 V 21 w(ho)r(ok)195 204 y Fu(If)11 +b(non-zero,)h(then)f(this)h(is)f(the)g(address)g(of)g(a)g(function)g +(to)g(call)h(when)f(completing)i(a)d(w)o(ord)h(w)o(ould)195 +259 y(normally)h(displa)o(y)g(the)f(list)h(of)f(p)q(ossible)h(matc)o +(hes.)18 b(This)12 b(function)g(is)g(called)g(in)g(lieu)h(of)e +(Readline)195 314 y(displa)o(ying)21 b(the)d(list.)32 +b(It)19 b(tak)o(es)f(three)h(argumen)o(ts:)26 b(\()p +Ft(char)14 b(**)p Fk(matc)o(hes)p Fu(,)19 b Ft(int)f +Fk(n)o(um)p 1688 314 14 2 v 17 w(matc)o(hes)p Fu(,)195 +369 y Ft(int)13 b Fk(max)p 368 369 V 16 w(length)p Fu(\))i(where)f +Fk(matc)o(hes)h Fu(is)f(the)g(arra)o(y)f(of)g(matc)o(hing)h(strings,)g +Fk(n)o(um)p 1578 369 V 16 w(matc)o(hes)i Fu(is)e(the)195 +423 y(n)o(um)o(b)q(er)h(of)f(strings)h(in)h(that)e(arra)o(y)l(,)f(and)i +Fk(max)p 1012 423 V 16 w(length)h Fu(is)f(the)g(length)g(of)g(the)f +(longest)h(string)g(in)195 478 y(that)e(arra)o(y)l(.)19 +b(Readline)c(pro)o(vides)g(a)e(con)o(v)o(enience)j(function,)f +Ft(rl_display_match_list)p Fu(,)c(that)195 533 y(tak)o(es)17 +b(care)g(of)g(doing)h(the)f(displa)o(y)i(to)d(Readline's)j(output)e +(stream.)26 b(That)16 b(function)j(ma)o(y)d(b)q(e)195 +588 y(called)h(from)d(this)i(ho)q(ok.)1773 704 y(V)l(ariable)-1861 +b Fi(const)20 b(char)g(*)f Fh(rl)p 436 704 18 3 v 21 +w(basic)p 580 704 V 21 w(w)n(ord)p 725 704 V 21 w(break)p +886 704 V 20 w(c)n(haracters)195 759 y Fu(The)j(basic)h(list)g(of)f(c)o +(haracters)f(that)g(signal)i(a)f(break)g(b)q(et)o(w)o(een)g(w)o(ords)g +(for)f(the)h(completer)195 814 y(routine.)30 b(The)19 +b(default)g(v)m(alue)h(of)e(this)h(v)m(ariable)h(is)f(the)g(c)o +(haracters)f(whic)o(h)h(break)g(w)o(ords)f(for)195 869 +y(completion)e(in)g(Bash:)k Ft(")15 b(\\t\\n\\"\\\\'`@$><=;|&{\(")p +Fu(.)1773 985 y(V)l(ariable)-1861 b Fi(const)20 b(char)g(*)f +Fh(rl)p 436 985 V 21 w(basic)p 580 985 V 21 w(quote)p +740 985 V 21 w(c)n(haracters)195 1040 y Fu(A)c(list)h(of)f(quote)g(c)o +(haracters)f(whic)o(h)i(can)g(cause)f(a)g(w)o(ord)g(break.)1773 +1156 y(V)l(ariable)-1861 b Fi(const)20 b(char)g(*)f Fh(rl)p +436 1156 V 21 w(completer)p 705 1156 V 21 w(w)n(ord)p +850 1156 V 20 w(break)p 1010 1156 V 20 w(c)n(haracters)195 +1211 y Fu(The)33 b(list)g(of)f(c)o(haracters)g(that)f(signal)j(a)e +(break)g(b)q(et)o(w)o(een)h(w)o(ords)f(for)g Ft(rl_complete_)195 +1266 y(internal\(\))p Fu(.)18 b(The)e(default)g(list)g(is)f(the)h(v)m +(alue)g(of)f Ft(rl_basic_word_break_chara)o(cters)p Fu(.)1773 +1382 y(V)l(ariable)-1861 b Fi(const)20 b(char)g(*)f Fh(rl)p +436 1382 V 21 w(completer)p 705 1382 V 21 w(quote)p 865 +1382 V 20 w(c)n(haracters)195 1437 y Fu(A)e(list)h(of)e(c)o(haracters)g +(whic)o(h)i(can)f(b)q(e)g(used)h(to)e(quote)h(a)f(substring)h(of)g(the) +g(line.)26 b(Completion)195 1492 y(o)q(ccurs)13 b(on)h(the)f(en)o(tire) +g(substring,)h(and)f(within)i(the)e(substring)g Ft +(rl_completer_word_break_)195 1547 y(characters)j Fu(are)h(treated)g +(as)h(an)o(y)f(other)g(c)o(haracter,)g(unless)i(they)e(also)h(app)q +(ear)g(within)h(this)195 1601 y(list.)1773 1718 y(V)l(ariable)-1861 +b Fi(const)20 b(char)g(*)f Fh(rl)p 436 1718 V 21 w(\014lename)p +665 1718 V 20 w(quote)p 824 1718 V 21 w(c)n(haracters)195 +1773 y Fu(A)e(list)h(of)e(c)o(haracters)g(that)g(cause)h(a)g +(\014lename)h(to)e(b)q(e)i(quoted)e(b)o(y)h(the)g(completer)h(when)f +(they)195 1828 y(app)q(ear)e(in)h(a)f(completed)h(\014lename.)21 +b(The)16 b(default)g(is)f(the)h(n)o(ull)g(string.)1773 +1944 y(V)l(ariable)-1861 b Fi(const)20 b(char)g(*)f Fh(rl)p +436 1944 V 21 w(sp)r(ecial)p 623 1944 V 22 w(pre\014xes)195 +1999 y Fu(The)14 b(list)h(of)e(c)o(haracters)g(that)g(are)h(w)o(ord)f +(break)h(c)o(haracters,)f(but)h(should)h(b)q(e)f(left)g(in)h +Fk(text)f Fu(when)195 2054 y(it)f(is)f(passed)h(to)f(the)g(completion)h +(function.)20 b(Programs)11 b(can)h(use)h(this)g(to)f(help)h(determine) +h(what)195 2108 y(kind)i(of)e(completing)i(to)e(do.)19 +b(F)l(or)14 b(instance,)i(Bash)e(sets)h(this)g(v)m(ariable)h(to)e +Ft(")p Fu($)p Ft(@")g Fu(so)g(that)g(it)h(can)195 2163 +y(complete)h(shell)h(v)m(ariables)f(and)g(hostnames.)1773 +2280 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 2280 +V 21 w(completion)p 510 2280 V 21 w(query)p 673 2280 +V 21 w(items)195 2334 y Fu(Up)e(to)g(this)g(man)o(y)g(items)g(will)i(b) +q(e)f(displa)o(y)o(ed)g(in)g(resp)q(onse)g(to)e(a)h(p)q +(ossible-completions)j(call.)195 2389 y(After)14 b(that,)f(w)o(e)h(ask) +g(the)h(user)f(if)h(she)f(is)h(sure)g(she)f(w)o(an)o(ts)f(to)h(see)h +(them)f(all.)20 b(The)15 b(default)g(v)m(alue)195 2444 +y(is)h(100.)1773 2560 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 2560 V 21 w(completion)p 510 2560 V 21 +w(app)r(end)p 715 2560 V 19 w(c)n(haracter)195 2615 y +Fu(When)d(a)f(single)i(completion)g(alternativ)o(e)f(matc)o(hes)f(at)g +(the)h(end)g(of)f(the)h(command)f(line,)j(this)195 2670 +y(c)o(haracter)10 b(is)h(app)q(ended)i(to)d(the)g(inserted)i +(completion)g(text.)18 b(The)11 b(default)g(is)g(a)g(space)g(c)o +(haracter)p eop +%%Page: 46 48 +46 47 bop 75 -58 a Fu(46)1299 b(GNU)15 b(Readline)h(Library)195 +149 y(\(`)e('\).)19 b(Setting)14 b(this)f(to)g(the)g(n)o(ull)i(c)o +(haracter)e(\(`)p Ft(\\0)p Fu('\))e(prev)o(en)o(ts)i(an)o(ything)h(b)q +(eing)h(app)q(ended)f(auto-)195 204 y(matically)l(.)21 +b(This)15 b(can)f(b)q(e)h(c)o(hanged)g(in)g(custom)f(completion)i +(functions)f(to)f(pro)o(vide)h(the)f(\\most)195 259 y(sensible)i(w)o +(ord)c(separator)h(c)o(haracter")f(according)i(to)f(an)h +(application-sp)q(eci\014c)j(command)c(line)195 314 y(syn)o(tax)h(sp)q +(eci\014cation.)1773 423 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 423 18 3 v 21 w(completion)p 510 423 V +21 w(suppress)p 746 423 V 19 w(app)r(end)195 478 y Fu(If)e(non-zero,)g +Fk(rl)p 476 478 14 2 v 17 w(completion)p 709 478 V 18 +w(app)q(end)p 871 478 V 17 w(c)o(haracter)i Fu(is)f(not)e(app)q(ended)i +(to)e(matc)o(hes)g(at)h(the)f(end)195 533 y(of)c(the)h(command)g(line,) +h(as)f(describ)q(ed)h(ab)q(o)o(v)o(e.)k(It)14 b(is)h(set)e(to)g(0)h(b)q +(efore)g(an)o(y)f(application-sp)q(eci)q(\014c)195 588 +y(completion)j(function)g(is)g(called.)1773 697 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 697 18 3 v 21 w(completion)p +510 697 V 21 w(mark)p 662 697 V 19 w(symlink)p 875 697 +V 21 w(dirs)195 752 y Fu(If)c(non-zero,)g(a)g(slash)g(will)i(b)q(e)e +(app)q(ended)i(to)d(completed)i(\014lenames)g(that)e(are)g(sym)o(b)q +(olic)j(links)195 807 y(to)11 b(directory)i(names,)f(sub)s(ject)g(to)f +(the)i(v)m(alue)g(of)f(the)g(user-settable)g Fk(mark-directories)j +Fu(v)m(ariable.)195 862 y(This)i(v)m(ariable)h(exists)f(so)g(that)e +(application)k(completion)f(functions)f(can)g(o)o(v)o(erride)g(the)f +(user's)195 917 y(global)f(preference)g(\(set)e(via)h(the)g +Fk(mark-symlink)o(ed-directories)k Fu(Readline)e(v)m(ariable\))f(if)f +(appro-)195 971 y(priate.)20 b(This)15 b(v)m(ariable)g(is)g(set)f(to)f +(the)i(user's)e(preference)j(b)q(efore)e(an)o(y)g(application)i +(completion)195 1026 y(function)j(is)g(called,)h(so)e(unless)h(that)f +(function)h(mo)q(di\014es)g(the)f(v)m(alue,)i(the)e(user's)g +(preferences)195 1081 y(are)d(honored.)1773 1191 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1191 V 21 w(ignore)p 391 1191 +V 20 w(completion)p 685 1191 V 21 w(duplicates)195 1245 +y Fu(If)15 b(non-zero,)h(then)f(duplicates)i(in)f(the)f(matc)o(hes)g +(are)g(remo)o(v)o(ed.)k(The)d(default)g(is)f(1.)1773 +1355 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p 215 1355 +V 21 w(\014lename)p 444 1355 V 20 w(completion)p 738 +1355 V 21 w(desired)195 1410 y Fu(Non-zero)c(means)g(that)f(the)h +(results)g(of)g(the)g(matc)o(hes)f(are)h(to)f(b)q(e)i(treated)e(as)g +(\014lenames.)23 b(This)195 1465 y(is)14 b Fl(always)j +Fu(zero)c(on)g(en)o(try)l(,)g(and)h(can)f(only)h(b)q(e)g(c)o(hanged)f +(within)i(a)e(completion)h(en)o(try)f(generator)195 1519 +y(function.)38 b(If)21 b(it)g(is)g(set)g(to)f(a)g(non-zero)h(v)m(alue,) +i(directory)e(names)g(ha)o(v)o(e)g(a)f(slash)h(app)q(ended)195 +1574 y(and)d(Readline)h(attempts)d(to)h(quote)g(completed)i +(\014lenames)f(if)g(they)g(con)o(tain)g(an)o(y)f(c)o(haracters)195 +1629 y(in)f Ft(rl_filename_quote_character)o(s)d Fu(and)i +Ft(rl_filename_quoting_desired)d Fu(is)k(set)f(to)f(a)195 +1684 y(non-zero)h(v)m(alue.)1773 1793 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 1793 V 21 w(\014lename)p 444 +1793 V 20 w(quoting)p 653 1793 V 21 w(desired)195 1848 +y Fu(Non-zero)14 b(means)g(that)f(the)i(results)f(of)g(the)g(matc)o +(hes)f(are)h(to)f(b)q(e)i(quoted)f(using)h(double)g(quotes)195 +1903 y(\(or)c(an)h(application-sp)q(eci\014)q(c)j(quoting)d(mec)o +(hanism\))g(if)h(the)f(completed)h(\014lename)g(con)o(tains)f(an)o(y) +195 1958 y(c)o(haracters)i(in)i Ft(rl_filename_quote_chars)p +Fu(.)h(This)f(is)f Fl(always)k Fu(non-zero)d(on)f(en)o(try)l(,)f(and)i +(can)195 2012 y(only)c(b)q(e)g(c)o(hanged)g(within)h(a)f(completion)g +(en)o(try)g(generator)e(function.)20 b(The)12 b(quoting)g(is)g +(e\013ected)195 2067 y(via)j(a)g(call)i(to)d(the)i(function)g(p)q(oin)o +(ted)g(to)e(b)o(y)h Ft(rl_filename_quoting_function)p +Fu(.)1773 2177 y(V)l(ariable)-1861 b Fi(int)20 b Fh(rl)p +215 2177 V 21 w(attempted)p 495 2177 V 20 w(completion)p +789 2177 V 21 w(o)n(v)n(er)195 2232 y Fu(If)47 b(an)g(application-sp)q +(eci\014)q(c)j(completion)e(function)g(assigned)f(to)g +Ft(rl_attempted_)195 2286 y(completion_function)24 b +Fu(sets)i(this)h(v)m(ariable)h(to)e(a)g(non-zero)h(v)m(alue,)j +(Readline)e(will)g(not)195 2341 y(p)q(erform)15 b(its)g(default)g +(\014lename)h(completion)g(ev)o(en)f(if)g(the)g(application's)h +(completion)g(function)195 2396 y(returns)f(no)g(matc)o(hes.)20 +b(It)15 b(should)h(b)q(e)g(set)f(only)h(b)o(y)f(an)g(application's)h +(completion)h(function.)1773 2506 y(V)l(ariable)-1861 +b Fi(int)20 b Fh(rl)p 215 2506 V 21 w(completion)p 510 +2506 V 21 w(t)n(yp)r(e)195 2560 y Fu(Set)e(to)e(a)i(c)o(haracter)f +(describing)i(the)e(t)o(yp)q(e)h(of)f(completion)i(Readline)g(is)f +(curren)o(tly)g(attempt-)195 2615 y(ing;)g(see)f(the)f(description)i +(of)f Ft(rl_complete_internal\(\))c Fu(\(see)k(Section)h(2.6.2)d +([Completion)195 2670 y(F)l(unctions],)g(page)g(42\))g(for)f(the)h +(list)h(of)f(c)o(haracters.)p eop +%%Page: 47 49 +47 48 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(47)1773 149 y(V)l(ariable)-1861 b Fi(int)20 +b Fh(rl)p 215 149 18 3 v 21 w(inhibit)p 399 149 V 23 +w(completion)195 204 y Fu(If)14 b(this)h(v)m(ariable)g(is)g(non-zero,)f +(completion)i(is)e(inhibited.)22 b(The)15 b(completion)g(c)o(haracter)e +(will)j(b)q(e)195 259 y(inserted)g(as)f(an)o(y)g(other)g(b)q(ound)h(to) +e Ft(self-insert)p Fu(.)75 371 y Fj(2.6.4)30 b(A)21 b(Short)f +(Completion)g(Example)137 467 y Fu(Here)11 b(is)f(a)g(small)h +(application)h(demonstrating)e(the)g(use)h(of)e(the)i(GNU)f(Readline)h +(library)l(.)19 b(It)11 b(is)f(called)75 522 y Ft(fileman)p +Fu(,)17 b(and)h(the)g(source)g(co)q(de)g(resides)h(in)f(`)p +Ft(examples/fileman.c)p Fu('.)25 b(This)18 b(sample)g(application)75 +577 y(pro)o(vides)c(completion)g(of)e(command)h(names,)g(line)i +(editing)g(features,)d(and)i(access)f(to)f(the)h(history)h(list.)p +eop +%%Page: 48 50 +48 49 bop 75 -58 a Fu(48)1299 b(GNU)15 b(Readline)h(Library)195 +149 y Ft(/*)24 b(fileman.c)e(--)i(A)g(tiny)f(application)f(which)h +(demonstrates)g(how)g(to)h(use)f(the)267 201 y(GNU)g(Readline)g +(library.)46 b(This)24 b(application)e(interactively)g(allows)h(users) +267 253 y(to)g(manipulate)g(files)g(and)g(their)g(modes.)h(*/)195 +357 y(#include)f()195 409 y(#include)g()195 +461 y(#include)g()195 513 y(#include)g()195 +565 y(#include)g()195 668 y(#include)g +()195 720 y(#include)g()195 +824 y(extern)g(char)g(*xmalloc)g(\(\);)195 928 y(/*)h(The)f(names)g(of) +h(functions)e(that)i(actually)f(do)g(the)h(manipulation.)e(*/)195 +980 y(int)h(com_list)g(__P\(\(char)g(*\)\);)195 1032 +y(int)g(com_view)g(__P\(\(char)g(*\)\);)195 1083 y(int)g(com_rename)g +(__P\(\(char)g(*\)\);)195 1135 y(int)g(com_stat)g(__P\(\(char)g(*\)\);) +195 1187 y(int)g(com_pwd)g(__P\(\(char)g(*\)\);)195 1239 +y(int)g(com_delete)g(__P\(\(char)g(*\)\);)195 1291 y(int)g(com_help)g +(__P\(\(char)g(*\)\);)195 1343 y(int)g(com_cd)g(__P\(\(char)g(*\)\);) +195 1395 y(int)g(com_quit)g(__P\(\(char)g(*\)\);)195 +1499 y(/*)h(A)f(structure)g(which)g(contains)g(information)f(on)i(the)f +(commands)g(this)g(program)267 1550 y(can)g(understand.)f(*/)195 +1654 y(typedef)h(struct)g({)243 1706 y(char)g(*name;)g(/*)h(User)f +(printable)g(name)g(of)h(the)f(function.)g(*/)243 1758 +y(rl_icpfunc_t)f(*func;)h(/*)h(Function)e(to)i(call)f(to)h(do)f(the)h +(job.)f(*/)243 1810 y(char)g(*doc;)g(/*)h(Documentation)e(for)h(this)h +(function.)46 b(*/)195 1862 y(})24 b(COMMAND;)195 1966 +y(COMMAND)f(commands[])f(=)i({)243 2017 y({)f("cd",)h(com_cd,)f +("Change)f(to)i(directory)f(DIR")g(},)243 2069 y({)g("delete",)g +(com_delete,)f("Delete)h(FILE")h(},)243 2121 y({)f("help",)g(com_help,) +g("Display)g(this)g(text")g(},)243 2173 y({)g("?",)h(com_help,)e +("Synonym)h(for)h(`help'")f(},)243 2225 y({)g("list",)g(com_list,)g +("List)g(files)g(in)h(DIR")f(},)243 2277 y({)g("ls",)h(com_list,)e +("Synonym)h(for)g(`list'")g(},)243 2329 y({)g("pwd",)g(com_pwd,)g +("Print)g(the)h(current)f(working)g(directory")f(},)243 +2381 y({)h("quit",)g(com_quit,)g("Quit)g(using)g(Fileman")g(},)243 +2433 y({)g("rename",)g(com_rename,)f("Rename)h(FILE)h(to)f(NEWNAME")g +(},)243 2484 y({)g("stat",)g(com_stat,)g("Print)g(out)g(statistics)g +(on)h(FILE")f(},)243 2536 y({)g("view",)g(com_view,)g("View)g(the)h +(contents)e(of)i(FILE")f(},)243 2588 y({)g(\(char)h(*\)NULL,)f +(\(rl_icpfunc_t)f(*\)NULL,)h(\(char)g(*\)NULL)g(})195 +2640 y(};)p eop +%%Page: 49 51 +49 50 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(49)195 201 y Ft(/*)24 b(Forward)e(declarations.)h(*/) +195 253 y(char)g(*stripwhite)g(\(\);)195 305 y(COMMAND)g(*find_command) +f(\(\);)195 409 y(/*)i(The)f(name)g(of)h(this)f(program,)g(as)h(taken)f +(from)g(argv[0].)g(*/)195 461 y(char)g(*progname;)195 +565 y(/*)h(When)f(non-zero,)g(this)g(means)g(the)g(user)h(is)f(done)h +(using)f(this)g(program.)g(*/)195 616 y(int)g(done;)195 +720 y(char)g(*)195 772 y(dupstr)g(\(s\))314 824 y(int)h(s;)195 +876 y({)243 928 y(char)f(*r;)243 1032 y(r)g(=)h(xmalloc)f(\(strlen)g +(\(s\))g(+)h(1\);)243 1083 y(strcpy)f(\(r,)g(s\);)243 +1135 y(return)g(\(r\);)195 1187 y(})195 1291 y(main)g(\(argc,)g(argv\)) +314 1343 y(int)h(argc;)314 1395 y(char)g(**argv;)195 +1447 y({)243 1499 y(char)f(*line,)g(*s;)243 1602 y(progname)f(=)i +(argv[0];)243 1706 y(initialize_readline)d(\(\);)i(/*)h(Bind)f(our)h +(completer.)e(*/)243 1810 y(/*)h(Loop)h(reading)f(and)g(executing)g +(lines)g(until)g(the)g(user)h(quits.)f(*/)243 1862 y(for)g(\()h(;)g +(done)f(==)h(0;)f(\))290 1914 y({)338 1966 y(line)g(=)h(readline)f +(\("FileMan:)f("\);)338 2069 y(if)i(\(!line\))386 2121 +y(break;)338 2225 y(/*)g(Remove)f(leading)g(and)g(trailing)g +(whitespace)f(from)i(the)f(line.)410 2277 y(Then,)g(if)h(there)f(is)g +(anything)g(left,)g(add)h(it)f(to)h(the)f(history)g(list)410 +2329 y(and)g(execute)g(it.)h(*/)338 2381 y(s)g(=)g(stripwhite)e +(\(line\);)338 2484 y(if)i(\(*s\))386 2536 y({)434 2588 +y(add_history)e(\(s\);)434 2640 y(execute_line)g(\(s\);)p +eop +%%Page: 50 52 +50 51 bop 75 -58 a Fu(50)1299 b(GNU)15 b(Readline)h(Library)386 +149 y Ft(})338 253 y(free)23 b(\(line\);)290 305 y(})243 +357 y(exit)g(\(0\);)195 409 y(})195 513 y(/*)h(Execute)e(a)i(command)f +(line.)g(*/)195 565 y(int)195 616 y(execute_line)f(\(line\))314 +668 y(char)i(*line;)195 720 y({)243 772 y(register)e(int)i(i;)243 +824 y(COMMAND)f(*command;)243 876 y(char)g(*word;)243 +980 y(/*)g(Isolate)g(the)h(command)f(word.)g(*/)243 1032 +y(i)g(=)h(0;)243 1083 y(while)f(\(line[i])g(&&)g(whitespace)g +(\(line[i]\)\))290 1135 y(i++;)243 1187 y(word)g(=)h(line)f(+)h(i;)243 +1291 y(while)f(\(line[i])g(&&)g(!whitespace)g(\(line[i]\)\))290 +1343 y(i++;)243 1447 y(if)g(\(line[i]\))290 1499 y(line[i++])g(=)h +('\\0';)243 1602 y(command)f(=)g(find_command)g(\(word\);)243 +1706 y(if)g(\(!command\))290 1758 y({)338 1810 y(fprintf)g(\(stderr,)g +("\045s:)g(No)h(such)f(command)g(for)g(FileMan.\\n",)g(word\);)338 +1862 y(return)g(\(-1\);)290 1914 y(})243 2017 y(/*)g(Get)h(argument)f +(to)g(command,)g(if)g(any.)h(*/)243 2069 y(while)f(\(whitespace)f +(\(line[i]\)\))290 2121 y(i++;)243 2225 y(word)h(=)h(line)f(+)h(i;)243 +2329 y(/*)f(Call)h(the)f(function.)g(*/)243 2381 y(return)g +(\(\(*\(command->func\)\))e(\(word\)\);)195 2433 y(})195 +2536 y(/*)j(Look)f(up)g(NAME)h(as)f(the)h(name)f(of)h(a)f(command,)g +(and)h(return)f(a)g(pointer)g(to)h(that)267 2588 y(command.)46 +b(Return)23 b(a)h(NULL)f(pointer)g(if)h(NAME)f(isn't)g(a)h(command)f +(name.)g(*/)195 2640 y(COMMAND)g(*)p eop +%%Page: 51 53 +51 52 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(51)195 149 y Ft(find_command)22 b(\(name\))314 +201 y(char)i(*name;)195 253 y({)243 305 y(register)e(int)i(i;)243 +409 y(for)f(\(i)h(=)f(0;)h(commands[i].name;)e(i++\))290 +461 y(if)i(\(strcmp)f(\(name,)g(commands[i].name\))f(==)h(0\))338 +513 y(return)g(\(&commands[i]\);)243 616 y(return)g(\(\(COMMAND)f +(*\)NULL\);)195 668 y(})195 772 y(/*)i(Strip)f(whitespace)f(from)i(the) +f(start)g(and)h(end)f(of)h(STRING.)46 b(Return)24 b(a)f(pointer)267 +824 y(into)g(STRING.)g(*/)195 876 y(char)g(*)195 928 +y(stripwhite)f(\(string\))314 980 y(char)i(*string;)195 +1032 y({)243 1083 y(register)e(char)i(*s,)f(*t;)243 1187 +y(for)g(\(s)h(=)f(string;)g(whitespace)g(\(*s\);)g(s++\))290 +1239 y(;)243 1343 y(if)g(\(*s)h(==)f(0\))290 1395 y(return)g(\(s\);)243 +1499 y(t)g(=)h(s)g(+)g(strlen)f(\(s\))g(-)h(1;)243 1550 +y(while)f(\(t)g(>)h(s)g(&&)g(whitespace)e(\(*t\)\))290 +1602 y(t--;)243 1654 y(*++t)h(=)h('\\0';)243 1758 y(return)f(s;)195 +1810 y(})195 1914 y(/*)h(***********************)o(*******)o(********)o +(*******)o(*******)o(********)o(****)d(*/)195 1966 y(/*)1575 +b(*/)195 2017 y(/*)429 b(Interface)23 b(to)g(Readline)g(Completion)381 +b(*/)195 2069 y(/*)1575 b(*/)195 2121 y(/*)24 b +(***********************)o(*******)o(********)o(*******)o(*******)o +(********)o(****)d(*/)195 2225 y(char)i(*command_generator)f +(__P\(\(const)g(char)i(*,)f(int\)\);)195 2277 y(char)g +(**fileman_completion)e(__P\(\(const)i(char)g(*,)h(int,)f(int\)\);)195 +2381 y(/*)h(Tell)f(the)g(GNU)h(Readline)f(library)f(how)i(to)g +(complete.)46 b(We)24 b(want)f(to)h(try)f(to)267 2433 +y(complete)f(on)i(command)f(names)g(if)h(this)f(is)h(the)f(first)g +(word)g(in)h(the)g(line,)f(or)267 2484 y(on)g(filenames)g(if)g(not.)h +(*/)195 2536 y(initialize_readline)d(\(\))195 2588 y({)243 +2640 y(/*)i(Allow)g(conditional)g(parsing)g(of)g(the)h(~/.inputrc)e +(file.)h(*/)p eop +%%Page: 52 54 +52 53 bop 75 -58 a Fu(52)1299 b(GNU)15 b(Readline)h(Library)243 +149 y Ft(rl_readline_name)21 b(=)j("FileMan";)243 253 +y(/*)f(Tell)h(the)f(completer)g(that)g(we)h(want)f(a)h(crack)f(first.)g +(*/)243 305 y(rl_attempted_completion_)o(functio)o(n)e(=)j +(fileman_completion;)195 357 y(})195 461 y(/*)g(Attempt)e(to)i +(complete)f(on)g(the)h(contents)f(of)g(TEXT.)47 b(START)23 +b(and)h(END)267 513 y(bound)f(the)g(region)g(of)h(rl_line_buffer)e +(that)h(contains)g(the)g(word)h(to)267 565 y(complete.)46 +b(TEXT)23 b(is)h(the)f(word)h(to)f(complete.)47 b(We)23 +b(can)h(use)f(the)h(entire)267 616 y(contents)e(of)i(rl_line_buffer)e +(in)h(case)h(we)f(want)h(to)f(do)h(some)f(simple)267 +668 y(parsing.)46 b(Returnthe)23 b(array)g(of)h(matches,)e(or)i(NULL)f +(if)h(there)f(aren't)g(any.)g(*/)195 720 y(char)g(**)195 +772 y(fileman_completion)e(\(text,)i(start,)g(end\))314 +824 y(const)g(char)h(*text;)314 876 y(int)g(start,)f(end;)195 +928 y({)243 980 y(char)g(**matches;)243 1083 y(matches)g(=)g(\(char)h +(**\)NULL;)243 1187 y(/*)f(If)h(this)f(word)h(is)f(at)h(the)f(start)g +(of)h(the)f(line,)h(then)f(it)g(is)h(a)g(command)314 +1239 y(to)g(complete.)46 b(Otherwise)23 b(it)h(is)f(the)h(name)f(of)h +(a)f(file)h(in)f(the)h(current)314 1291 y(directory.)f(*/)243 +1343 y(if)g(\(start)g(==)h(0\))290 1395 y(matches)f(=)h +(rl_completion_matches)d(\(text,)i(command_generator\);)243 +1499 y(return)g(\(matches\);)195 1550 y(})195 1654 y(/*)h(Generator)e +(function)h(for)g(command)g(completion.)47 b(STATE)23 +b(lets)g(us)267 1706 y(know)g(whether)g(to)g(start)h(from)f(scratch;)g +(without)g(any)g(state)267 1758 y(\(i.e.)g(STATE)g(==)h(0\),)f(then)g +(we)h(start)f(at)h(the)f(top)h(of)f(the)h(list.)f(*/)195 +1810 y(char)g(*)195 1862 y(command_generator)f(\(text,)h(state\))314 +1914 y(const)g(char)h(*text;)314 1966 y(int)g(state;)195 +2017 y({)243 2069 y(static)f(int)g(list_index,)g(len;)243 +2121 y(char)g(*name;)243 2225 y(/*)g(If)h(this)f(is)h(a)g(new)f(word)g +(to)h(complete,)f(initialize)f(now.)47 b(This)314 2277 +y(includes)23 b(saving)g(the)h(length)f(of)g(TEXT)h(for)f(efficiency,)f +(and)314 2329 y(initializing)h(the)g(index)g(variable)g(to)h(0.)f(*/) +243 2381 y(if)g(\(!state\))290 2433 y({)338 2484 y(list_index)g(=)g(0;) +338 2536 y(len)h(=)f(strlen)g(\(text\);)290 2588 y(})p +eop +%%Page: 53 55 +53 54 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(53)243 149 y Ft(/*)23 b(Return)g(the)h(next)f(name)g +(which)h(partially)e(matches)h(from)g(the)314 201 y(command)g(list.)g +(*/)243 253 y(while)g(\(name)g(=)h(commands[list_index].name)o(\))290 +305 y({)338 357 y(list_index++;)338 461 y(if)g(\(strncmp)f(\(name,)g +(text,)g(len\))g(==)h(0\))386 513 y(return)f(\(dupstr\(name\)\);)290 +565 y(})243 668 y(/*)g(If)h(no)f(names)h(matched,)e(then)i(return)f +(NULL.)g(*/)243 720 y(return)g(\(\(char)g(*\)NULL\);)195 +772 y(})195 876 y(/*)h(***********************)o(*******)o(********)o +(*******)o(*******)o(********)o(****)d(*/)195 928 y(/*)1575 +b(*/)195 980 y(/*)549 b(FileMan)22 b(Commands)644 b(*/)195 +1032 y(/*)1575 b(*/)195 1083 y(/*)24 b(***********************)o +(*******)o(********)o(*******)o(*******)o(********)o(****)d(*/)195 +1187 y(/*)j(String)f(to)g(pass)h(to)f(system)g(\(\).)47 +b(This)24 b(is)f(for)h(the)f(LIST,)g(VIEW)h(and)f(RENAME)267 +1239 y(commands.)f(*/)195 1291 y(static)h(char)g(syscom[1024];)195 +1395 y(/*)h(List)f(the)g(file\(s\))g(named)g(in)h(arg.)f(*/)195 +1447 y(com_list)g(\(arg\))314 1499 y(char)h(*arg;)195 +1550 y({)243 1602 y(if)f(\(!arg\))290 1654 y(arg)h(=)g("";)243 +1758 y(sprintf)f(\(syscom,)f("ls)i(-FClg)f(\045s",)g(arg\);)243 +1810 y(return)g(\(system)g(\(syscom\)\);)195 1862 y(})195 +1966 y(com_view)g(\(arg\))314 2017 y(char)h(*arg;)195 +2069 y({)243 2121 y(if)f(\(!valid_argument)f(\("view",)h(arg\)\))290 +2173 y(return)g(1;)243 2277 y(sprintf)g(\(syscom,)f("more)i(\045s",)f +(arg\);)243 2329 y(return)g(\(system)g(\(syscom\)\);)195 +2381 y(})195 2484 y(com_rename)f(\(arg\))314 2536 y(char)i(*arg;)195 +2588 y({)243 2640 y(too_dangerous)e(\("rename"\);)p eop +%%Page: 54 56 +54 55 bop 75 -58 a Fu(54)1299 b(GNU)15 b(Readline)h(Library)243 +149 y Ft(return)23 b(\(1\);)195 201 y(})195 305 y(com_stat)g(\(arg\)) +314 357 y(char)h(*arg;)195 409 y({)243 461 y(struct)f(stat)g(finfo;)243 +565 y(if)g(\(!valid_argument)f(\("stat",)h(arg\)\))290 +616 y(return)g(\(1\);)243 720 y(if)g(\(stat)g(\(arg,)h(&finfo\))f(==)g +(-1\))290 772 y({)338 824 y(perror)g(\(arg\);)338 876 +y(return)g(\(1\);)290 928 y(})243 1032 y(printf)g(\("Statistics)f(for)h +(`\045s':\\n",)g(arg\);)243 1135 y(printf)g(\("\045s)g(has)h(\045d)f +(link\045s,)g(and)g(is)h(\045d)g(byte\045s)f(in)g(length.\\n",)g(arg,) +434 1187 y(finfo.st_nlink,)434 1239 y(\(finfo.st_nlink)e(==)j(1\))g(?)f +("")h(:)g("s",)434 1291 y(finfo.st_size,)434 1343 y(\(finfo.st_size)e +(==)h(1\))h(?)f("")h(:)g("s"\);)243 1395 y(printf)f(\("Inode)g(Last)g +(Change)g(at:)g(\045s",)h(ctime)f(\(&finfo.st_ctime\)\);)243 +1447 y(printf)g(\(")143 b(Last)23 b(access)g(at:)g(\045s",)h(ctime)f +(\(&finfo.st_atime\)\);)243 1499 y(printf)g(\(")95 b(Last)23 +b(modified)g(at:)g(\045s",)h(ctime)f(\(&finfo.st_mtime\)\);)243 +1550 y(return)g(\(0\);)195 1602 y(})195 1706 y(com_delete)f(\(arg\))314 +1758 y(char)i(*arg;)195 1810 y({)243 1862 y(too_dangerous)e +(\("delete"\);)243 1914 y(return)h(\(1\);)195 1966 y(})195 +2069 y(/*)h(Print)f(out)g(help)h(for)f(ARG,)g(or)h(for)f(all)h(of)f +(the)h(commands)f(if)g(ARG)h(is)267 2121 y(not)f(present.)g(*/)195 +2173 y(com_help)g(\(arg\))314 2225 y(char)h(*arg;)195 +2277 y({)243 2329 y(register)e(int)i(i;)243 2381 y(int)f(printed)g(=)h +(0;)243 2484 y(for)f(\(i)h(=)f(0;)h(commands[i].name;)e(i++\))290 +2536 y({)338 2588 y(if)i(\(!*arg)f(||)g(\(strcmp)g(\(arg,)g +(commands[i].name\))f(==)i(0\)\))386 2640 y({)p eop +%%Page: 55 57 +55 56 bop 75 -58 a Fu(Chapter)15 b(2:)k(Programming)c(with)g(GNU)g +(Readline)843 b(55)434 149 y Ft(printf)23 b(\("\045s\\t\\t\045s.\\n",)e +(commands[i].name,)h(commands[i].doc\);)434 201 y(printed++;)386 +253 y(})290 305 y(})243 409 y(if)h(\(!printed\))290 461 +y({)338 513 y(printf)g(\("No)h(commands)e(match)h(`\045s'.)48 +b(Possibilties)22 b(are:\\n",)h(arg\);)338 616 y(for)h(\(i)f(=)h(0;)g +(commands[i].name;)d(i++\))386 668 y({)434 720 y(/*)i(Print)g(in)h(six) +f(columns.)g(*/)434 772 y(if)g(\(printed)g(==)h(6\))481 +824 y({)529 876 y(printed)f(=)h(0;)529 928 y(printf)f(\("\\n"\);)481 +980 y(})434 1083 y(printf)g(\("\045s\\t",)f(commands[i].name\);)434 +1135 y(printed++;)386 1187 y(})338 1291 y(if)i(\(printed\))386 +1343 y(printf)f(\("\\n"\);)290 1395 y(})243 1447 y(return)g(\(0\);)195 +1499 y(})195 1602 y(/*)h(Change)f(to)g(the)h(directory)e(ARG.)i(*/)195 +1654 y(com_cd)f(\(arg\))314 1706 y(char)h(*arg;)195 1758 +y({)243 1810 y(if)f(\(chdir)g(\(arg\))h(==)f(-1\))290 +1862 y({)338 1914 y(perror)g(\(arg\);)338 1966 y(return)g(1;)290 +2017 y(})243 2121 y(com_pwd)g(\(""\);)243 2173 y(return)g(\(0\);)195 +2225 y(})195 2329 y(/*)h(Print)f(out)g(the)h(current)f(working)f +(directory.)h(*/)195 2381 y(com_pwd)g(\(ignore\))314 +2433 y(char)h(*ignore;)195 2484 y({)243 2536 y(char)f(dir[1024],)g(*s;) +243 2640 y(s)g(=)h(getcwd)f(\(dir,)g(sizeof\(dir\))g(-)g(1\);)p +eop +%%Page: 56 58 +56 57 bop 75 -58 a Fu(56)1299 b(GNU)15 b(Readline)h(Library)243 +149 y Ft(if)23 b(\(s)h(==)f(0\))290 201 y({)338 253 y(printf)g +(\("Error)g(getting)g(pwd:)g(\045s\\n",)g(dir\);)338 +305 y(return)g(1;)290 357 y(})243 461 y(printf)g(\("Current)f +(directory)h(is)h(\045s\\n",)f(dir\);)243 513 y(return)g(0;)195 +565 y(})195 668 y(/*)h(The)f(user)g(wishes)g(to)h(quit)f(using)g(this)h +(program.)46 b(Just)24 b(set)f(DONE)267 720 y(non-zero.)f(*/)195 +772 y(com_quit)h(\(arg\))314 824 y(char)h(*arg;)195 876 +y({)243 928 y(done)f(=)h(1;)243 980 y(return)f(\(0\);)195 +1032 y(})195 1135 y(/*)h(Function)e(which)i(tells)f(you)g(that)g(you)h +(can't)f(do)h(this.)f(*/)195 1187 y(too_dangerous)f(\(caller\))314 +1239 y(char)i(*caller;)195 1291 y({)243 1343 y(fprintf)f(\(stderr,)457 +1395 y("\045s:)h(Too)f(dangerous)g(for)g(me)h(to)g(distribute.\\n")457 +1447 y(caller\);)243 1499 y(fprintf)f(\(stderr,)f("Write)h(it)h +(yourself.\\n"\);)195 1550 y(})195 1654 y(/*)g(Return)f(non-zero)f(if)i +(ARG)f(is)h(a)g(valid)f(argument)g(for)g(CALLER,)267 +1706 y(else)g(print)g(an)h(error)f(message)g(and)g(return)g(zero.)g(*/) +195 1758 y(int)195 1810 y(valid_argument)f(\(caller,)h(arg\))314 +1862 y(char)h(*caller,)e(*arg;)195 1914 y({)243 1966 +y(if)h(\(!arg)g(||)h(!*arg\))290 2017 y({)338 2069 y(fprintf)f +(\(stderr,)g("\045s:)g(Argument)g(required.\\n",)f(caller\);)338 +2121 y(return)h(\(0\);)290 2173 y(})243 2277 y(return)g(\(1\);)195 +2329 y(})p eop +%%Page: 57 59 +57 58 bop 75 -58 a Fu(Concept)15 b(Index)1466 b(57)75 +149 y Fq(Concept)27 b(Index)75 321 y Fs(C)75 382 y Ff(command)14 +b(editing)e Fe(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 +b Ff(1)75 511 y Fs(E)75 572 y Ff(editing)15 b(command)f(lines)f +Fe(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)24 b Ff(1)75 702 y Fs(I)75 +763 y Ff(initiali)q(zati)q(on)16 b(\014le,)e(readline)t +Fe(.)8 b(.)e(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)17 b Ff(4)75 808 y(in)o(teraction,)e(readline)5 +b Fe(.)j(.)f(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)18 b Ff(1)75 +938 y Fs(K)75 999 y Ff(kill)d(ring)8 b Fe(.)f(.)f(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)20 +b Ff(3)75 1044 y(killing)c(text)9 b Fe(.)d(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)21 b Ff(2)1012 321 +y Fs(N)1012 390 y Ff(notation,)15 b(readline)7 b Fe(.)h(.)e(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)20 b Ff(1)1012 539 y Fs(R)1012 +608 y Ff(readline,)15 b(function)8 b Fe(.)g(.)e(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)21 b Ff(21)1012 757 y Fs(V)1012 826 y Ff(v)n(ariables,)15 +b(readline)t Fe(.)9 b(.)d(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)17 +b Ff(4)1012 976 y Fs(Y)1012 1044 y Ff(y)o(anking)e(text)t +Fe(.)7 b(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)17 +b Ff(2)p eop +%%Page: 58 60 +58 59 bop 75 -58 a Fu(58)1299 b(GNU)15 b(Readline)h(Library)p +eop +%%Page: 59 61 +59 60 bop 75 -58 a Fu(F)l(unction)16 b(and)f(V)l(ariable)i(Index)1187 +b(59)75 149 y Fq(F)-7 b(unction)26 b(and)h(V)-7 b(ariable)26 +b(Index)p 79 307 21 3 v 75 369 a Fd(_rl_digit_)o(p)7 +b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 +b Ff(36)75 415 y Fd(_rl_digit_)o(va)o(lue)6 b Fe(.)t(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)20 b Ff(37)75 462 y Fd(_rl_lowerc)o(as)o(e_p)6 +b Fe(.)t(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)20 b Ff(36)75 +508 y Fd(_rl_to_low)o(er)6 b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)22 b Ff(36)75 554 y Fd(_rl_to_upp)o(er)6 +b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)22 +b Ff(36)75 600 y Fd(_rl_upperc)o(as)o(e_p)6 b Fe(.)t(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)20 b Ff(36)75 733 y Fs(A)75 794 y +Fd(abort)11 b(\(C-g\))5 b Fe(.)t(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)17 b Ff(17)75 841 y Fd(accept-lin)o(e)10 +b(\(Newline)f(or)j(Return\))6 b Fe(.)t(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)19 b Ff(12)75 973 y Fs(B)75 1035 y Fd(backward-c)o(ha)o(r)10 +b(\(C-b\))e Fe(.)t(.)e(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)21 b Ff(12)75 +1081 y Fd(backward-d)o(el)o(ete)o(-c)o(har)9 b(\(Rubout\))e +Fe(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 +b Ff(14)75 1127 y Fd(backward-k)o(il)o(l-l)o(in)o(e)10 +b(\(C-x)h(Rubout\))e Fe(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)24 +b Ff(15)75 1174 y Fd(backward-k)o(il)o(l-w)o(or)o(d)10 +b(\(M-)501 1172 y Fn(h)p 512 1146 73 2 v 512 1174 a Fm(DEL)p +512 1181 V 583 1172 a Fn(i)598 1174 y Fd(\))g Fe(.)c(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)23 b Ff(15)75 1220 y +Fd(backward-w)o(or)o(d)10 b(\(M-b\))e Fe(.)t(.)e(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)21 +b Ff(12)75 1266 y Fd(beginning-)o(of)o(-hi)o(st)o(ory)9 +b(\(M-<\))h Fe(.)c(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)25 b Ff(13)75 1312 y Fd(beginning-)o(of)o(-li)o(ne)9 +b(\(C-a\))c Fe(.)t(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)18 b Ff(12)75 1359 y(b)q(ell-st)o(yle)7 +b Fe(.)i(.)d(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)20 b Ff(5)75 1490 y Fs(C)75 1552 y Fd(call-last-)o(kb)o(d-m) +o(ac)o(ro)9 b(\(C-x)j(e\))5 b Fe(.)h(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)g(.)h(.)f(.)18 b Ff(17)75 1598 y Fd(capitalize)o(-w)o(ord)9 +b(\(M-c\))d Fe(.)f(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)19 b Ff(14)75 1644 y Fd(character-)o(se) +o(arc)o(h)10 b(\(C-]\))c Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)18 b Ff(18)75 +1691 y Fd(character-)o(se)o(arc)o(h-)o(bac)o(kwa)o(rd)9 +b(\(M-C-]\))e Fe(.)s(.)g(.)f(.)g(.)g(.)g(.)g(.)g(.)20 +b Ff(18)75 1737 y Fd(clear-scre)o(en)9 b(\(C-l\))g Fe(.)t(.)d(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)21 b Ff(12)75 1783 y(commen)o(t-b)q(egin)9 +b Fe(.)f(.)e(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)21 +b Ff(5)75 1829 y Fd(complete)10 b(\()265 1827 y Fn(h)p +276 1801 74 2 v 276 1829 a Fm(T)m(AB)p 276 1837 V 348 +1827 a Fn(i)363 1829 y Fd(\))f Fe(.)e(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +22 b Ff(16)75 1875 y(completion-query-i)q(tems)t Fe(.)9 +b(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)16 b Ff(5)75 1922 y(con)o(v)o(ert-meta)10 +b Fe(.)c(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)22 +b Ff(5)75 1968 y Fd(copy-backw)o(ar)o(d-w)o(or)o(d)10 +b(\(\))c Fe(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)19 b Ff(15)75 2014 y Fd(copy-forwa)o(rd)o +(-wo)o(rd)9 b(\(\))e Fe(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)20 b Ff(16)75 +2060 y Fd(copy-regio)o(n-)o(as-)o(ki)o(ll)9 b(\(\))d +Fe(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)18 b Ff(15)75 2193 y Fs(D)75 2255 y Fd(delete-cha)o(r)10 +b(\(C-d\))d Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)22 b Ff(14)75 +2301 y Fd(delete-cha)o(r-)o(or-)o(li)o(st)9 b(\(\))d +Fe(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)18 b Ff(17)75 2347 y Fd(delete-hor)o(iz)o(ont)o(al)o +(-sp)o(ace)9 b(\(\))i Fe(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)25 b Ff(15)75 2393 y Fd(digit-argu)o(me)o(nt)9 +b(\()p Fc(M-0)p Fd(,)i Fc(M-1)p Fd(,)h(...)f Fc(M--)p +Fd(\))c Fe(.)e(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)20 b Ff(16)75 +2439 y(disable-comple)q(tion)9 b Fe(.)g(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)21 b Ff(5)75 2486 y Fd(do-upperca)o(se)o(-ve)o(rs)o(ion)9 +b(\(M-a,)i(M-b,)g(M-)p Fb(x)p Fd(,)h(...)o(\))159 2531 +y Fe(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)20 b Ff(17)75 2578 y Fd(downcase-w)o(or)o(d)10 +b(\(M-l\))e Fe(.)t(.)e(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)21 b Ff(14)75 +2624 y Fd(dump-funct)o(io)o(ns)9 b(\(\))g Fe(.)d(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)22 b Ff(18)75 2670 y Fd(dump-macro)o(s)10 b(\(\))g +Fe(.)c(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)24 b Ff(18)1012 +307 y Fd(dump-variab)o(le)o(s)10 b(\(\))e Fe(.)e(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)23 b Ff(18)1012 449 y Fs(E)1012 514 y Ff(editing-mo)q(de)12 +b Fe(.)7 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)22 +b Ff(5)1012 562 y Fd(emacs-editi)o(ng)o(-mo)o(de)9 b(\(C-e\))t +Fe(.)c(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)18 b Ff(18)1012 610 y(enable-k)o(eypad)9 b Fe(.)g(.)d(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 b Ff(5)1012 +658 y Fd(end-kbd-mac)o(ro)9 b(\(C-x)i(\)\))e Fe(.)e(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)23 +b Ff(17)1012 706 y Fd(end-of-hist)o(or)o(y)10 b(\(M->\))d +Fe(.)t(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)20 b Ff(13)1012 754 y Fd(end-of-line)9 +b(\(C-e\))e Fe(.)f(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)23 b Ff(12)1012 +802 y Fd(exchange-po)o(in)o(t-a)o(nd)o(-ma)o(rk)9 b(\(C-x)j(C-x\))c +Fe(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)24 b Ff(18)1012 +850 y(expand-tilde)6 b Fe(.)j(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)19 b Ff(5)1012 991 y Fs(F)1012 1056 +y Fd(forward-bac)o(kw)o(ard)o(-d)o(ele)o(te)o(-ch)o(ar)9 +b(\(\))f Fe(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)22 +b Ff(14)1012 1104 y Fd(forward-cha)o(r)10 b(\(C-f\))f +Fe(.)s(.)e(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 b Ff(12)1012 1152 y +Fd(forward-sea)o(rc)o(h-h)o(is)o(tor)o(y)10 b(\(C-s\))e +Fe(.)e(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)24 +b Ff(13)1012 1200 y Fd(forward-wor)o(d)10 b(\(M-f\))f +Fe(.)s(.)e(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 b Ff(12)1012 1334 y +Fs(H)1012 1400 y Ff(history-preserv)o(e-p)q(oi)q(n)o(t)8 +b Fe(.)h(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)21 b Ff(5)1012 1448 y +Fd(history-sea)o(rc)o(h-b)o(ac)o(kwa)o(rd)9 b(\(\))i +Fe(.)c(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)25 +b Ff(13)1012 1496 y Fd(history-sea)o(rc)o(h-f)o(or)o(war)o(d)10 +b(\(\))s Fe(.)c(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)17 b Ff(13)1012 1543 y(horizon)o(tal-scrol)q(l-mo)r(de)6 +b Fe(.)j(.)d(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)19 b Ff(6)1012 1678 y +Fs(I)1012 1743 y Ff(input-meta)8 b Fe(.)g(.)e(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 b Ff(6)1012 1791 +y Fd(insert-comm)o(en)o(t)10 b(\(M-#\))d Fe(.)t(.)f(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)20 +b Ff(18)1012 1839 y Fd(insert-comp)o(le)o(tio)o(ns)9 +b(\(M-*\))t Fe(.)c(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)18 b Ff(16)1012 1887 y(isearc)o(h-terminators)t +Fe(.)8 b(.)f(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)16 b Ff(6)1012 +2021 y Fs(K)1012 2087 y Ff(k)o(eymap)9 b Fe(.)e(.)f(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 +b Ff(6)1012 2135 y Fd(kill-line)10 b(\(C-k\))f Fe(.)d(.)g(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)24 b Ff(15)1012 2183 y Fd(kill-region)9 +b(\(\))i Fe(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 +b Ff(15)1012 2231 y Fd(kill-whole-)o(li)o(ne)9 b(\(\))g +Fe(.)c(.)i(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 b Ff(15)1012 2278 y +Fd(kill-word)10 b(\(M-d\))f Fe(.)d(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +24 b Ff(15)1012 2413 y Fs(M)1012 2478 y Ff(mark-mo)q(di\014ed-li)q(nes) +8 b Fe(.)h(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 b Ff(6)1012 +2526 y(mark-symlink)o(ed-di)q(rectori)q(es)14 b Fe(.)6 +b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)23 b Ff(6)1012 2574 y(matc)o(h-hidden-\014l)q(es)14 +b Fe(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)24 b Ff(6)1012 +2622 y Fd(menu-comple)o(te)9 b(\(\))g Fe(.)e(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)23 b Ff(16)1012 2670 y(meta-\015ag)t Fe(.)8 b(.)e(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)18 +b Ff(6)p eop +%%Page: 60 62 +60 61 bop 75 -58 a Fu(60)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fs(N)75 210 y Fd(next-histo)o(ry)9 b(\(C-n\))g +Fe(.)t(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)21 b Ff(13)75 256 y Fd(non-increm)o(en)o +(tal)o(-f)o(orw)o(ard)o(-s)o(ear)o(ch)o(-hi)o(st)o(ory)9 +b(\(M-n\))159 302 y Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)20 b Ff(13)75 +347 y Fd(non-increm)o(en)o(tal)o(-r)o(eve)o(rse)o(-s)o(ear)o(ch)o(-hi)o +(st)o(ory)9 b(\(M-p\))159 393 y Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)20 +b Ff(13)75 515 y Fs(O)75 576 y Ff(output-meta)5 b Fe(.)i(.)f(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)18 b Ff(6)75 +622 y Fd(overwrite-)o(mo)o(de)9 b(\(\))g Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)22 b Ff(15)75 744 y Fs(P)75 805 y Ff(page-completions)14 +b Fe(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)23 +b Ff(7)75 851 y Fd(possible-c)o(om)o(ple)o(ti)o(ons)9 +b(\(M-?\))h Fe(.)c(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)25 b Ff(16)75 897 y Fd(prefix-met)o(a)10 b(\()324 +895 y Fn(h)p 335 868 70 2 v 335 897 a Fm(ESC)p 335 904 +V 402 895 a Fn(i)417 897 y Fd(\))g Fe(.)c(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)23 +b Ff(17)75 942 y Fd(previous-h)o(is)o(tor)o(y)10 b(\(C-p\))c +Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)18 b Ff(12)75 1072 y Fs(Q)75 1133 y Fd(quoted-ins)o(er)o +(t)10 b(\(C-q)h(or)h(C-v\))c Fe(.)e(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)22 b Ff(14)75 1263 y Fs(R)75 +1323 y Fd(re-read-in)o(it)o(-fi)o(le)9 b(\(C-x)i(C-r\))5 +b Fe(.)h(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)18 +b Ff(17)75 1369 y Fd(readline)s Fe(.)s(.)7 b(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)16 b Ff(21)75 +1415 y Fd(redraw-cur)o(re)o(nt-)o(li)o(ne)9 b(\(\))d +Fe(.)g(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)18 b Ff(12)75 1461 y Fd(reverse-se)o(ar)o(ch-)o(hi)o +(sto)o(ry)9 b(\(C-r\))g Fe(.)d(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)23 b Ff(13)75 1506 y Fd(revert-lin)o(e)10 +b(\(M-r\))d Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)22 b Ff(17)75 +1552 y Fd(rl_add_def)o(un)6 b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)22 b Ff(28)75 1598 y Fd(rl_add_fun)o(ma)o(p_e)o(nt)o(ry) +t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(31)75 1643 y Fd(rl_add_und)o(o)7 +b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 +b Ff(32)75 1689 y Fd(rl_alphabe)o(ti)o(c)9 b Fe(.)s(.)d(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)22 b Ff(36)75 1735 y Fd(rl_already)o(_p)o(rom)o +(pt)o(ed)t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(25)75 +1781 y Fd(rl_attempt)o(ed)o(_co)o(mp)o(let)o(ion)o(_f)o(unc)o(ti)o(on)t +Fe(.)s(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)17 b Ff(43)75 +1826 y Fd(rl_attempt)o(ed)o(_co)o(mp)o(let)o(ion)o(_o)o(ver)6 +b Fe(.)s(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)20 +b Ff(46)75 1872 y Fd(rl_basic_q)o(uo)o(te_)o(ch)o(ara)o(cte)o(rs)8 +b Fe(.)t(.)e(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +22 b Ff(45)75 1918 y Fd(rl_basic_w)o(or)o(d_b)o(re)o(ak_)o(cha)o(ra)o +(cte)o(rs)5 b Fe(.)s(.)h(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)18 +b Ff(45)75 1964 y Fd(rl_begin_u)o(nd)o(o_g)o(ro)o(up)t +Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(32)75 2009 y Fd(rl_bind_ke)o(y)7 +b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 +b Ff(30)75 2055 y Fd(rl_bind_ke)o(y_)o(in_)o(ma)o(p)5 +b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)18 b Ff(30)75 2101 y +Fd(rl_binding)o(_k)o(eym)o(ap)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)19 +b Ff(27)75 2146 y Fd(rl_callbac)o(k_)o(han)o(dl)o(er_)o(ins)o(ta)o(ll)7 +b Fe(.)s(.)g(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)20 +b Ff(38)75 2192 y Fd(rl_callbac)o(k_)o(han)o(dl)o(er_)o(rem)o(ov)o(e)8 +b Fe(.)t(.)e(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)21 +b Ff(38)75 2238 y Fd(rl_callbac)o(k_)o(rea)o(d_)o(cha)o(r)9 +b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)25 b Ff(38)75 2284 y Fd(rl_catch_s)o(ig)o(nal)o(s)6 +b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)19 b Ff(40)75 +2329 y Fd(rl_catch_s)o(ig)o(win)o(ch)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)19 b Ff(40)75 2375 y Fd(rl_char_is)o(_q)o(uot)o(ed)o(_p)t +Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(44)75 2421 y Fd(rl_cleanup)o(_a)o +(fte)o(r_)o(sig)o(nal)7 b Fe(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)23 b Ff(40)75 2467 y +Fd(rl_clear_m)o(es)o(sag)o(e)6 b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +19 b Ff(33)75 2512 y Fd(rl_clear_p)o(en)o(din)o(g_)o(inp)o(ut)8 +b Fe(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)24 b Ff(35)1012 149 y Fd(rl_clear_si)o(gn)o(als)6 +b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)20 b Ff(41)1012 +196 y Fd(rl_complete)6 b Fe(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)24 b Ff(42)1012 242 y Fd(rl_complete)o(_i)o(nte)o(rn)o(al)s +Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)17 b Ff(42)1012 288 y Fd(rl_complete)o(r_)o +(quo)o(te)o(_ch)o(ar)o(act)o(ers)5 b Fe(.)t(.)h(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)20 b Ff(45)1012 335 y Fd(rl_complete)o(r_)o(wor)o +(d_)o(bre)o(ak)o(_ch)o(ara)o(ct)o(ers)8 b Fe(.)e(.)g(.)g(.)h(.)f(.)g(.) +25 b Ff(45)1012 381 y Fd(rl_completi)o(on)o(_ap)o(pe)o(nd_)o(ch)o(ara)o +(cte)o(r)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)19 +b Ff(45)1012 427 y Fd(rl_completi)o(on)o(_di)o(sp)o(lay)o(_m)o(atc)o +(hes)o(_h)o(ook)8 b Fe(.)e(.)g(.)g(.)h(.)f(.)g(.)25 b +Ff(45)1012 474 y Fd(rl_completi)o(on)o(_en)o(tr)o(y_f)o(un)o(cti)o(on)s +Fe(.)s(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)17 b Ff(42,)c(43)1012 +520 y Fd(rl_completi)o(on)o(_ma)o(rk)o(_sy)o(ml)o(ink)o(_di)o(rs)t +Fe(.)s(.)7 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)18 b Ff(46)1012 +566 y Fd(rl_completi)o(on)o(_ma)o(tc)o(hes)8 b Fe(.)f(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)25 +b Ff(43)1012 613 y Fd(rl_completi)o(on)o(_mo)o(de)t Fe(.)t(.)6 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(43)1012 659 y Fd(rl_completi)o(on)o(_qu) +o(er)o(y_i)o(te)o(ms)9 b Fe(.)s(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)23 b Ff(45)1012 705 y Fd(rl_completi)o(on)o(_su) +o(pp)o(res)o(s_)o(app)o(end)5 b Fe(.)t(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)20 b Ff(46)1012 752 y Fd(rl_completi)o(on)o(_ty)o(pe)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(46)1012 798 y +Fd(rl_copy_key)o(ma)o(p)8 b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)21 b Ff(29)1012 844 y Fd(rl_copy_tex)o(t)6 b Fe(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 b Ff(34)1012 891 y +Fd(rl_crlf)t Fe(.)t(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)17 b Ff(33)1012 937 y Fd(rl_delete_t)o(ex)o(t)8 +b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)21 b +Ff(34)1012 983 y Fd(rl_deprep_t)o(er)o(m_f)o(un)o(cti)o(on)7 +b Fe(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)24 b Ff(26)1012 1030 y Fd(rl_deprep_t)o(er)o(min)o(al)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(35)1012 1076 +y Fd(rl_ding)t Fe(.)t(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)17 b Ff(36)1012 1122 y Fd(rl_director)o(y_)o +(com)o(pl)o(eti)o(on)o(_ho)o(ok)7 b Fe(.)s(.)f(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)20 b Ff(44)1012 1169 y Fd(rl_discard_)o(ke)o +(yma)o(p)6 b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)19 b Ff(29)1012 +1215 y Fd(rl_dispatch)o(in)o(g)8 b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)21 b Ff(25)1012 1261 y Fd(rl_display_)o(ma)o(tch)o(_l)o +(ist)8 b Fe(.)f(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)25 b Ff(36)1012 1308 y Fd(rl_do_undo)8 +b Fe(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)24 +b Ff(32)1012 1354 y Fd(rl_done)t Fe(.)t(.)6 b(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)17 b Ff(24)1012 +1400 y Fd(rl_editing_)o(mo)o(de)7 b Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)21 b Ff(28)1012 1447 y Fd(rl_end)5 b Fe(.)t(.)h(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)18 +b Ff(24)1012 1493 y Fd(rl_end_undo)o(_g)o(rou)o(p)6 b +Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)19 b Ff(32)1012 1539 +y Fd(rl_erase_em)o(pt)o(y_l)o(in)o(e)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)18 +b Ff(25)1012 1586 y Fd(rl_event_ho)o(ok)8 b Fe(.)s(.)e(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)22 b Ff(26)1012 1632 y Fd(rl_execute_)o(ne)o +(xt)7 b Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 +b Ff(35)1012 1678 y Fd(rl_executin)o(g_)o(key)o(ma)o(p)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)18 b Ff(26)1012 1725 y Fd(rl_executin)o(g_) +o(mac)o(ro)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(27)1012 +1771 y Fd(rl_expand_p)o(ro)o(mpt)6 b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)20 b Ff(34)1012 1817 y Fd(rl_explicit)o(_a)o(rg)7 +b Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 b Ff(28)1012 +1864 y Fd(rl_extend_l)o(in)o(e_b)o(uf)o(fer)8 b Fe(.)f(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)25 +b Ff(36)1012 1910 y Fd(rl_filename)o(_c)o(omp)o(le)o(tio)o(n_)o(des)o +(ire)o(d)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)19 +b Ff(46)1012 1956 y Fd(rl_filename)o(_c)o(omp)o(le)o(tio)o(n_)o(fun)o +(cti)o(on)t Fe(.)s(.)7 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)18 +b Ff(43)1012 2003 y Fd(rl_filename)o(_d)o(equ)o(ot)o(ing)o(_f)o(unc)o +(tio)o(n)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)19 +b Ff(44)1012 2049 y Fd(rl_filename)o(_q)o(uot)o(e_)o(cha)o(ra)o(cte)o +(rs)7 b Fe(.)s(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)20 +b Ff(45)1012 2095 y Fd(rl_filename)o(_q)o(uot)o(in)o(g_d)o(es)o(ire)o +(d)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)21 +b Ff(46)1012 2142 y Fd(rl_filename)o(_q)o(uot)o(in)o(g_f)o(un)o(cti)o +(on)7 b Fe(.)s(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)20 +b Ff(44)1012 2188 y Fd(rl_forced_u)o(pd)o(ate)o(_d)o(isp)o(la)o(y)7 +b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)23 b Ff(33)1012 2234 y Fd(rl_free_lin)o(e_)o(sta)o(te)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(40)1012 2281 +y Fd(rl_free_und)o(o_)o(lis)o(t)6 b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +19 b Ff(32)1012 2327 y Fd(rl_function)o(_d)o(ump)o(er)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(31)1012 2373 +y Fd(rl_function)o(_o)o(f_k)o(ey)o(seq)8 b Fe(.)f(.)f(.)g(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)25 +b Ff(31)1012 2420 y Fd(rl_funmap_n)o(am)o(es)7 b Fe(.)s(.)f(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)21 b Ff(31)1012 2466 y Fd(rl_generic_)o(bi)o(nd)7 +b Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 b Ff(30)1012 +2512 y Fd(rl_get_keym)o(ap)8 b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)22 b Ff(29)p eop +%%Page: 61 63 +61 62 bop 75 -58 a Fu(F)l(unction)16 b(and)f(V)l(ariable)i(Index)1187 +b(61)75 149 y Fd(rl_get_key)o(ma)o(p_b)o(y_)o(nam)o(e)9 +b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)25 b Ff(29)75 196 y Fd(rl_get_key)o(ma)o(p_n)o(am)o(e)5 +b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)18 b Ff(29)75 242 y Fd(rl_get_scr)o(ee) +o(n_s)o(iz)o(e)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)18 +b Ff(41)75 288 y Fd(rl_get_ter)o(mc)o(ap)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)21 b Ff(37)75 335 y Fd(rl_getc)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)17 b Ff(35)75 381 y Fd(rl_getc_fu)o(nc)o(tio)o(n)6 +b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)19 b Ff(26)75 +427 y Fd(rl_gnu_rea)o(dl)o(ine)o(_p)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)19 b Ff(25)75 474 y Fd(rl_ignore_)o(co)o(mpl)o(et)o(ion)o(_du)o(pl) +o(ica)o(te)o(s)5 b Fe(.)s(.)h(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)18 +b Ff(46)75 520 y Fd(rl_ignore_)o(so)o(me_)o(co)o(mpl)o(eti)o(on)o(s_f)o +(un)o(cti)o(on)7 b Fe(.)g(.)f(.)g(.)g(.)g(.)24 b Ff(44)75 +566 y Fd(rl_inhibit)o(_c)o(omp)o(le)o(tio)o(n)9 b Fe(.)d(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 +b Ff(47)75 613 y Fd(rl_initial)o(iz)o(e)9 b Fe(.)s(.)d(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)22 b Ff(36)75 659 y Fd(rl_insert_)o(co)o(mpl)o +(et)o(ion)o(s)9 b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 b Ff(43)75 705 y Fd(rl_insert_)o(te) +o(xt)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 +b Ff(34)75 752 y Fd(rl_instrea)o(m)7 b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 b Ff(25)75 798 y Fd(rl_invokin)o(g_)o +(key)o(se)o(qs)t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(31)75 +844 y Fd(rl_invokin)o(g_)o(key)o(se)o(qs_)o(in_)o(ma)o(p)8 +b Fe(.)t(.)e(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)21 +b Ff(31)75 891 y Fd(rl_kill_te)o(xt)6 b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)22 b Ff(34)75 937 y Fd(rl_last_fu)o(nc)6 +b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)22 +b Ff(26)75 983 y Fd(rl_library)o(_v)o(ers)o(io)o(n)5 +b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)18 b Ff(25)75 1030 y +Fd(rl_line_bu)o(ff)o(er)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)21 b Ff(24)75 1076 y Fd(rl_list_fu)o(nm)o(ap_)o(na)o(mes)s +Fe(.)s(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)16 b Ff(31)75 1122 y Fd(rl_macro_b)o(in)o(d)9 +b Fe(.)s(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)22 +b Ff(37)75 1169 y Fd(rl_macro_d)o(um)o(per)6 b Fe(.)t(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)20 b Ff(37)75 1215 y Fd(rl_make_ba)o(re)o(_ke)o(ym) +o(ap)t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(29)75 1261 +y Fd(rl_make_ke)o(ym)o(ap)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)21 b Ff(29)75 1308 y Fd(rl_mark)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)17 +b Ff(24)75 1354 y Fd(rl_message)7 b Fe(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)24 b Ff(33)75 1400 y Fd(rl_modifyi)o(ng)6 +b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)22 +b Ff(32)75 1447 y Fd(rl_named_f)o(un)o(cti)o(on)5 b Fe(.)s(.)i(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)19 b Ff(31)75 1493 y Fd(rl_num_cha)o(rs)o(_to)o(_r)o +(ead)s Fe(.)s(.)6 b(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)16 b Ff(24)75 1539 y Fd(rl_numeric)o(_a) +o(rg)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)21 +b Ff(28)75 1586 y Fd(rl_on_new_)o(li)o(ne)8 b Fe(.)s(.)e(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)21 b Ff(33)75 1632 y Fd(rl_on_new_)o(li)o(ne_)o +(wi)o(th_)o(pro)o(mp)o(t)8 b Fe(.)t(.)e(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)21 b Ff(33)75 1678 y Fd(rl_outstre)o(am)6 +b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)22 +b Ff(26)75 1725 y Fd(rl_parse_a)o(nd)o(_bi)o(nd)5 b Fe(.)s(.)i(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)19 b Ff(31)75 1771 y Fd(rl_pending)o(_i)o(npu)o(t)6 +b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)19 b Ff(24)75 +1817 y Fd(rl_point)s Fe(.)s(.)7 b(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)16 b Ff(24)75 1864 y Fd(rl_possibl)o(e_)o +(com)o(pl)o(eti)o(ons)7 b Fe(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)23 b Ff(42)75 1910 y +Fd(rl_pre_inp)o(ut)o(_ho)o(ok)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)19 +b Ff(26)75 1956 y Fd(rl_prep_te)o(rm)o(_fu)o(nc)o(tio)o(n)9 +b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)25 b Ff(26)75 2003 y Fd(rl_prep_te)o(rm)o(ina)o(l)6 +b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)19 b Ff(35)75 +2049 y Fd(rl_prompt)8 b Fe(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)24 b Ff(25)75 2095 y Fd(rl_push_ma)o(cr)o(o_i)o(np) +o(ut)t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 b Ff(34)75 2142 +y Fd(rl_read_in)o(it)o(_fi)o(le)5 b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +19 b Ff(31)75 2188 y Fd(rl_read_ke)o(y)7 b Fe(.)f(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 b Ff(34)75 2234 y +Fd(rl_readlin)o(e_)o(nam)o(e)6 b Fe(.)t(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +19 b Ff(25)75 2281 y Fd(rl_readlin)o(e_)o(sta)o(te)5 +b Fe(.)s(.)i(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)19 b Ff(27)75 2327 +y Fd(rl_readlin)o(e_)o(ver)o(si)o(on)t Fe(.)s(.)6 b(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)17 +b Ff(25)75 2373 y Fd(rl_redispl)o(ay)6 b Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)22 b Ff(33)75 2420 y Fd(rl_redispl)o(ay)o(_fu)o +(nc)o(tio)o(n)9 b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 b Ff(26)75 2466 y +Fd(rl_replace)o(_l)o(ine)6 b Fe(.)t(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +20 b Ff(36)75 2512 y Fd(rl_reset_a)o(ft)o(er_)o(si)o(gna)o(l)9 +b Fe(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)25 b Ff(40)1012 149 y Fd(rl_reset_li)o(ne)o(_st)o(at)o +(e)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)18 b Ff(33)1012 195 +y Fd(rl_reset_te)o(rm)o(ina)o(l)6 b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +19 b Ff(35)1012 241 y Fd(rl_resize_t)o(er)o(min)o(al)t +Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(41)1012 287 y +Fd(rl_restore_)o(pr)o(omp)o(t)6 b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)19 +b Ff(34)1012 333 y Fd(rl_save_pro)o(mp)o(t)8 b Fe(.)s(.)e(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)21 b Ff(33)1012 379 y Fd(rl_set_key)8 +b Fe(.)e(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)24 +b Ff(30)1012 424 y Fd(rl_set_keyb)o(oa)o(rd_)o(in)o(put)o(_t)o(ime)o +(out)5 b Fe(.)t(.)h(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)20 +b Ff(35)1012 470 y Fd(rl_set_keym)o(ap)8 b Fe(.)s(.)e(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)22 b Ff(29)1012 516 y Fd(rl_set_pare)o(n_)o +(bli)o(nk)o(_ti)o(me)o(out)7 b Fe(.)t(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)22 b Ff(37)1012 562 y Fd(rl_set_prom)o(pt)8 +b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)22 +b Ff(34)1012 608 y Fd(rl_set_scre)o(en)o(_si)o(ze)t Fe(.)t(.)6 +b(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)19 b Ff(41)1012 654 y Fd(rl_set_sign)o(al)o(s)8 +b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)21 b +Ff(41)1012 700 y Fd(rl_show_cha)o(r)6 b Fe(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)23 b Ff(33)1012 745 y Fd(rl_special_)o(pr)o +(efi)o(xe)o(s)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)18 b Ff(45)1012 +791 y Fd(rl_startup_)o(ho)o(ok)7 b Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)21 b Ff(26)1012 837 y Fd(rl_stuff_ch)o(ar)8 b +Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)22 +b Ff(35)1012 883 y Fd(rl_terminal)o(_n)o(ame)6 b Fe(.)s(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)20 b Ff(25)1012 929 y Fd(rl_tty_set_)o(de)o(fau)o(lt)o +(_bi)o(nd)o(ing)o(s)8 b Fe(.)s(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)21 b Ff(35)1012 975 y Fd(rl_unbind_c)o(om)o(man)o(d_)o +(in_)o(ma)o(p)7 b Fe(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)23 b Ff(30)1012 1020 y Fd(rl_unbind_f)o(un)o(cti)o +(on)o(_in)o(_m)o(ap)9 b Fe(.)s(.)d(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)g(.)23 b Ff(30)1012 1066 y Fd(rl_unbind_k)o(ey)8 +b Fe(.)s(.)e(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)22 +b Ff(30)1012 1112 y Fd(rl_unbind_k)o(ey)o(_in)o(_m)o(ap)s +Fe(.)t(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.) +g(.)g(.)g(.)h(.)f(.)g(.)17 b Ff(30)1012 1158 y Fd(rl_username)o(_c)o +(omp)o(le)o(tio)o(n_)o(fun)o(cti)o(on)t Fe(.)s(.)7 b(.)f(.)g(.)g(.)g(.) +g(.)h(.)f(.)g(.)18 b Ff(43)1012 1204 y Fd(rl_variable)o(_b)o(ind)6 +b Fe(.)s(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)20 b Ff(37)1012 +1250 y Fd(rl_variable)o(_d)o(ump)o(er)t Fe(.)t(.)6 b(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g +(.)19 b Ff(37)1012 1380 y Fs(S)1012 1441 y Fd(self-insert)9 +b(\(a,)j(b,)g(A,)g(1,)g(!,)g(...)o(\))6 b Fe(.)g(.)g(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)20 b Ff(14)1012 1487 y Fd(set-mark)10 +b(\(C-@\))g Fe(.)c(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 +b Ff(17)1012 1533 y(sho)o(w-all-if-am)o(bigu)q(ous)14 +b Fe(.)6 b(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)23 b Ff(7)1012 1579 +y Fd(start-kbd-m)o(ac)o(ro)9 b(\(C-x)j(\(\))c Fe(.)d(.)i(.)f(.)g(.)g(.) +g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)22 +b Ff(17)1012 1701 y Fs(T)1012 1763 y Fd(tab-insert)9 +b(\(M-)1281 1761 y Fn(h)p 1292 1735 74 2 v 1292 1763 +a Fm(T)m(AB)p 1292 1770 V 1364 1761 a Fn(i)1379 1763 +y Fd(\))e Fe(.)f(.)g(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.) +f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)20 b Ff(14)1012 1808 +y Fd(tilde-expan)o(d)10 b(\(M-~\))f Fe(.)s(.)e(.)f(.)g(.)g(.)g(.)g(.)g +(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)22 +b Ff(17)1012 1854 y Fd(transpose-c)o(ha)o(rs)9 b(\(C-t\))d +Fe(.)f(.)h(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)20 b Ff(14)1012 1900 y Fd(transpose-w)o(or)o(ds)9 +b(\(M-t\))d Fe(.)f(.)h(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)20 b Ff(14)1012 2030 y +Fs(U)1012 2092 y Fd(undo)12 b(\(C-_)f(or)h(C-x)g(C-u\))c +Fe(.)t(.)e(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)21 b Ff(17)1012 2137 y Fd(universal-a)o(rg)o +(ume)o(nt)9 b(\(\))d Fe(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)20 b Ff(16)1012 +2183 y Fd(unix-line-d)o(is)o(car)o(d)10 b(\(C-u\))5 b +Fe(.)t(.)h(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)18 b Ff(15)1012 2229 y Fd(unix-word-r)o(ub)o(out)9 +b(\(C-w\))d Fe(.)t(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)19 b Ff(15)1012 2275 y Fd(upcase-word)9 +b(\(M-u\))e Fe(.)f(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)23 b Ff(14)1012 +2405 y Fs(V)1012 2466 y Fd(vi-editing-)o(mo)o(de)9 b(\(M-C-j\))c +Fe(.)t(.)h(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g +(.)h(.)f(.)18 b Ff(18)1012 2512 y(visible-stats)c Fe(.)6 +b(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)24 +b Ff(7)p eop +%%Page: 62 64 +62 63 bop 75 -58 a Fu(62)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fs(Y)75 242 y Fd(yank)11 b(\(C-y\))5 b Fe(.)g(.)h(.)g(.)g(.)g(.)h +(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.) +h(.)f(.)g(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)18 b Ff(16)1012 +149 y Fd(yank-last-a)o(rg)9 b(\(M-.)i(or)h(M-_\))c Fe(.)f(.)f(.)g(.)g +(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)23 +b Ff(13)1012 196 y Fd(yank-nth-ar)o(g)10 b(\(M-C-y\))d +Fe(.)s(.)f(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f +(.)g(.)g(.)g(.)g(.)h(.)20 b Ff(13)1012 242 y Fd(yank-pop)10 +b(\(M-y\))g Fe(.)c(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g +(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)25 +b Ff(16)p eop +%%Page: -1 65 +-1 64 bop 1862 -58 a Fu(i)75 149 y Fq(T)-7 b(able)27 +b(of)f(Con)n(ten)n(ts)75 320 y Fs(1)67 b(Command)22 b(Line)i(Editing)d +Fa(.)10 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)g(.)42 b Fs(1)224 389 y Fu(1.1)j(In)o(tro)q(duction)16 +b(to)f(Line)h(Editing)e Fl(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)27 b Fu(1)224 444 y(1.2)45 b(Readline)16 b(In)o(teraction)8 +b Fl(.)g(.)g(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)23 b Fu(1)374 499 y(1.2.1)44 b(Readline)16 +b(Bare)f(Essen)o(tials)f Fl(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)27 +b Fu(1)374 553 y(1.2.2)44 b(Readline)16 b(Mo)o(v)o(emen)o(t)e(Commands) +7 b Fl(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)21 b Fu(2)374 608 y(1.2.3)44 b(Readline)16 b(Killing)i(Commands) +11 b Fl(.)c(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)25 b Fu(2)374 663 y(1.2.4)44 b(Readline)16 +b(Argumen)o(ts)c Fl(.)c(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)27 +b Fu(3)374 718 y(1.2.5)44 b(Searc)o(hing)16 b(for)e(Commands)h(in)h +(the)f(History)e Fl(.)8 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)27 +b Fu(3)224 773 y(1.3)45 b(Readline)16 b(Init)h(File)e +Fl(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)29 b Fu(4)374 827 y(1.3.1)44 b(Readline)16 +b(Init)g(File)h(Syn)o(tax)7 b Fl(.)g(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)21 +b Fu(4)374 882 y(1.3.2)44 b(Conditional)16 b(Init)g(Constructs)5 +b Fl(.)i(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)g(.)f(.)19 b Fu(9)374 937 y(1.3.3)44 b(Sample)16 +b(Init)g(File)11 b Fl(.)e(.)e(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)26 b Fu(9)224 992 y(1.4)45 b(Bindable)17 b(Readline)g(Commands) +6 b Fl(.)h(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)21 b Fu(12)374 +1046 y(1.4.1)44 b(Commands)14 b(F)l(or)h(Mo)o(ving)e +Fl(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)28 b Fu(12)374 1101 y(1.4.2)44 +b(Commands)14 b(F)l(or)h(Manipulating)i(The)e(History)9 +b Fl(.)e(.)h(.)f(.)h(.)f(.)h(.)24 b Fu(12)374 1156 y(1.4.3)44 +b(Commands)14 b(F)l(or)h(Changing)h(T)l(ext)e Fl(.)8 +b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)30 +b Fu(14)374 1211 y(1.4.4)44 b(Killing)18 b(And)e(Y)l(anking)9 +b Fl(.)e(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)24 b Fu(15)374 +1266 y(1.4.5)44 b(Sp)q(ecifying)17 b(Numeric)f(Argumen)o(ts)c +Fl(.)c(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)27 +b Fu(16)374 1320 y(1.4.6)44 b(Letting)15 b(Readline)i(T)o(yp)q(e)e(F)l +(or)g(Y)l(ou)10 b Fl(.)d(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)25 b Fu(16)374 1375 y(1.4.7)44 b(Keyb)q(oard)15 +b(Macros)6 b Fl(.)h(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)21 +b Fu(17)374 1430 y(1.4.8)44 b(Some)15 b(Miscellaneous)i(Commands)7 +b Fl(.)g(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +22 b Fu(17)224 1485 y(1.5)45 b(Readline)16 b(vi)g(Mo)q(de)e +Fl(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)28 b Fu(18)75 1606 y Fs(2)67 b(Programming)23 +b(with)g(GNU)f(Readline)12 b Fa(.)f(.)g(.)f(.)g(.)g(.)g(.)h(.)f(.)35 +b Fs(21)224 1675 y Fu(2.1)45 b(Basic)16 b(Beha)o(vior)8 +b Fl(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)23 b Fu(21)224 1729 y(2.2)45 +b(Custom)14 b(F)l(unctions)7 b Fl(.)i(.)f(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)22 b Fu(22)374 +1784 y(2.2.1)44 b(Readline)16 b(T)o(yp)q(edefs)9 b Fl(.)g(.)e(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)g(.)f(.)h(.)24 b Fu(23)374 1839 y(2.2.2)44 +b(W)l(riting)16 b(a)e(New)i(F)l(unction)6 b Fl(.)i(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +21 b Fu(23)224 1894 y(2.3)45 b(Readline)16 b(V)l(ariables)g +Fl(.)8 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g +(.)f(.)h(.)29 b Fu(24)224 1949 y(2.4)45 b(Readline)16 +b(Con)o(v)o(enience)h(F)l(unctions)7 b Fl(.)i(.)e(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +23 b Fu(28)374 2003 y(2.4.1)44 b(Naming)15 b(a)g(F)l(unction)e +Fl(.)7 b(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)27 b Fu(28)374 +2058 y(2.4.2)44 b(Selecting)17 b(a)e(Keymap)6 b Fl(.)h(.)h(.)g(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)21 b Fu(29)374 2113 y(2.4.3)44 b(Binding)17 +b(Keys)5 b Fl(.)j(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.) +h(.)f(.)20 b Fu(30)374 2168 y(2.4.4)44 b(Asso)q(ciating)16 +b(F)l(unction)g(Names)f(and)g(Bindings)8 b Fl(.)h(.)f(.)f(.)h(.)f(.)h +(.)23 b Fu(31)374 2222 y(2.4.5)44 b(Allo)o(wing)16 b(Undoing)f +Fl(.)8 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)29 b +Fu(32)374 2277 y(2.4.6)44 b(Redispla)o(y)10 b Fl(.)e(.)g(.)g(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)26 +b Fu(33)374 2332 y(2.4.7)44 b(Mo)q(difying)16 b(T)l(ext)7 +b Fl(.)g(.)g(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)22 +b Fu(34)374 2387 y(2.4.8)44 b(Character)14 b(Input)c +Fl(.)f(.)e(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)25 +b Fu(34)374 2442 y(2.4.9)44 b(T)l(erminal)16 b(Managemen)o(t)11 +b Fl(.)c(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)27 b Fu(35)374 2496 y(2.4.10)43 +b(Utilit)o(y)17 b(F)l(unctions)c Fl(.)7 b(.)h(.)g(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)28 b Fu(36)374 2551 y(2.4.11)43 b(Miscellaneous)18 +b(F)l(unctions)6 b Fl(.)i(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)21 b Fu(37)374 +2606 y(2.4.12)43 b(Alternate)16 b(In)o(terface)f Fl(.)7 +b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)30 b Fu(37)374 2661 +y(2.4.13)43 b(A)16 b(Readline)g(Example)9 b Fl(.)f(.)f(.)h(.)f(.)h(.)g +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)24 b Fu(38)p eop +%%Page: -2 66 +-2 65 bop 75 -58 a Fu(ii)1321 b(GNU)15 b(Readline)h(Library)224 +42 y(2.5)45 b(Readline)16 b(Signal)h(Handling)12 b Fl(.)c(.)g(.)f(.)h +(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)27 b Fu(39)224 96 +y(2.6)45 b(Custom)14 b(Completers)f Fl(.)8 b(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)28 b Fu(41)374 +151 y(2.6.1)44 b(Ho)o(w)14 b(Completing)i(W)l(orks)10 +b Fl(.)d(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)25 b Fu(41)374 206 y(2.6.2)44 +b(Completion)16 b(F)l(unctions)6 b Fl(.)i(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +21 b Fu(42)374 261 y(2.6.3)44 b(Completion)16 b(V)l(ariables)c +Fl(.)c(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)27 b Fu(43)374 315 +y(2.6.4)44 b(A)15 b(Short)g(Completion)h(Example)5 b +Fl(.)j(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)20 b Fu(47)75 437 y Fs(Concept)i(Index)10 b Fa(.)i(.)e(.)g(.)g +(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.) +g(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)33 b Fs(57)75 572 +y(F)-6 b(unction)25 b(and)d(V)-6 b(ariable)24 b(Index)9 +b Fa(.)i(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.) +g(.)32 b Fs(59)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/readline-doc-4.3/doc/readline_3.ps b/readline-doc-4.3/doc/readline_3.ps new file mode 100644 index 0000000..7d20e17 --- /dev/null +++ b/readline-doc-4.3/doc/readline_3.ps @@ -0,0 +1,1294 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.17.2 +%%CreationDate: Thu Jun 27 13:54:44 2002 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Bold +%%+ font Times-Italic +%%+ font Courier +%%DocumentSuppliedResources: procset grops 1.17 2 +%%Pages: 14 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.17 2 +/setpacking where{ +pop +currentpacking +true setpacking +}if +/grops 120 dict dup begin +/SC 32 def +/A/show load def +/B{0 SC 3 -1 roll widthshow}bind def +/C{0 exch ashow}bind def +/D{0 exch 0 SC 5 2 roll awidthshow}bind def +/E{0 rmoveto show}bind def +/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def +/G{0 rmoveto 0 exch ashow}bind def +/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/I{0 exch rmoveto show}bind def +/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def +/K{0 exch rmoveto 0 exch ashow}bind def +/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/M{rmoveto show}bind def +/N{rmoveto 0 SC 3 -1 roll widthshow}bind def +/O{rmoveto 0 exch ashow}bind def +/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/Q{moveto show}bind def +/R{moveto 0 SC 3 -1 roll widthshow}bind def +/S{moveto 0 exch ashow}bind def +/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def +/SF{ +findfont exch +[exch dup 0 exch 0 exch neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/MF{ +findfont +[5 2 roll +0 3 1 roll +neg 0 0]makefont +dup setfont +[exch/setfont cvx]cvx bind def +}bind def +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def +/MANUAL{ +statusdict begin/manualfeed true store end +}bind def +/PLG{ +gsave newpath clippath pathbbox grestore +exch pop add exch pop +}bind def +/BP{ +/level0 save def +1 setlinecap +1 setlinejoin +72 RES div dup scale +LS{ +90 rotate +}{ +0 PL translate +}ifelse +1 -1 scale +}bind def +/EP{ +level0 restore +showpage +}bind def +/DA{ +newpath arcn stroke +}bind def +/SN{ +transform +.25 sub exch .25 sub exch +round .25 add exch round .25 add exch +itransform +}bind def +/DL{ +SN +moveto +SN +lineto stroke +}bind def +/DC{ +newpath 0 360 arc closepath +}bind def +/TM matrix def +/DE{ +TM currentmatrix pop +translate scale newpath 0 0 .5 0 360 arc closepath +TM setmatrix +}bind def +/RC/rcurveto load def +/RL/rlineto load def +/ST/stroke load def +/MT/moveto load def +/CL/closepath load def +/FL{ +currentgray exch setgray fill setgray +}bind def +/BL/fill load def +/LW/setlinewidth load def +/RE{ +findfont +dup maxlength 1 index/FontName known not{1 add}if dict begin +{ +1 index/FID ne{def}{pop pop}ifelse +}forall +/Encoding exch def +dup/FontName exch def +currentdict end definefont pop +}bind def +/DEFS 0 def +/EBEGIN{ +moveto +DEFS begin +}bind def +/EEND/end load def +/CNT 0 def +/level1 0 def +/PBEGIN{ +/level1 save def +translate +div 3 1 roll div exch scale +neg exch neg exch translate +0 setgray +0 setlinecap +1 setlinewidth +0 setlinejoin +10 setmiterlimit +[]0 setdash +/setstrokeadjust where{ +pop +false setstrokeadjust +}if +/setoverprint where{ +pop +false setoverprint +}if +newpath +/CNT countdictstack def +userdict begin +/showpage{}def +}bind def +/PEND{ +clear +countdictstack CNT sub{end}repeat +level1 restore +}bind def +end def +/setpacking where{ +pop +setpacking +}if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Bold +%%IncludeResource: font Times-Italic +%%IncludeResource: font Courier +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 +def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron +/scaron/zcaron/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent +/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen +/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon +/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O +/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex +/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y +/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft +/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl +/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen +/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft +/logicalnot/minus/registered/macron/degree/plusminus/twosuperior +/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior +/ordmasculine/guilsinglright/onequarter/onehalf/threequarters +/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE +/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex +/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn +/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla +/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis +/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash +/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def +/Courier@0 ENC0/Courier RE/Times-Italic@0 ENC0/Times-Italic RE +/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 +10.95/Times-Bold@0 SF -.219(NA)72 84 S(ME).219 E F0 +(readline \255 get a line from a user with editing)108 96 Q F1(SYNOPSIS) +72 112.8 Q/F2 10/Times-Bold@0 SF(#include )108 124.8 Q +(#include )-.18 E(#include )-.7 E/F3 10/Times-Italic@0 SF +-.15(ch)108 165.6 S(ar *).15 E F2 -.18(re)108 177.6 S(adline).18 E F0 +(\()2.5 E F3(const c)A(har *pr)-.15 E(ompt)-.45 E F0(\);)A F1(COPYRIGHT) +72 194.4 Q F0(Readline is Cop)108 206.4 Q +(yright \251 1989\2552002 by the Free Softw)-.1 E(are F)-.1 E +(oundation, Inc.)-.15 E F1(DESCRIPTION)72 223.2 Q F2 -.18(re)108 235.2 S +(adline).18 E F0 .088 +(will read a line from the terminal and return it, using)2.588 F F2(pr) +2.587 E(ompt)-.18 E F0 .087(as a prompt.)2.587 F(If)5.087 E F2(pr)2.587 +E(ompt)-.18 E F0(is)2.587 E F2(NULL)2.587 E F0(or)2.587 E .42 +(the empty string, no prompt is issued.)108 247.2 R .421 +(The line returned is allocated with)5.42 F F3(malloc)2.921 E F0 .421 +(\(3\); the caller must free it).31 F(when \214nished.)108 259.2 Q +(The line returned has the \214nal ne)5 E(wline remo)-.25 E -.15(ve)-.15 +G(d, so only the te).15 E(xt of the line remains.)-.15 E F2 -.18(re)108 +276 S(adline).18 E F0(of)3.79 E 1.29 +(fers editing capabilities while the user is entering the line.)-.25 F +1.289(By def)6.289 F 1.289(ault, the line editing com-)-.1 F +(mands are similar to those of emacs.)108 288 Q 2.5(Av)5 G +(i\255style line editing interf)-2.5 E(ace is also a)-.1 E -.25(va)-.2 G +(ilable.).25 E .272 +(This manual page describes only the most basic use of)108 304.8 R F2 +-.18(re)2.772 G(adline).18 E F0 5.272(.M)C .272 +(uch more functionality is a)-5.272 F -.25(va)-.2 G .272(ilable; see).25 +F F3(The GNU Readline Libr)108 316.8 Q(ary)-.15 E F0(and)2.5 E F3 +(The GNU History Libr)2.5 E(ary)-.15 E F0(for additional information.) +2.5 E F1(RETURN V)72 333.6 Q(ALUE)-1.478 E F2 -.18(re)108 345.6 S +(adline).18 E F0 1.09(returns the te)3.59 F 1.09(xt of the line read.) +-.15 F 3.589(Ab)6.09 G 1.089(lank line returns the empty string.)-3.589 +F(If)6.089 E F2(EOF)3.589 E F0 1.089(is encountered)3.589 F .283 +(while reading a line, and the line is empty)108 357.6 R(,)-.65 E F2 +(NULL)2.783 E F0 .283(is returned.)2.783 F .283(If an)5.283 F F2(EOF) +2.783 E F0 .283(is read with a non\255empty line, it)2.783 F +(is treated as a ne)108 369.6 Q(wline.)-.25 E F1(NO)72 386.4 Q -.986(TA) +-.438 G(TION)-.054 E F0 .181 +(An emacs-style notation is used to denote k)108 398.4 R -.15(ey)-.1 G +(strok).15 E 2.681(es. Control)-.1 F -.1(ke)2.681 G .18 +(ys are denoted by C\255)-.05 F F3 -.1(ke)C(y)-.2 E F0 2.68(,e)C .18 +(.g., C\255n means)-2.68 F 2.625(Control\255N. Similarly)108 410.4 R(,) +-.65 E F3(meta)2.625 E F0 -.1(ke)2.625 G .125(ys are denoted by M\255) +-.05 F F3 -.1(ke)C(y)-.2 E F0 2.625(,s)C 2.625(oM)-2.625 G .125 +(\255x means Meta\255X.)-2.625 F .126(\(On k)5.126 F -.15(ey)-.1 G .126 +(boards without a).15 F F3(meta)108 422.4 Q F0 -.1(ke)3.309 G 2.109 -.65 +(y, M)-.05 H.65 E F3(x)A F0 .809(means ESC)3.309 F F3(x)3.309 E F0 +3.309(,i)C .809(.e., press the Escape k)-3.309 F 1.108 -.15(ey t)-.1 H +.808(hen the).15 F F3(x)3.308 E F0 -.1(ke)3.308 G 4.608 -.65(y. T)-.05 H +.808(his mak).65 F .808(es ESC the)-.1 F F3 .808(meta pr)3.308 F(e\214x) +-.37 E F0(.)A .48(The combination M\255C\255)108 434.4 R F3(x)A F0 .48 +(means ESC\255Control\255)2.98 F F3(x)A F0 2.98(,o)C 2.98(rp)-2.98 G .48 +(ress the Escape k)-2.98 F .78 -.15(ey t)-.1 H .48 +(hen hold the Control k).15 F .78 -.15(ey w)-.1 H(hile).15 E +(pressing the)108 446.4 Q F3(x)2.5 E F0 -.1(ke)2.5 G -.65(y.)-.05 G(\)) +.65 E .62(Readline commands may be gi)108 463.2 R -.15(ve)-.25 G 3.119 +(nn).15 G(umeric)-3.119 E F3(ar)3.119 E(guments)-.37 E F0 3.119(,w).27 G +.619(hich normally act as a repeat count.)-3.119 F(Sometimes,)5.619 E +(ho)108 475.2 Q(we)-.25 E -.15(ve)-.25 G 1.418 -.4(r, i).15 H 3.118(ti) +.4 G 3.119(st)-3.118 G .619(he sign of the ar)-3.119 F .619 +(gument that is signi\214cant.)-.18 F -.15(Pa)5.619 G .619(ssing a ne) +.15 F -.05(ga)-.15 G(ti).05 E .919 -.15(ve a)-.25 H -.18(rg).15 G .619 +(ument to a command that).18 F 1.019(acts in the forw)108 487.2 R 1.018 +(ard direction \(e.g.,)-.1 F F2(kill\255line)3.518 E F0 3.518(\)c)C +1.018(auses that command to act in a backw)-3.518 F 1.018 +(ard direction.)-.1 F(Com-)6.018 E(mands whose beha)108 499.2 Q +(vior with ar)-.2 E(guments de)-.18 E(viates from this are noted.)-.25 E +.811(When a command is described as)108 516 R F3(killing)3.311 E F0(te) +3.311 E .811(xt, the te)-.15 F .811(xt deleted is sa)-.15 F -.15(ve)-.2 +G 3.311(df).15 G .812(or possible future retrie)-3.311 F -.25(va)-.25 G +3.312(l\().25 G F3(yank-)-3.312 E(ing)108 528 Q F0 2.529(\). The)B .029 +(killed te)2.529 F .029(xt is sa)-.15 F -.15(ve)-.2 G 2.529(di).15 G +2.529(na)-2.529 G F3 .029(kill ring)B F0 5.029(.C)C(onsecuti)-5.029 E +.329 -.15(ve k)-.25 H .029(ills cause the te).15 F .029 +(xt to be accumulated into one unit,)-.15 F .567(which can be yank)108 +540 R .567(ed all at once.)-.1 F .567(Commands which do not kill te) +5.567 F .567(xt separate the chunks of te)-.15 F .567(xt on the kill) +-.15 F(ring.)108 552 Q F1(INITIALIZA)72 568.8 Q(TION FILE)-1.04 E F0 +.091(Readline is customized by putting commands in an initialization \ +\214le \(the)108 580.8 R F3(inputr)2.591 E(c)-.37 E F0 2.591 +(\214le\). The)2.591 F .091(name of this \214le)2.591 F 1.442(is tak)108 +592.8 R 1.443(en from the v)-.1 F 1.443(alue of the)-.25 F F2(INPUTRC) +3.943 E F0(en)3.943 E 1.443(vironment v)-.4 F 3.943(ariable. If)-.25 F +1.443(that v)3.943 F 1.443(ariable is unset, the def)-.25 F 1.443 +(ault is)-.1 F F3(~/.inputr)108 604.8 Q(c)-.37 E F0 5.359(.W).31 G .359 +(hen a program which uses the readline library starts up, the init \214\ +le is read, and the k)-5.359 F .658 -.15(ey b)-.1 H(ind-).15 E 1.083 +(ings and v)108 616.8 R 1.083(ariables are set.)-.25 F 1.083 +(There are only a fe)6.083 F 3.583(wb)-.25 G 1.083(asic constructs allo) +-3.583 F 1.084(wed in the readline init \214le.)-.25 F(Blank)6.084 E +.737(lines are ignored.)108 628.8 R .737(Lines be)5.737 F .737 +(ginning with a)-.15 F F2(#)3.237 E F0 .737(are comments.)3.237 F .737 +(Lines be)5.737 F .737(ginning with a)-.15 F F2($)3.237 E F0 .736 +(indicate conditional)3.236 F 2.614(constructs. Other)108 640.8 R .114 +(lines denote k)2.614 F .414 -.15(ey b)-.1 H .115(indings and v).15 F +.115(ariable settings.)-.25 F .115 +(Each program using this library may add)5.115 F(its o)108 652.8 Q +(wn commands and bindings.)-.25 E -.15(Fo)108 669.6 S 2.5(re).15 G +(xample, placing)-2.65 E(M\255Control\255u: uni)144 686.4 Q -.15(ve)-.25 +G(rsal\255ar).15 E(gument)-.18 E(or)108 698.4 Q(C\255Meta\255u: uni)144 +710.4 Q -.15(ve)-.25 G(rsal\255ar).15 E(gument)-.18 E(GNU Readline 4.3) +72 768 Q(2002 January 22)126.24 E(1)195.95 E EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R +(into the)108 84 Q/F1 10/Times-Italic@0 SF(inputr)2.5 E(c)-.37 E F0 -.1 +(wo)2.5 G(uld mak).1 E 2.5(eM)-.1 G(\255C\255u e)-2.5 E -.15(xe)-.15 G +(cute the readline command).15 E F1(univer)2.5 E(sal\255ar)-.1 E(gument) +-.37 E F0(.).68 E 2.795(The follo)108 100.8 R 2.795 +(wing symbolic character names are recognized while processing k)-.25 F +3.095 -.15(ey b)-.1 H(indings:).15 E F1(DEL)5.295 E F0(,).53 E F1(ESC) +5.295 E F0(,).72 E F1(ESCAPE)108 112.8 Q F0(,).73 E F1(LFD)2.5 E F0(,) +.28 E F1(NEWLINE)2.5 E F0(,).73 E F1(RET)2.5 E F0(,)1.27 E F1(RETURN)2.5 +E F0(,)1.1 E F1 -.4(RU)2.5 G(BOUT).4 E F0(,)1.27 E F1(SP)2.5 E -.3(AC) +-.9 G(E).3 E F0(,).73 E F1(SPC)2.5 E F0 2.5(,a).72 G(nd)-2.5 E F1 -.5 +(TA)2.5 G(B).5 E F0(.).27 E .209 +(In addition to command names, readline allo)108 129.6 R .209(ws k)-.25 +F -.15(ey)-.1 G 2.709(st).15 G 2.709(ob)-2.709 G 2.709(eb)-2.709 G .209 +(ound to a string that is inserted when the k)-2.709 F .509 -.15(ey i) +-.1 H(s).15 E(pressed \(a)108 141.6 Q F1(macr)2.5 E(o)-.45 E F0(\).)A/F2 +10/Times-Bold@0 SF -.25(Ke)87 163.2 S 2.5(yB).25 G(indings)-2.5 E F0 +.382(The syntax for controlling k)108 175.2 R .682 -.15(ey b)-.1 H .382 +(indings in the).15 F F1(inputr)2.882 E(c)-.37 E F0 .382 +(\214le is simple.)2.882 F .382(All that is required is the name of the) +5.382 F .382(command or the te)108 187.2 R .383(xt of a macro and a k) +-.15 F .683 -.15(ey s)-.1 H .383 +(equence to which it should be bound. The name may be speci-).15 F .853 +(\214ed in one of tw)108 199.2 R 3.353(ow)-.1 G .853 +(ays: as a symbolic k)-3.453 F 1.153 -.15(ey n)-.1 H .853 +(ame, possibly with).15 F F1(Meta\255)3.353 E F0(or)3.353 E F1(Contr) +3.353 E(ol\255)-.45 E F0(pre\214x)3.353 E .853(es, or as a k)-.15 F -.15 +(ey)-.1 G(sequence.)108 211.2 Q 1.766(When using the form)108 228 R F2 +-.1(ke)4.266 G(yname).1 E F0(:)A F1(function-name).833 E F0(or)4.266 E +F1(macr)4.267 E(o)-.45 E F0(,)A F1 -.1(ke)4.267 G(yname)-.2 E F0 1.767 +(is the name of a k)4.267 F 2.067 -.15(ey s)-.1 H 1.767(pelled out in) +.15 F 2.5(English. F)108 240 R(or e)-.15 E(xample:)-.15 E +(Control\255u: uni)144 264 Q -.15(ve)-.25 G(rsal\255ar).15 E(gument)-.18 +E(Meta\255Rubout: backw)144 276 Q(ard\255kill\255w)-.1 E(ord)-.1 E +(Control\255o: "> output")144 288 Q .229(In the abo)108 304.8 R .529 +-.15(ve ex)-.15 H(ample,).15 E F1(C\255u)2.729 E F0 .229 +(is bound to the function)2.729 F F2(uni)2.729 E -.1(ve)-.1 G +(rsal\255ar).1 E(gument)-.1 E F0(,)A F1(M-DEL)2.729 E F0 .228 +(is bound to the function)2.729 F F2(backward\255kill\255w)108 316.8 Q +(ord)-.1 E F0 3.837(,a)C(nd)-3.837 E F1(C\255o)3.837 E F0 1.337 +(is bound to run the macro e)3.837 F 1.337 +(xpressed on the right hand side \(that is, to)-.15 F(insert the te)108 +328.8 Q(xt)-.15 E/F3 10/Courier@0 SF 6(>o)2.5 G(utput)-6 E F0 +(into the line\).)2.5 E .056(In the second form,)108 345.6 R F2("k)2.556 +E(eyseq")-.1 E F0(:)A F1(function\255name).833 E F0(or)2.556 E F1(macr) +2.556 E(o)-.45 E F0(,)A F2 -.1(ke)2.556 G(yseq).1 E F0(dif)2.555 E .055 +(fers from)-.25 F F2 -.1(ke)2.555 G(yname).1 E F0(abo)2.555 E .355 -.15 +(ve i)-.15 H 2.555(nt).15 G .055(hat strings)-2.555 F 1.284 +(denoting an entire k)108 357.6 R 1.584 -.15(ey s)-.1 H 1.284(equence m\ +ay be speci\214ed by placing the sequence within double quotes.).15 F +(Some)6.284 E .386(GNU Emacs style k)108 369.6 R .686 -.15(ey e)-.1 H +.385(scapes can be used, as in the follo).15 F .385(wing e)-.25 F .385 +(xample, b)-.15 F .385(ut the symbolic character names)-.2 F +(are not recognized.)108 381.6 Q("\\C\255u": uni)144 405.6 Q -.15(ve) +-.25 G(rsal\255ar).15 E(gument)-.18 E +("\\C\255x\\C\255r": re\255read\255init\255\214le)144 417.6 Q +("\\e[11~": "Function K)144 429.6 Q .3 -.15(ey 1)-.25 H(").15 E .237 +(In this e)108 446.4 R(xample,)-.15 E F1(C-u)2.737 E F0 .237(is ag)2.737 +F .238(ain bound to the function)-.05 F F2(uni)2.738 E -.1(ve)-.1 G +(rsal\255ar).1 E(gument)-.1 E F0(.)A F1 .238(C-x C-r)5.238 F F0 .238 +(is bound to the function)2.738 F F2 -.18(re)108 458.4 S.18 E +(ead\255init\255\214le)-.18 E F0 2.5(,a)C(nd)-2.5 E F1(ESC [ 1 1 ~)2.5 E +F0(is bound to insert the te)2.5 E(xt)-.15 E F3(Function Key 1)2.5 E F0 +(.)A(The full set of GNU Emacs style escape sequences a)108 475.2 Q -.25 +(va)-.2 G(ilable when specifying k).25 E .3 -.15(ey s)-.1 H(equences is) +.15 E F2<5c43ad>144 487.2 Q F0(control pre\214x)20.3 E F2<5c4dad>144 +499.2 Q F0(meta pre\214x)18.08 E F2(\\e)144 511.2 Q F0 +(an escape character)28.78 E F2(\\\\)144 523.2 Q F0(backslash)30.44 E F2 +(\\")144 535.2 Q F0(literal ", a double quote)27.67 E F2(\\')144 547.2 Q +F0(literal ', a single quote)29.89 E(In addition to the GNU Emacs style\ + escape sequences, a second set of backslash escapes is a)108 564 Q -.25 +(va)-.2 G(ilable:).25 E F2(\\a)144 576 Q F0(alert \(bell\))28.22 E F2 +(\\b)144 588 Q F0(backspace)27.66 E F2(\\d)144 600 Q F0(delete)27.66 E +F2(\\f)144 612 Q F0(form feed)29.89 E F2(\\n)144 624 Q F0(ne)27.66 E +(wline)-.25 E F2(\\r)144 636 Q F0(carriage return)28.78 E F2(\\t)144 648 +Q F0(horizontal tab)29.89 E F2(\\v)144 660 Q F0 -.15(ve)28.22 G +(rtical tab).15 E F2(\\)144 672 Q F1(nnn)A F0 +(the eight-bit character whose v)18.22 E(alue is the octal v)-.25 E +(alue)-.25 E F1(nnn)2.5 E F0(\(one to three digits\))2.5 E F2(\\x)144 +684 Q F1(HH)A F0(the eight-bit character whose v)13.78 E(alue is the he) +-.25 E(xadecimal v)-.15 E(alue)-.25 E F1(HH)2.5 E F0(\(one or tw)2.5 E +2.5(oh)-.1 G .3 -.15(ex d)-2.5 H(igits\)).15 E .74(When entering the te) +108 700.8 R .74(xt of a macro, single or double quotes should be used t\ +o indicate a macro de\214nition.)-.15 F .089(Unquoted te)108 712.8 R +.089(xt is assumed to be a function name.)-.15 F .09(In the macro body) +5.089 F 2.59(,t)-.65 G .09(he backslash escapes described abo)-2.59 F +-.15(ve)-.15 G(are e)108 724.8 Q 2.5(xpanded. Backslash)-.15 F +(will quote an)2.5 E 2.5(yo)-.15 G(ther character in the macro te)-2.5 E +(xt, including " and '.)-.15 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(2)195.95 E EP +%%Page: 3 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(Bash)108 84 Q F0(allo)2.93 E .43 +(ws the current readline k)-.25 F .73 -.15(ey b)-.1 H .429 +(indings to be displayed or modi\214ed with the).15 F F1(bind)2.929 E F0 +-.2(bu)2.929 G .429(iltin command.).2 F 1.095 +(The editing mode may be switched during interacti)108 96 R 1.395 -.15 +(ve u)-.25 H 1.095(se by using the).15 F F13.595 E F0 1.095 +(option to the)3.595 F F1(set)3.595 E F0 -.2(bu)3.595 G 1.095 +(iltin com-).2 F 3.097(mand. Other)108 108 R .597 +(programs using this library pro)3.097 F .597(vide similar mechanisms.) +-.15 F(The)5.597 E/F2 10/Times-Italic@0 SF(inputr)3.097 E(c)-.37 E F0 +.596(\214le may be edited and)3.096 F(re-read if a program does not pro) +108 120 Q(vide an)-.15 E 2.5(yo)-.15 G(ther means to incorporate ne)-2.5 +E 2.5(wb)-.25 G(indings.)-2.5 E F1 -.92(Va)87 136.8 S(riables).92 E F0 +.043(Readline has v)108 148.8 R .044 +(ariables that can be used to further customize its beha)-.25 F(vior)-.2 +E 5.044(.A)-.55 G -.25(va)-2.5 G .044(riable may be set in the).25 F F2 +(inpu-)2.544 E(tr)108 160.8 Q(c)-.37 E F0 +(\214le with a statement of the form)2.5 E F1(set)144 177.6 Q F2 +(variable\255name value)2.5 E F0 .807(Except where noted, readline v)108 +194.4 R .807(ariables can tak)-.25 F 3.307(et)-.1 G .807(he v)-3.307 F +(alues)-.25 E F1(On)3.307 E F0(or)3.307 E F1(Off)3.307 E F0 .807 +(\(without re)3.307 F -.05(ga)-.15 G .807(rd to case\).).05 F .807 +(The v)5.807 F(ari-)-.25 E(ables and their def)108 206.4 Q(ault v)-.1 E +(alues are:)-.25 E F1(bell\255style \(audible\))108 223.2 Q F0 .01 +(Controls what happens when readline w)144 235.2 R .011 +(ants to ring the terminal bell.)-.1 F .011(If set to)5.011 F F1(none) +2.511 E F0 2.511(,r)C .011(eadline ne)-2.511 F -.15(ve)-.25 G(r).15 E +.94(rings the bell.)144 247.2 R .94(If set to)5.94 F F1(visible)3.44 E +F0 3.44(,r)C .94(eadline uses a visible bell if one is a)-3.44 F -.25 +(va)-.2 G 3.44(ilable. If).25 F .94(set to)3.44 F F1(audible)3.44 E F0 +(,)A(readline attempts to ring the terminal')144 259.2 Q 2.5(sb)-.55 G +(ell.)-2.5 E F1(comment\255begin \(`)108 271.2 Q(`#')-.63 E('\))-.63 E +F0 .062(The string that is inserted in)144 283.2 R F1(vi)2.562 E F0 .062 +(mode when the)2.562 F F1(insert\255comment)2.562 E F0 .062 +(command is e)2.562 F -.15(xe)-.15 G 2.562(cuted. This).15 F(com-)2.562 +E(mand is bound to)144 295.2 Q F1(M\255#)2.5 E F0(in emacs mode and to) +2.5 E F1(#)2.5 E F0(in vi command mode.)2.5 E F1(completion\255ignor)108 +307.2 Q(e\255case \(Off\))-.18 E F0(If set to)144 319.2 Q F1(On)2.5 E F0 +2.5(,r)C(eadline performs \214lename matching and completion in a case\ +\255insensiti)-2.5 E .3 -.15(ve f)-.25 H(ashion.).05 E F1 +(completion\255query\255items \(100\))108 331.2 Q F0 .53 +(This determines when the user is queried about vie)144 343.2 R .529 +(wing the number of possible completions gen-)-.25 F .56(erated by the) +144 355.2 R F1(possible\255completions)3.06 E F0 3.06(command. It)3.06 F +.561(may be set to an)3.061 F 3.061(yi)-.15 G(nte)-3.061 E .561(ger v) +-.15 F .561(alue greater than or)-.25 F .783(equal to zero.)144 367.2 R +.783(If the number of possible completions is greater than or equal to \ +the v)5.783 F .782(alue of this)-.25 F -.25(va)144 379.2 S .237 +(riable, the user is ask).25 F .237(ed whether or not he wishes to vie) +-.1 F 2.737(wt)-.25 G .237(hem; otherwise the)-2.737 F 2.737(ya)-.15 G +.237(re simply listed)-2.737 F(on the terminal.)144 391.2 Q F1(con)108 +403.2 Q -.1(ve)-.4 G(rt\255meta \(On\)).1 E F0 .613(If set to)144 415.2 +R F1(On)3.113 E F0 3.113(,r)C .613(eadline will con)-3.113 F -.15(ve)-.4 +G .613(rt characters with the eighth bit set to an ASCII k).15 F .912 +-.15(ey s)-.1 H .612(equence by).15 F 1.315(stripping the eighth bit an\ +d pre\214xing it with an escape character \(in ef)144 427.2 R 1.316 +(fect, using escape as the)-.25 F F2(meta pr)144 439.2 Q(e\214x)-.37 E +F0(\).)A F1(disable\255completion \(Off\))108 451.2 Q F0 .038(If set to) +144 463.2 R F1(On)2.538 E F0 2.538(,r)C .038(eadline will inhibit w) +-2.538 F .038(ord completion.)-.1 F .038 +(Completion characters will be inserted into the)5.038 F(line as if the) +144 475.2 Q 2.5(yh)-.15 G(ad been mapped to)-2.5 E F1(self-insert)2.5 E +F0(.)A F1(editing\255mode \(emacs\))108 487.2 Q F0 .215 +(Controls whether readline be)144 499.2 R .215(gins with a set of k)-.15 +F .515 -.15(ey b)-.1 H .216(indings similar to emacs or vi.).15 F F1 +(editing\255mode)5.216 E F0(can be set to either)144 511.2 Q F1(emacs) +2.5 E F0(or)2.5 E F1(vi)2.5 E F0(.)A F1(enable\255k)108 523.2 Q +(eypad \(Off\))-.1 E F0 .893(When set to)144 535.2 R F1(On)3.393 E F0 +3.393(,r)C .893(eadline will try to enable the application k)-3.393 F +-.15(ey)-.1 G .893(pad when it is called.).15 F .892(Some sys-)5.893 F +(tems need this to enable the arro)144 547.2 Q 2.5(wk)-.25 G -.15(ey) +-2.6 G(s.).15 E F1(expand\255tilde \(Off\))108 559.2 Q F0(If set to)144 +571.2 Q F1(on)2.5 E F0 2.5(,t)C(ilde e)-2.5 E +(xpansion is performed when readline attempts w)-.15 E(ord completion.) +-.1 E F1(history-pr)108 583.2 Q(eser)-.18 E -.1(ve)-.1 G(-point).1 E F0 +1.492(If set to)144 595.2 R F1(on)3.992 E F0 3.992(,t)C 1.493(he histor\ +y code attempts to place point at the same location on each history lin\ +e)-3.992 F(retri)144 607.2 Q -.15(ve)-.25 G 2.5(dw).15 G(ith)-2.5 E F1 +(pr)2.5 E -.15(ev)-.18 G(ious-history).15 E F0(or)2.5 E F1(next-history) +2.5 E F0(.)A F1(horizontal\255scr)108 619.2 Q(oll\255mode \(Off\))-.18 E +F0 .449(When set to)144 631.2 R F1(On)2.949 E F0 2.949(,m)C(ak)-2.949 E +.448(es readline use a single line for display)-.1 F 2.948(,s)-.65 G +.448(crolling the input horizontally on a)-2.948 F 1.194(single screen \ +line when it becomes longer than the screen width rather than wrapping \ +to a ne)144 643.2 R(w)-.25 E(line.)144 655.2 Q F1(input\255meta \(Off\)) +108 667.2 Q F0 .367(If set to)144 679.2 R F1(On)2.867 E F0 2.867(,r)C +.367(eadline will enable eight-bit input \(that is, it will not clear t\ +he eighth bit in the char)-2.867 F(-)-.2 E .956(acters it reads\), re) +144 691.2 R -.05(ga)-.15 G .956 +(rdless of what the terminal claims it can support.).05 F .957(The name) +5.956 F F1(meta\255\215ag)3.457 E F0 .957(is a)3.457 F(synon)144 703.2 Q +(ym for this v)-.15 E(ariable.)-.25 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(3)195.95 E EP +%%Page: 4 4 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(isear)108 84 Q(ch\255terminators \(`)-.18 E +(`C\255[ C\255J')-.63 E('\))-.63 E F0 .439(The string of characters tha\ +t should terminate an incremental search without subsequently e)144 96 R +-.15(xe)-.15 G(cut-).15 E .934(ing the character as a command.)144 108 R +.935(If this v)5.935 F .935(ariable has not been gi)-.25 F -.15(ve)-.25 +G 3.435(nav).15 G .935(alue, the characters)-3.685 F/F2 10 +/Times-Italic@0 SF(ESC)3.435 E F0(and)144 120 Q F2(C\255J)2.5 E F0 +(will terminate an incremental search.)2.5 E F1 -.1(ke)108 132 S +(ymap \(emacs\)).1 E F0 2.323(Set the current readline k)144 144 R -.15 +(ey)-.1 G 4.823(map. The).15 F 2.323(set of le)4.823 F -.05(ga)-.15 G +4.823(lk).05 G -.15(ey)-4.923 G 2.323(map names is).15 F F2 2.323 +(emacs, emacs-standar)4.823 F(d,)-.37 E .808 +(emacs-meta, emacs-ctlx, vi, vi-mo)144 156 R(ve)-.1 E 3.308(,v)-.1 G +(i-command)-3.308 E F0 3.308(,a)C(nd)-3.308 E F2(vi-insert)3.308 E F0(.) +.68 E F2(vi)5.808 E F0 .808(is equi)3.308 F -.25(va)-.25 G .809(lent to) +.25 F F2(vi-command)3.309 E F0(;)A F2(emacs)144 168 Q F0 .697(is equi) +3.197 F -.25(va)-.25 G .697(lent to).25 F F2(emacs-standar)3.197 E(d) +-.37 E F0 5.697(.T)C .697(he def)-5.697 F .697(ault v)-.1 F .697 +(alue is)-.25 F F2(emacs)3.197 E F0 5.697(.T).27 G .697(he v)-5.697 F +.697(alue of)-.25 F F1(editing\255mode)3.196 E F0(also af)144 180 Q +(fects the def)-.25 E(ault k)-.1 E -.15(ey)-.1 G(map.).15 E F1 +(mark\255dir)108 192 Q(ectories \(On\))-.18 E F0(If set to)144 204 Q F1 +(On)2.5 E F0 2.5(,c)C(ompleted directory names ha)-2.5 E .3 -.15(ve a s) +-.2 H(lash appended.).15 E F1(mark\255modi\214ed\255lines \(Off\))108 +216 Q F0(If set to)144 228 Q F1(On)2.5 E F0 2.5(,h)C +(istory lines that ha)-2.5 E .3 -.15(ve b)-.2 H +(een modi\214ed are displayed with a preceding asterisk \().15 E F1(*)A +F0(\).)A F1(mark\255symlink)108 240 Q(ed\255dir)-.1 E(ectories \(Off\)) +-.18 E F0 .175(If set to)144 252 R F1(On)2.675 E F0 2.675(,c)C .175 +(ompleted names which are symbolic links to directories ha)-2.675 F .475 +-.15(ve a s)-.2 H .175(lash appended \(sub-).15 F(ject to the v)144 264 +Q(alue of)-.25 E F1(mark\255dir)2.5 E(ectories)-.18 E F0(\).)A F1 +(match\255hidden\255\214les \(On\))108 276 Q F0 .193(This v)144 288 R +.193(ariable, when set to)-.25 F F1(On)2.693 E F0 2.693(,c)C .192 +(auses readline to match \214les whose names be)-2.693 F .192 +(gin with a `.)-.15 F 2.692('\()-.7 G(hidden)-2.692 E 1.023 +(\214les\) when performing \214lename completion, unless the leading `.) +144 300 R 3.523('i)-.7 G 3.523(ss)-3.523 G 1.024 +(upplied by the user in the)-3.523 F(\214lename to be completed.)144 312 +Q F1(output\255meta \(Off\))108 324 Q F0 .507(If set to)144 336 R F1(On) +3.007 E F0 3.007(,r)C .507(eadline will display characters with the eig\ +hth bit set directly rather than as a meta-)-3.007 F(pre\214x)144 348 Q +(ed escape sequence.)-.15 E F1(page\255completions \(On\))108 360 Q F0 +.808(If set to)144 372 R F1(On)3.308 E F0 3.308(,r)C .808 +(eadline uses an internal)-3.308 F F2(mor)3.308 E(e)-.37 E F0(-lik)A +3.308(ep)-.1 G .808(ager to display a screenful of possible comple-) +-3.308 F(tions at a time.)144 384 Q F1 +(print\255completions\255horizontally \(Off\))108 396 Q F0 1.319 +(If set to)144 408 R F1(On)3.819 E F0 3.819(,r)C 1.318(eadline will dis\ +play completions with matches sorted horizontally in alphabetical)-3.819 +F(order)144 420 Q 2.5(,r)-.4 G(ather than do)-2.5 E(wn the screen.)-.25 +E F1(sho)108 432 Q(w\255all\255if\255ambiguous \(Off\))-.1 E F0 .477 +(This alters the def)144 444 R .477(ault beha)-.1 F .477 +(vior of the completion functions.)-.2 F .478(If set to)5.478 F F1(on) +2.978 E F0 2.978(,w)C .478(ords which ha)-3.078 F .778 -.15(ve m)-.2 H +(ore).15 E 1.264(than one possible completion cause the matches to be l\ +isted immediately instead of ringing the)144 456 R(bell.)144 468 Q F1 +(visible\255stats \(Off\))108 480 Q F0 .846(If set to)144 492 R F1(On) +3.346 E F0 3.346(,ac)C .846(haracter denoting a \214le')-3.346 F 3.346 +(st)-.55 G .846(ype as reported by)-3.346 F F2(stat)3.346 E F0 .846 +(\(2\) is appended to the \214lename)B +(when listing possible completions.)144 504 Q F1(Conditional Constructs) +87 520.8 Q F0 .05(Readline implements a f)108 532.8 R .05(acility simil\ +ar in spirit to the conditional compilation features of the C preproces\ +sor)-.1 F .096(which allo)108 544.8 R .096(ws k)-.25 F .396 -.15(ey b) +-.1 H .096(indings and v).15 F .096 +(ariable settings to be performed as the result of tests.)-.25 F .097 +(There are four parser)5.096 F(directi)108 556.8 Q -.15(ve)-.25 G 2.5 +(su).15 G(sed.)-2.5 E F1($if)108 573.6 Q F0(The)24.89 E F1($if)2.963 E +F0 .463(construct allo)2.963 F .462(ws bindings to be made based on the\ + editing mode, the terminal being used,)-.25 F .477 +(or the application using readline.)144 585.6 R .477(The te)5.477 F .477 +(xt of the test e)-.15 F .477 +(xtends to the end of the line; no characters)-.15 F +(are required to isolate it.)144 597.6 Q F1(mode)144 614.4 Q F0(The) +12.67 E F1(mode=)3.712 E F0 1.212(form of the)3.712 F F1($if)3.711 E F0 +(directi)3.711 E 1.511 -.15(ve i)-.25 H 3.711(su).15 G 1.211 +(sed to test whether readline is in emacs or vi)-3.711 F 3.065 +(mode. This)180 626.4 R .565(may be used in conjunction with the)3.065 F +F1 .565(set k)3.065 F(eymap)-.1 E F0 .565(command, for instance, to) +3.065 F .03(set bindings in the)180 638.4 R F2(emacs-standar)2.529 E(d) +-.37 E F0(and)2.529 E F2(emacs-ctlx)2.529 E F0 -.1(ke)2.529 G .029 +(ymaps only if readline is starting out)-.05 F(in emacs mode.)180 650.4 +Q F1(term)144 667.2 Q F0(The)15.46 E F1(term=)3.196 E F0 .696 +(form may be used to include terminal-speci\214c k)3.196 F .996 -.15 +(ey b)-.1 H .697(indings, perhaps to bind).15 F .654(the k)180 679.2 R +.954 -.15(ey s)-.1 H .654(equences output by the terminal').15 F 3.154 +(sf)-.55 G .654(unction k)-3.154 F -.15(ey)-.1 G 3.154(s. The).15 F -.1 +(wo)3.154 G .654(rd on the right side of).1 F(the)180 691.2 Q F1(=)3.003 +E F0 .503(is tested ag)3.003 F .504(ainst the full name of the terminal\ + and the portion of the terminal name)-.05 F(before the \214rst)180 +703.2 Q F12.5 E F0 5(.T)C(his allo)-5 E(ws)-.25 E F2(sun)2.5 E F0 +(to match both)2.5 E F2(sun)2.5 E F0(and)2.5 E F2(sun\255cmd)2.5 E F0 +2.5(,f).77 G(or instance.)-2.5 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(4)195.95 E EP +%%Page: 5 5 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(application)144 84 Q F0(The)180 96 Q F1(application) +3.003 E F0 .503 +(construct is used to include application-speci\214c settings.)3.003 F +.503(Each program)5.503 F .114(using the readline library sets the)180 +108 R/F2 10/Times-Italic@0 SF .114(application name)2.614 F F0 2.614(,a) +C .114(nd an initialization \214le can test for a)-2.614 F .501 +(particular v)180 120 R 3.001(alue. This)-.25 F .501 +(could be used to bind k)3.001 F .801 -.15(ey s)-.1 H .5 +(equences to functions useful for a spe-).15 F .396(ci\214c program.)180 +132 R -.15(Fo)5.396 G 2.896(ri).15 G .396(nstance, the follo)-2.896 F +.396(wing command adds a k)-.25 F .696 -.15(ey s)-.1 H .397 +(equence that quotes the).15 F(current or pre)180 144 Q(vious w)-.25 E +(ord in Bash:)-.1 E F1($if)180 168 Q F0(Bash)2.5 E 2.5(#Q)180 180 S +(uote the current or pre)-2.5 E(vious w)-.25 E(ord)-.1 E +("\\C-xq": "\\eb\\"\\ef\\"")180 192 Q F1($endif)180 204 Q($endif)108 +220.8 Q F0(This command, as seen in the pre)9.33 E(vious e)-.25 E +(xample, terminates an)-.15 E F1($if)2.5 E F0(command.)2.5 E F1($else) +108 237.6 Q F0(Commands in this branch of the)15.45 E F1($if)2.5 E F0 +(directi)2.5 E .3 -.15(ve a)-.25 H(re e).15 E -.15(xe)-.15 G +(cuted if the test f).15 E(ails.)-.1 E F1($include)108 254.4 Q F0 .357 +(This directi)144 266.4 R .657 -.15(ve t)-.25 H(ak).15 E .357 +(es a single \214lename as an ar)-.1 F .356 +(gument and reads commands and bindings from that)-.18 F 2.5(\214le. F) +144 278.4 R(or e)-.15 E(xample, the follo)-.15 E(wing directi)-.25 E .3 +-.15(ve w)-.25 H(ould read).05 E F2(/etc/inputr)2.5 E(c)-.37 E F0(:)A F1 +($include)144 302.4 Q F2(/etc/inputr)5.833 E(c)-.37 E/F3 10.95 +/Times-Bold@0 SF(SEARCHING)72 319.2 Q F0 1.003(Readline pro)108 331.2 R +1.003(vides commands for searching through the command history for line\ +s containing a speci\214ed)-.15 F 2.5(string. There)108 343.2 R(are tw) +2.5 E 2.5(os)-.1 G(earch modes:)-2.5 E F2(incr)2.5 E(emental)-.37 E F0 +(and)2.5 E F2(non-incr)2.5 E(emental)-.37 E F0(.).51 E .698 +(Incremental searches be)108 360 R .698 +(gin before the user has \214nished typing the search string.)-.15 F +.697(As each character of the)5.697 F .112 +(search string is typed, readline displays the ne)108 372 R .112 +(xt entry from the history matching the string typed so f)-.15 F(ar)-.1 +E 5.113(.A)-.55 G(n)-5.113 E .545 +(incremental search requires only as man)108 384 R 3.045(yc)-.15 G .544 +(haracters as needed to \214nd the desired history entry)-3.045 F 5.544 +(.T)-.65 G 3.044(os)-6.344 G(earch)-3.044 E(backw)108 396 Q .18 +(ard in the history for a particular string, type)-.1 F F1(C\255r)2.681 +E F0 5.181(.T)C(yping)-5.981 E F1(C\255s)2.681 E F0 .181(searches forw) +2.681 F .181(ard through the history)-.1 F(.)-.65 E .354 +(The characters present in the v)108 408 R .354(alue of the)-.25 F F1 +(isear)2.854 E(ch-terminators)-.18 E F0 -.25(va)2.854 G .354 +(riable are used to terminate an incremen-).25 F .6(tal search.)108 420 +R .6(If that v)5.6 F .6(ariable has not been assigned a v)-.25 F .6 +(alue the)-.25 F F2(Escape)3.1 E F0(and)3.1 E F1(C\255J)3.1 E F0 .6 +(characters will terminate an)3.1 F .123(incremental search.)108 432 R +F1(C\255G)5.123 E F0 .123 +(will abort an incremental search and restore the original line.)2.623 F +.122(When the search is)5.122 F(terminated, the history entry containin\ +g the search string becomes the current line.)108 444 Q 2.406 -.8 +(To \214)108 460.8 T .806 +(nd other matching entries in the history list, type).8 F F1(C\255s) +3.306 E F0(or)3.306 E F1(C\255r)3.306 E F0 .806(as appropriate.)3.306 F +.807(This will search back-)5.806 F -.1(wa)108 472.8 S 1.309(rd or forw) +.1 F 1.309(ard in the history for the ne)-.1 F 1.309 +(xt line matching the search string typed so f)-.15 F(ar)-.1 E 6.309(.A) +-.55 G 1.609 -.15(ny o)-6.309 H 1.308(ther k).15 F -.15(ey)-.1 G .317 +(sequence bound to a readline command will terminate the search and e) +108 484.8 R -.15(xe)-.15 G .318(cute that command.).15 F -.15(Fo)5.318 G +2.818(ri).15 G(nstance,)-2.818 E 3.481(an)108 496.8 S -.25(ew)-3.481 G +.981(line will terminate the search and accept the line, thereby e).25 F +-.15(xe)-.15 G .98(cuting the command from the history).15 F 3.061 +(list. A)108 508.8 R(mo)3.061 E -.15(ve)-.15 G .562 +(ment command will terminate the search, mak).15 F 3.062(et)-.1 G .562 +(he last line found the current line, and be)-3.062 F(gin)-.15 E +(editing.)108 520.8 Q .567(Non-incremental searches read the entire sea\ +rch string before starting to search for matching history lines.)108 +537.6 R(The search string may be typed by the user or be part of the co\ +ntents of the current line.)108 549.6 Q F3(EDITING COMMANDS)72 566.4 Q +F0 1.391(The follo)108 578.4 R 1.391 +(wing is a list of the names of the commands and the def)-.25 F 1.391 +(ault k)-.1 F 1.691 -.15(ey s)-.1 H 1.391(equences to which the).15 F +3.892(ya)-.15 G(re)-3.892 E 2.5(bound. Command)108 590.4 R +(names without an accompan)2.5 E(ying k)-.15 E .3 -.15(ey s)-.1 H +(equence are unbound by def).15 E(ault.)-.1 E .055(In the follo)108 +607.2 R .055(wing descriptions,)-.25 F F2(point)2.555 E F0 .055 +(refers to the current cursor position, and)2.555 F F2(mark)2.555 E F0 +.054(refers to a cursor position)2.554 F(sa)108 619.2 Q -.15(ve)-.2 G +2.5(db).15 G 2.5(yt)-2.5 G(he)-2.5 E F1(set\255mark)2.5 E F0 2.5 +(command. The)2.5 F(te)2.5 E +(xt between the point and mark is referred to as the)-.15 E F2 -.37(re) +2.5 G(gion)-.03 E F0(.)A F1(Commands f)87 636 Q(or Mo)-.25 E(ving)-.1 E +(beginning\255of\255line \(C\255a\))108 648 Q F0(Mo)144 660 Q .3 -.15 +(ve t)-.15 H 2.5(ot).15 G(he start of the current line.)-2.5 E F1 +(end\255of\255line \(C\255e\))108 672 Q F0(Mo)144 684 Q .3 -.15(ve t) +-.15 H 2.5(ot).15 G(he end of the line.)-2.5 E F1 -.25(fo)108 696 S +(rward\255char \(C\255f\)).25 E F0(Mo)144 708 Q .3 -.15(ve f)-.15 H(orw) +.15 E(ard a character)-.1 E(.)-.55 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(5)195.95 E EP +%%Page: 6 6 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(backward\255char \(C\255b\))108 84 Q F0(Mo)144 96 Q .3 +-.15(ve b)-.15 H(ack a character).15 E(.)-.55 E F1 -.25(fo)108 108 S +(rward\255w).25 E(ord \(M\255f\))-.1 E F0(Mo)144 120 Q .822 -.15(ve f) +-.15 H(orw).15 E .522(ard to the end of the ne)-.1 F .523(xt w)-.15 F +3.023(ord. W)-.1 F .523 +(ords are composed of alphanumeric characters \(let-)-.8 F +(ters and digits\).)144 132 Q F1(backward\255w)108 144 Q(ord \(M\255b\)) +-.1 E F0(Mo)144 156 Q 1.71 -.15(ve b)-.15 H 1.41 +(ack to the start of the current or pre).15 F 1.41(vious w)-.25 F 3.91 +(ord. W)-.1 F 1.41(ords are composed of alphanumeric)-.8 F +(characters \(letters and digits\).)144 168 Q F1(clear\255scr)108 180 Q +(een \(C\255l\))-.18 E F0 .993(Clear the screen lea)144 192 R .993 +(ving the current line at the top of the screen.)-.2 F -.4(Wi)5.993 G +.993(th an ar).4 F .993(gument, refresh the)-.18 F +(current line without clearing the screen.)144 204 Q F1 -.18(re)108 216 +S(draw\255curr).18 E(ent\255line)-.18 E F0(Refresh the current line.)144 +228 Q F1(Commands f)87 244.8 Q(or Manipulating the History)-.25 E +(accept\255line \(Newline, Retur)108 256.8 Q(n\))-.15 E F0 .365 +(Accept the line re)144 268.8 R -.05(ga)-.15 G .364 +(rdless of where the cursor is.).05 F .364(If this line is non-empty) +5.364 F 2.864(,i)-.65 G 2.864(tm)-2.864 G .364(ay be added to the)-2.864 +F .74(history list for future recall with)144 280.8 R F1 +(add_history\(\))3.24 E F0 5.741(.I)C 3.241(ft)-5.741 G .741 +(he line is a modi\214ed history line, the history)-3.241 F +(line is restored to its original state.)144 292.8 Q F1(pr)108 304.8 Q +-.15(ev)-.18 G(ious\255history \(C\255p\)).15 E F0(Fetch the pre)144 +316.8 Q(vious command from the history list, mo)-.25 E +(ving back in the list.)-.15 E F1(next\255history \(C\255n\))108 328.8 Q +F0(Fetch the ne)144 340.8 Q(xt command from the history list, mo)-.15 E +(ving forw)-.15 E(ard in the list.)-.1 E F1 +(beginning\255of\255history \(M\255<\))108 352.8 Q F0(Mo)144 364.8 Q .3 +-.15(ve t)-.15 H 2.5(ot).15 G(he \214rst line in the history)-2.5 E(.) +-.65 E F1(end\255of\255history \(M\255>\))108 376.8 Q F0(Mo)144 388.8 Q +.3 -.15(ve t)-.15 H 2.5(ot).15 G(he end of the input history)-2.5 E 2.5 +(,i)-.65 G(.e., the line currently being entered.)-2.5 E F1 -2.29 -.18 +(re v)108 400.8 T(erse\255sear).08 E(ch\255history \(C\255r\))-.18 E F0 +1.471(Search backw)144 412.8 R 1.471 +(ard starting at the current line and mo)-.1 F 1.47 +(ving `up' through the history as necessary)-.15 F(.)-.65 E +(This is an incremental search.)144 424.8 Q F1 -.25(fo)108 436.8 S +(rward\255sear).25 E(ch\255history \(C\255s\))-.18 E F0 1.131 +(Search forw)144 448.8 R 1.131(ard starting at the current line and mo) +-.1 F 1.132(ving `do)-.15 F 1.132(wn' through the history as necessary) +-.25 F(.)-.65 E(This is an incremental search.)144 460.8 Q F1 +(non\255incr)108 472.8 Q(emental\255r)-.18 E -2.3 -.15(ev e)-.18 H +(rse\255sear).15 E(ch\255history \(M\255p\))-.18 E F0 .165(Search backw) +144 484.8 R .164(ard through the history starting at the current line u\ +sing a non-incremental search for)-.1 F 2.5(as)144 496.8 S +(tring supplied by the user)-2.5 E(.)-.55 E F1(non\255incr)108 508.8 Q +(emental\255f)-.18 E(orward\255sear)-.25 E(ch\255history \(M\255n\))-.18 +E F0 1.353(Search forw)144 520.8 R 1.354(ard through the history using \ +a non-incremental search for a string supplied by the)-.1 F(user)144 +532.8 Q(.)-.55 E F1(history\255sear)108 544.8 Q(ch\255f)-.18 E(orward) +-.25 E F0 .249(Search forw)144 556.8 R .249(ard through the history for\ + the string of characters between the start of the current line)-.1 F +(and the current cursor position \(the)144 568.8 Q/F2 10/Times-Italic@0 +SF(point)2.5 E F0 2.5(\). This)B(is a non-incremental search.)2.5 E F1 +(history\255sear)108 580.8 Q(ch\255backward)-.18 E F0 .95(Search backw) +144 592.8 R .951(ard through the history for the string of characters b\ +etween the start of the current)-.1 F(line and the point.)144 604.8 Q +(This is a non-incremental search.)5 E F1(yank\255nth\255ar)108 616.8 Q +2.5(g\()-.1 G<4dad43ad7929>-2.5 E F0 .622(Insert the \214rst ar)144 +628.8 R .622(gument to the pre)-.18 F .622 +(vious command \(usually the second w)-.25 F .622(ord on the pre)-.1 F +.622(vious line\))-.25 F .794(at point.)144 640.8 R -.4(Wi)5.794 G .794 +(th an ar).4 F(gument)-.18 E F2(n)3.294 E F0 3.294(,i).24 G .794 +(nsert the)-3.294 F F2(n)3.294 E F0 .794(th w)B .794(ord from the pre) +-.1 F .794(vious command \(the w)-.25 F .795(ords in the)-.1 F(pre)144 +652.8 Q .292(vious command be)-.25 F .292(gin with w)-.15 F .291 +(ord 0\).)-.1 F 2.791(An)5.291 G -2.25 -.15(eg a)-2.791 H(ti).15 E .591 +-.15(ve a)-.25 H -.18(rg).15 G .291(ument inserts the).18 F F2(n)2.791 E +F0 .291(th w)B .291(ord from the end of)-.1 F(the pre)144 664.8 Q +(vious command.)-.25 E F1(yank\255last\255ar)108 676.8 Q 2.5(g\()-.1 G +-1.667(M\255. ,)-2.5 F -1.667(M\255_ \))2.5 F F0 1.307 +(Insert the last ar)144 688.8 R 1.307(gument to the pre)-.18 F 1.307 +(vious command \(the last w)-.25 F 1.308(ord of the pre)-.1 F 1.308 +(vious history entry\).)-.25 F -.4(Wi)144 700.8 S .736(th an ar).4 F +.736(gument, beha)-.18 F 1.036 -.15(ve ex)-.2 H .736(actly lik).15 F(e) +-.1 E F1(yank\255nth\255ar)3.235 E(g)-.1 E F0 5.735(.S)C(uccessi)-5.735 +E 1.035 -.15(ve c)-.25 H .735(alls to).15 F F1(yank\255last\255ar)3.235 +E(g)-.1 E F0(mo)3.235 E -.15(ve)-.15 G +(back through the history list, inserting the last ar)144 712.8 Q +(gument of each line in turn.)-.18 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(6)195.95 E EP +%%Page: 7 7 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(Commands f)87 84 Q(or Changing T)-.25 E(ext)-.92 E +(delete\255char \(C\255d\))108 96 Q F0 .357 +(Delete the character at point.)144 108 R .358(If point is at the be) +5.358 F .358(ginning of the line, there are no characters in the)-.15 F +(line, and the last character typed w)144 120 Q(as not bound to)-.1 E F1 +(delete\255char)2.5 E F0 2.5(,t)C(hen return)-2.5 E/F2 9/Times-Bold@0 SF +(EOF)2.5 E/F3 9/Times-Roman@0 SF(.)A F1 +(backward\255delete\255char \(Rubout\))108 132 Q F0 .553 +(Delete the character behind the cursor)144 144 R 5.553(.W)-.55 G .553 +(hen gi)-5.553 F -.15(ve)-.25 G 3.053(nan).15 G .553(umeric ar)-3.053 F +.552(gument, sa)-.18 F .852 -.15(ve t)-.2 H .552(he deleted te).15 F +.552(xt on)-.15 F(the kill ring.)144 156 Q F1 -.25(fo)108 168 S +(rward\255backward\255delete\255char).25 E F0 .473 +(Delete the character under the cursor)144 180 R 2.973(,u)-.4 G .474 +(nless the cursor is at the end of the line, in which case the)-2.973 F +(character behind the cursor is deleted.)144 192 Q F1 +(quoted\255insert \(C\255q, C\255v\))108 204 Q F0 1.229(Add the ne)144 +216 R 1.228(xt character that you type to the line v)-.15 F 3.728 +(erbatim. This)-.15 F 1.228(is ho)3.728 F 3.728(wt)-.25 G 3.728(oi) +-3.728 G 1.228(nsert characters lik)-3.728 F(e)-.1 E F1(C\255q)144 228 Q +F0 2.5(,f)C(or e)-2.5 E(xample.)-.15 E F1(tab\255insert \(M-T)108 240 Q +(AB\))-.9 E F0(Insert a tab character)144 252 Q(.)-.55 E F1 +(self\255insert \(a, b, A, 1, !, ...\))108 264 Q F0 +(Insert the character typed.)144 276 Q F1(transpose\255chars \(C\255t\)) +108 288 Q F0 .321(Drag the character before point forw)144 300 R .321 +(ard o)-.1 F -.15(ve)-.15 G 2.821(rt).15 G .321 +(he character at point, mo)-2.821 F .322(ving point forw)-.15 F .322 +(ard as well.)-.1 F 1.182 +(If point is at the end of the line, then this transposes the tw)144 312 +R 3.682(oc)-.1 G 1.182(haracters before point.)-3.682 F(Ne)6.182 E -.05 +(ga)-.15 G(ti).05 E -.15(ve)-.25 G(ar)144 324 Q(guments ha)-.18 E .3 +-.15(ve n)-.2 H 2.5(oe).15 G -.25(ff)-2.5 G(ect.).25 E F1 +(transpose\255w)108 336 Q(ords \(M\255t\))-.1 E F0 .023(Drag the w)144 +348 R .023(ord before point past the w)-.1 F .023(ord after point, mo) +-.1 F .023(ving point o)-.15 F -.15(ve)-.15 G 2.524(rt).15 G .024(hat w) +-2.524 F .024(ord as well.)-.1 F .024(If point)5.024 F +(is at the end of the line, this transposes the last tw)144 360 Q 2.5 +(ow)-.1 G(ords on the line.)-2.6 E F1(upcase\255w)108 372 Q +(ord \(M\255u\))-.1 E F0 1.699(Uppercase the current \(or follo)144 384 +R 1.698(wing\) w)-.25 F 4.198(ord. W)-.1 F 1.698(ith a ne)-.4 F -.05(ga) +-.15 G(ti).05 E 1.998 -.15(ve a)-.25 H -.18(rg).15 G 1.698 +(ument, uppercase the pre).18 F(vious)-.25 E -.1(wo)144 396 S(rd, b).1 E +(ut do not mo)-.2 E .3 -.15(ve p)-.15 H(oint.).15 E F1(do)108 408 Q +(wncase\255w)-.1 E(ord \(M\255l\))-.1 E F0(Lo)144 420 Q 1.647 +(wercase the current \(or follo)-.25 F 1.647(wing\) w)-.25 F 4.147 +(ord. W)-.1 F 1.648(ith a ne)-.4 F -.05(ga)-.15 G(ti).05 E 1.948 -.15 +(ve a)-.25 H -.18(rg).15 G 1.648(ument, lo).18 F 1.648(wercase the pre) +-.25 F(vious)-.25 E -.1(wo)144 432 S(rd, b).1 E(ut do not mo)-.2 E .3 +-.15(ve p)-.15 H(oint.).15 E F1(capitalize\255w)108 444 Q +(ord \(M\255c\))-.1 E F0 1.975(Capitalize the current \(or follo)144 456 +R 1.974(wing\) w)-.25 F 4.474(ord. W)-.1 F 1.974(ith a ne)-.4 F -.05(ga) +-.15 G(ti).05 E 2.274 -.15(ve a)-.25 H -.18(rg).15 G 1.974 +(ument, capitalize the pre).18 F(vious)-.25 E -.1(wo)144 468 S(rd, b).1 +E(ut do not mo)-.2 E .3 -.15(ve p)-.15 H(oint.).15 E F1 -.1(ove)108 480 +S(rwrite\255mode).1 E F0 -.8(To)144 492 S .437(ggle o).8 F -.15(ve)-.15 +G .437(rwrite mode.).15 F -.4(Wi)5.437 G .437(th an e).4 F .437 +(xplicit positi)-.15 F .738 -.15(ve n)-.25 H .438(umeric ar).15 F .438 +(gument, switches to o)-.18 F -.15(ve)-.15 G .438(rwrite mode.).15 F -.4 +(Wi)144 504 S .781(th an e).4 F .781(xplicit non-positi)-.15 F 1.081 +-.15(ve n)-.25 H .781(umeric ar).15 F .781 +(gument, switches to insert mode.)-.18 F .78(This command af)5.781 F +(fects)-.25 E(only)144 516 Q F1(emacs)4.394 E F0(mode;)4.394 E F1(vi) +4.394 E F0 1.894(mode does o)4.394 F -.15(ve)-.15 G 1.894(rwrite dif).15 +F(ferently)-.25 E 6.894(.E)-.65 G 1.894(ach call to)-6.894 F/F4 10 +/Times-Italic@0 SF -.37(re)4.395 G(adline\(\)).37 E F0 1.895 +(starts in insert)4.395 F 3.969(mode. In)144 528 R -.15(ove)3.969 G +1.469(rwrite mode, characters bound to).15 F F1(self\255insert)3.969 E +F0 1.468(replace the te)3.969 F 1.468(xt at point rather than)-.15 F +.957(pushing the te)144 540 R .957(xt to the right.)-.15 F .958 +(Characters bound to)5.957 F F1(backward\255delete\255char)3.458 E F0 +.958(replace the character)3.458 F(before point with a space.)144 552 Q +(By def)5 E(ault, this command is unbound.)-.1 E F1(Killing and Y)87 +568.8 Q(anking)-.85 E(kill\255line \(C\255k\))108 580.8 Q F0 +(Kill the te)144 592.8 Q(xt from point to the end of the line.)-.15 E F1 +(backward\255kill\255line \(C\255x Rubout\))108 604.8 Q F0(Kill backw) +144 616.8 Q(ard to the be)-.1 E(ginning of the line.)-.15 E F1 +(unix\255line\255discard \(C\255u\))108 628.8 Q F0(Kill backw)144 640.8 +Q(ard from point to the be)-.1 E(ginning of the line.)-.15 E +(The killed te)5 E(xt is sa)-.15 E -.15(ve)-.2 G 2.5(do).15 G 2.5(nt) +-2.5 G(he kill-ring.)-2.5 E F1(kill\255whole\255line)108 652.8 Q F0 +(Kill all characters on the current line, no matter where point is.)144 +664.8 Q F1(kill\255w)108 676.8 Q(ord \(M\255d\))-.1 E F0 1.308 +(Kill from point the end of the current w)144 688.8 R 1.308 +(ord, or if between w)-.1 F 1.308(ords, to the end of the ne)-.1 F 1.307 +(xt w)-.15 F(ord.)-.1 E -.8(Wo)144 700.8 S +(rd boundaries are the same as those used by).8 E F1 -.25(fo)2.5 G +(rward\255w).25 E(ord)-.1 E F0(.)A(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(7)195.95 E EP +%%Page: 8 8 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(backward\255kill\255w)108 84 Q(ord \(M\255Rubout\))-.1 +E F0(Kill the w)144 96 Q(ord behind point.)-.1 E -.8(Wo)5 G +(rd boundaries are the same as those used by).8 E F1(backward\255w)2.5 E +(ord)-.1 E F0(.)A F1(unix\255w)108 108 Q(ord\255rubout \(C\255w\))-.1 E +F0 .364(Kill the w)144 120 R .364 +(ord behind point, using white space as a w)-.1 F .365(ord boundary)-.1 +F 5.365(.T)-.65 G .365(he killed te)-5.365 F .365(xt is sa)-.15 F -.15 +(ve)-.2 G 2.865(do).15 G 2.865(nt)-2.865 G(he)-2.865 E(kill-ring.)144 +132 Q F1(delete\255horizontal\255space \(M\255\\\))108 144 Q F0 +(Delete all spaces and tabs around point.)144 156 Q F1(kill\255r)108 168 +Q(egion)-.18 E F0 1.13(Kill the te)144 180 R 1.13 +(xt between the point and)-.15 F/F2 10/Times-Italic@0 SF(mark)3.63 E F0 +(\(sa)3.63 E -.15(ve)-.2 G 3.63(dc).15 G 1.13(ursor position\).)-3.63 F +1.13(This te)6.13 F 1.13(xt is referred to as the)-.15 F F2 -.37(re)144 +192 S(gion)-.03 E F0(.)A F1(copy\255r)108 204 Q(egion\255as\255kill)-.18 +E F0(Cop)144 216 Q 2.5(yt)-.1 G(he te)-2.5 E(xt in the re)-.15 E +(gion to the kill b)-.15 E(uf)-.2 E(fer)-.25 E(.)-.55 E F1 +(copy\255backward\255w)108 228 Q(ord)-.1 E F0(Cop)144 240 Q 4.8(yt)-.1 G +2.3(he w)-4.8 F 2.3(ord before point to the kill b)-.1 F(uf)-.2 E(fer) +-.25 E 7.301(.T)-.55 G 2.301(he w)-7.301 F 2.301 +(ord boundaries are the same as)-.1 F F1(back-)4.801 E(ward\255w)144 252 +Q(ord)-.1 E F0(.)A F1(copy\255f)108 264 Q(orward\255w)-.25 E(ord)-.1 E +F0(Cop)144 276 Q 4.508(yt)-.1 G 2.008(he w)-4.508 F 2.008(ord follo)-.1 +F 2.008(wing point to the kill b)-.25 F(uf)-.2 E(fer)-.25 E 7.007(.T) +-.55 G 2.007(he w)-7.007 F 2.007(ord boundaries are the same as)-.1 F F1 +-.25(fo)4.507 G -.37(r-).25 G(ward\255w)144 288 Q(ord)-.1 E F0(.)A F1 +(yank \(C\255y\))108 300 Q F0 -1(Ya)144 312 S +(nk the top of the kill ring into the b)1 E(uf)-.2 E(fer at point.)-.25 +E F1(yank\255pop \(M\255y\))108 324 Q F0 +(Rotate the kill ring, and yank the ne)144 336 Q 2.5(wt)-.25 G 2.5 +(op. Only)-2.5 F -.1(wo)2.5 G(rks follo).1 E(wing)-.25 E F1(yank)2.5 E +F0(or)2.5 E F1(yank\255pop)2.5 E F0(.)A F1(Numeric Ar)87 352.8 Q +(guments)-.1 E(digit\255ar)108 364.8 Q +(gument \(M\2550, M\2551, ..., M\255\255\))-.1 E F0 .641 +(Add this digit to the ar)144 376.8 R .641 +(gument already accumulating, or start a ne)-.18 F 3.141(wa)-.25 G -.18 +(rg)-3.141 G 3.142(ument. M\255\255).18 F .642(starts a ne)3.142 F(g-) +-.15 E(ati)144 388.8 Q .3 -.15(ve a)-.25 H -.18(rg).15 G(ument.).18 E F1 +(uni)108 400.8 Q -.1(ve)-.1 G(rsal\255ar).1 E(gument)-.1 E F0 .779 +(This is another w)144 412.8 R .779(ay to specify an ar)-.1 F 3.279 +(gument. If)-.18 F .779(this command is follo)3.279 F .778 +(wed by one or more digits,)-.25 F 1.376 +(optionally with a leading minus sign, those digits de\214ne the ar)144 +424.8 R 3.876(gument. If)-.18 F 1.376(the command is fol-)3.876 F(lo)144 +436.8 Q 1.17(wed by digits, e)-.25 F -.15(xe)-.15 G(cuting).15 E F1(uni) +3.67 E -.1(ve)-.1 G(rsal\255ar).1 E(gument)-.1 E F0(ag)3.67 E 1.17 +(ain ends the numeric ar)-.05 F 1.17(gument, b)-.18 F 1.17(ut is other) +-.2 F(-)-.2 E .898(wise ignored.)144 448.8 R .898 +(As a special case, if this command is immediately follo)5.898 F .898 +(wed by a character that is)-.25 F .243 +(neither a digit or minus sign, the ar)144 460.8 R .243 +(gument count for the ne)-.18 F .243(xt command is multiplied by four) +-.15 F 5.242(.T)-.55 G(he)-5.242 E(ar)144 472.8 Q .378 +(gument count is initially one, so e)-.18 F -.15(xe)-.15 G .378 +(cuting this function the \214rst time mak).15 F .378(es the ar)-.1 F +.378(gument count)-.18 F(four)144 484.8 Q 2.5(,as)-.4 G(econd time mak) +-2.5 E(es the ar)-.1 E(gument count sixteen, and so on.)-.18 E F1 +(Completing)87 501.6 Q(complete \(T)108 513.6 Q(AB\))-.9 E F0 1.909 +(Attempt to perform completion on the te)144 525.6 R 1.908 +(xt before point.)-.15 F 1.908(The actual completion performed is)6.908 +F(application-speci\214c.)144 537.6 Q F1(Bash)5.517 E F0 3.017(,f)C .518 +(or instance, attempts completion treating the te)-3.017 F .518 +(xt as a v)-.15 F .518(ariable \(if the)-.25 F(te)144 549.6 Q .657 +(xt be)-.15 F .657(gins with)-.15 F F1($)3.156 E F0 .656 +(\), username \(if the te)B .656(xt be)-.15 F .656(gins with)-.15 F F1 +(~)3.156 E F0 .656(\), hostname \(if the te)B .656(xt be)-.15 F .656 +(gins with)-.15 F F1(@)3.156 E F0 .656(\), or)B .929 +(command \(including aliases and functions\) in turn.)144 561.6 R .93 +(If none of these produces a match, \214lename)5.929 F 1.274 +(completion is attempted.)144 573.6 R F1(Gdb)6.273 E F0 3.773(,o)C 3.773 +(nt)-3.773 G 1.273(he other hand, allo)-3.773 F 1.273 +(ws completion of program functions and)-.25 F -.25(va)144 585.6 S(riab\ +les, and only attempts \214lename completion under certain circumstance\ +s.).25 E F1(possible\255completions \(M\255?\))108 597.6 Q F0 +(List the possible completions of the te)144 609.6 Q(xt before point.) +-.15 E F1(insert\255completions \(M\255*\))108 621.6 Q F0 .783 +(Insert all completions of the te)144 633.6 R .783 +(xt before point that w)-.15 F .783(ould ha)-.1 F 1.083 -.15(ve b)-.2 H +.783(een generated by).15 F F1(possible\255com-)3.283 E(pletions)144 +645.6 Q F0(.)A F1(menu\255complete)108 657.6 Q F0 .929(Similar to)144 +669.6 R F1(complete)3.429 E F0 3.429(,b)C .929(ut replaces the w)-3.629 +F .929(ord to be completed with a single match from the list of)-.1 F +1.193(possible completions.)144 681.6 R 1.193(Repeated e)6.193 F -.15 +(xe)-.15 G 1.193(cution of).15 F F1(menu\255complete)3.694 E F0 1.194 +(steps through the list of possible)3.694 F .829 +(completions, inserting each match in turn.)144 693.6 R .828 +(At the end of the list of completions, the bell is rung)5.828 F .965 +(\(subject to the setting of)144 705.6 R F1 .965 +(0and the original text is r)3.465 F(estor)-.18 E 3.465(ed. An)-.18 F +(ar)3.465 E .966(gument of)-.1 F F2(n)3.466 E F1(mo)3.466 E -.1(ve)-.1 G +(s).1 E F2(n)3.466 E F1(posi-)3.466 E 1.249(tions f)144 717.6 R 1.249 +(orward in the list of matches; a negati)-.25 F 1.449 -.1(ve a)-.1 H -.1 +(rg).1 G 1.248(ument may be used to mo).1 F 1.448 -.1(ve b)-.1 H +(ackward).1 E(thr)144 729.6 Q(ough the list.)-.18 E +(This command is intended to be bound to T)5 E(AB, b)-.9 E +(ut is unbound by default.)-.2 E F0(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(8)195.95 E EP +%%Page: 9 9 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(delete\255char\255or\255list)108 84 Q F0 .373 +(Deletes the character under the cursor if not at the be)144 96 R .374 +(ginning or end of the line \(lik)-.15 F(e)-.1 E F1(delete-char)2.874 E +F0(\).)A(If at the end of the line, beha)144 108 Q -.15(ve)-.2 G 2.5(si) +.15 G(dentically to)-2.5 E F1(possible-completions)2.5 E F0(.)A F1 -.25 +(Ke)87 124.8 S(yboard Macr).25 E(os)-.18 E(start\255kbd\255macr)108 +136.8 Q 2.5(o\()-.18 G(C\255x \()-2.5 E(\)).833 E F0(Be)144 148.8 Q +(gin sa)-.15 E(ving the characters typed into the current k)-.2 E -.15 +(ey)-.1 G(board macro.).15 E F1(end\255kbd\255macr)108 160.8 Q 2.5(o\() +-.18 G(C\255x \))-2.5 E(\)).833 E F0(Stop sa)144 172.8 Q +(ving the characters typed into the current k)-.2 E -.15(ey)-.1 G +(board macro and store the de\214nition.).15 E F1 +(call\255last\255kbd\255macr)108 184.8 Q 2.5(o\()-.18 G(C\255x e\))-2.5 +E F0(Re-e)144 196.8 Q -.15(xe)-.15 G 1(cute the last k).15 F -.15(ey)-.1 +G .999(board macro de\214ned, by making the characters in the macro app\ +ear as if).15 F(typed at the k)144 208.8 Q -.15(ey)-.1 G(board.).15 E F1 +(Miscellaneous)87 225.6 Q -.18(re)108 237.6 S.18 E +(ead\255init\255\214le \(C\255x C\255r\))-.18 E F0 1.776 +(Read in the contents of the)144 249.6 R/F2 10/Times-Italic@0 SF(inputr) +4.276 E(c)-.37 E F0 1.777(\214le, and incorporate an)4.276 F 4.277(yb) +-.15 G 1.777(indings or v)-4.277 F 1.777(ariable assignments)-.25 F +(found there.)144 261.6 Q F1(abort \(C\255g\))108 273.6 Q F0 3.249 +(Abort the current editing command and ring the terminal')144 285.6 R +5.748(sb)-.55 G 3.248(ell \(subject to the setting of)-5.748 F F1 +(bell\255style)144 297.6 Q F0(\).)A F1(do\255upper)108 309.6 Q +(case\255v)-.18 E(ersion \(M\255a, M\255b, M\255)-.1 E F2(x)A F1 2.5(,.) +C(..\))-2.5 E F0 1.755(If the meta\214ed character)144 321.6 R F2(x) +4.255 E F0 1.755(is lo)4.255 F 1.756 +(wercase, run the command that is bound to the corresponding)-.25 F +(uppercase character)144 333.6 Q(.)-.55 E F1(pr)108 345.6 Q +(e\214x\255meta \(ESC\))-.18 E F0(Metafy the ne)144 357.6 Q +(xt character typed.)-.15 E/F3 9/Times-Bold@0 SF(ESC)5 E F1(f)2.25 E F0 +(is equi)2.5 E -.25(va)-.25 G(lent to).25 E F1(Meta\255f)2.5 E F0(.)A F1 +(undo \(C\255_, C\255x C\255u\))108 369.6 Q F0 +(Incremental undo, separately remembered for each line.)144 381.6 Q F1 +-2.29 -.18(re v)108 393.6 T(ert\255line \(M\255r\)).08 E F0 1.095 +(Undo all changes made to this line.)144 405.6 R 1.095(This is lik)6.095 +F 3.595(ee)-.1 G -.15(xe)-3.745 G 1.095(cuting the).15 F F1(undo)3.595 E +F0 1.095(command enough times to)3.595 F +(return the line to its initial state.)144 417.6 Q F1 +(tilde\255expand \(M\255&\))108 429.6 Q F0(Perform tilde e)144 441.6 Q +(xpansion on the current w)-.15 E(ord.)-.1 E F1 +(set\255mark \(C\255@, M\255\))108 453.6 Q F0 +(Set the mark to the point.)144 465.6 Q(If a numeric ar)5 E +(gument is supplied, the mark is set to that position.)-.18 E F1 +(exchange\255point\255and\255mark \(C\255x C\255x\))108 477.6 Q F0(Sw) +144 489.6 Q .282(ap the point with the mark.)-.1 F .283 +(The current cursor position is set to the sa)5.283 F -.15(ve)-.2 G +2.783(dp).15 G .283(osition, and the old)-2.783 F(cursor position is sa) +144 501.6 Q -.15(ve)-.2 G 2.5(da).15 G 2.5(st)-2.5 G(he mark.)-2.5 E F1 +(character\255sear)108 513.6 Q(ch \(C\255]\))-.18 E F0 3.036(Ac)144 +525.6 S .536(haracter is read and point is mo)-3.036 F -.15(ve)-.15 G +3.035(dt).15 G 3.035(ot)-3.035 G .535(he ne)-3.035 F .535 +(xt occurrence of that character)-.15 F 5.535(.A)-.55 G(ne)-2.5 E -.05 +(ga)-.15 G(ti).05 E .835 -.15(ve c)-.25 H(ount).15 E(searches for pre) +144 537.6 Q(vious occurrences.)-.25 E F1(character\255sear)108 549.6 Q +(ch\255backward \(M\255C\255]\))-.18 E F0 3.543(Ac)144 561.6 S 1.043 +(haracter is read and point is mo)-3.543 F -.15(ve)-.15 G 3.544(dt).15 G +3.544(ot)-3.544 G 1.044(he pre)-3.544 F 1.044 +(vious occurrence of that character)-.25 F 6.044(.A)-.55 G(ne)-2.5 E +-.05(ga)-.15 G(ti).05 E -.15(ve)-.25 G +(count searches for subsequent occurrences.)144 573.6 Q F1 +(insert\255comment \(M\255#\))108 585.6 Q F0 -.4(Wi)144 597.6 S .481 +(thout a numeric ar).4 F .481(gument, the v)-.18 F .481 +(alue of the readline)-.25 F F1(comment\255begin)2.981 E F0 -.25(va) +2.981 G .48(riable is inserted at the).25 F(be)144 609.6 Q .097 +(ginning of the current line.)-.15 F .098(If a numeric ar)5.097 F .098 +(gument is supplied, this command acts as a toggle:)-.18 F(if)5.098 E +.322(the characters at the be)144 621.6 R .321 +(ginning of the line do not match the v)-.15 F .321(alue of)-.25 F F1 +(comment\255begin)2.821 E F0 2.821(,t)C .321(he v)-2.821 F .321(alue is) +-.25 F 1.013(inserted, otherwise the characters in)144 633.6 R F1 +(comment-begin)3.514 E F0 1.014(are deleted from the be)3.514 F 1.014 +(ginning of the line.)-.15 F 1.469 +(In either case, the line is accepted as if a ne)144 645.6 R 1.468 +(wline had been typed.)-.25 F 1.468(The def)6.468 F 1.468(ault v)-.1 F +1.468(alue of)-.25 F F1(com-)3.968 E(ment\255begin)144 657.6 Q F0(mak) +2.982 E .483(es the current line a shell comment.)-.1 F .483 +(If a numeric ar)5.483 F .483(gument causes the comment)-.18 F +(character to be remo)144 669.6 Q -.15(ve)-.15 G(d, the line will be e) +.15 E -.15(xe)-.15 G(cuted by the shell.).15 E F1(dump\255functions)108 +681.6 Q F0 .627(Print all of the functions and their k)144 693.6 R .927 +-.15(ey b)-.1 H .626(indings to the readline output stream.).15 F .626 +(If a numeric ar)5.626 F(gu-)-.18 E +(ment is supplied, the output is formatted in such a w)144 705.6 Q +(ay that it can be made part of an)-.1 E F2(inputr)2.5 E(c)-.37 E F0 +(\214le.)2.5 E(GNU Readline 4.3)72 768 Q(2002 January 22)126.24 E(9) +195.95 E EP +%%Page: 10 10 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(dump\255v)108 84 Q(ariables)-.1 E F0 .283 +(Print all of the settable v)144 96 R .283(ariables and their v)-.25 F +.283(alues to the readline output stream.)-.25 F .283(If a numeric ar) +5.283 F(gu-)-.18 E +(ment is supplied, the output is formatted in such a w)144 108 Q +(ay that it can be made part of an)-.1 E/F2 10/Times-Italic@0 SF(inputr) +2.5 E(c)-.37 E F0(\214le.)2.5 E F1(dump\255macr)108 120 Q(os)-.18 E F0 +.756(Print all of the readline k)144 132 R 1.056 -.15(ey s)-.1 H .756 +(equences bound to macros and the strings the).15 F 3.256(yo)-.15 G +3.256(uput. If)-3.256 F 3.255(an)3.255 G(umeric)-3.255 E(ar)144 144 Q +.528(gument is supplied, the output is formatted in such a w)-.18 F .528 +(ay that it can be made part of an)-.1 F F2(inputr)3.028 E(c)-.37 E F0 +(\214le.)144 156 Q F1(emacs\255editing\255mode \(C\255e\))108 168 Q F0 +(When in)144 180 Q F1(vi)2.5 E F0(command mode, this causes a switch to) +2.5 E F1(emacs)2.5 E F0(editing mode.)2.5 E F1 +(vi\255editing\255mode \(M\255C\255j\))108 192 Q F0(When in)144 204 Q F1 +(emacs)2.5 E F0(editing mode, this causes a switch to)2.5 E F1(vi)2.5 E +F0(editing mode.)2.5 E/F3 10.95/Times-Bold@0 SF(DEF)72 220.8 Q -.548(AU) +-.986 G 2.014 -1.007(LT K).548 H(EY BINDINGS)1.007 E F0 .065(The follo) +108 232.8 R .065(wing is a list of the def)-.25 F .065 +(ault emacs and vi bindings.)-.1 F .064 +(Characters with the eighth bit set are written as)5.064 F .615 +(M\255, and are referred to as)108 244.8 R F2(meta\214ed) +3.115 E F0 3.115(characters. The)3.115 F .616 +(printable ASCII characters not mentioned)3.116 F 1.116 +(in the list of emacs standard bindings are bound to the)108 256.8 R F1 +(self\255insert)3.615 E F0 1.115(function, which just inserts the gi) +3.615 F -.15(ve)-.25 G(n).15 E .945(character into the input line.)108 +268.8 R .945(In vi insertion mode, all characters not speci\214cally me\ +ntioned are bound to)5.945 F F1(self\255insert)108 280.8 Q F0 5.359(.C)C +.359(haracters assigned to signal generation by)-5.359 F F2(stty)2.859 E +F0 .359(\(1\) or the terminal dri).32 F -.15(ve)-.25 G 1.159 -.4(r, s) +.15 H .358(uch as C-Z or C-C,).4 F .187(retain that function.)108 292.8 +R .187(Upper and lo)5.187 F .188(wer case meta\214ed characters are bou\ +nd to the same function in the emacs)-.25 F .305(mode meta k)108 304.8 R +-.15(ey)-.1 G 2.805(map. The).15 F .305(remaining characters are unboun\ +d, which causes readline to ring the bell \(subject)2.805 F +(to the setting of the)108 316.8 Q F1(bell\255style)2.5 E F0 -.25(va)2.5 +G(riable\).).25 E F1(Emacs Mode)87 333.6 Q F0(Emacs Standard bindings) +151.2 345.6 Q 2.5("C-@" set-mark)151.2 369.6 R 2.5("C-A" be)151.2 381.6 +R(ginning-of-line)-.15 E 2.5("C-B" backw)151.2 393.6 R(ard-char)-.1 E +2.5("C-D" delete-char)151.2 405.6 R 2.5("C-E" end-of-line)151.2 417.6 R +2.5("C-F" forw)151.2 429.6 R(ard-char)-.1 E 2.5("C-G" abort)151.2 441.6 +R 2.5("C-H" backw)151.2 453.6 R(ard-delete-char)-.1 E 2.5 +("C-I" complete)151.2 465.6 R 2.5("C-J" accept-line)151.2 477.6 R 2.5 +("C-K" kill-line)151.2 489.6 R 2.5("C-L" clear)151.2 501.6 R(-screen)-.2 +E 2.5("C-M" accept-line)151.2 513.6 R 2.5("C-N" ne)151.2 525.6 R +(xt-history)-.15 E 2.5("C-P" pre)151.2 537.6 R(vious-history)-.25 E 2.5 +("C-Q" quoted-insert)151.2 549.6 R 2.5("C-R" re)151.2 561.6 R -.15(ve) +-.25 G(rse-search-history).15 E 2.5("C-S" forw)151.2 573.6 R +(ard-search-history)-.1 E 2.5("C-T" transpose-chars)151.2 585.6 R 2.5 +("C-U" unix-line-discard)151.2 597.6 R 2.5("C-V" quoted-insert)151.2 +609.6 R 2.5("C-W" unix-w)151.2 621.6 R(ord-rubout)-.1 E 2.5("C-Y" yank) +151.2 633.6 R 2.5("C-]" character)151.2 645.6 R(-search)-.2 E 2.5 +("C-_" undo)151.2 657.6 R 3.333("")151.2 669.6 S(to "/")-.833 E +(self-insert)5 E 2.5("0" to)151.2 681.6 R 2.5("9" self-insert)2.5 F 2.5 +(":" to)151.2 693.6 R 2.5("~" self-insert)2.5 F 2.5("C-?" backw)151.2 +705.6 R(ard-delete-char)-.1 E(Emacs Meta bindings)151.2 722.4 Q +(GNU Readline 4.3)72 768 Q(2002 January 22)126.24 E(10)190.95 E EP +%%Page: 11 11 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R 2.5 +("M-C-G" abort)151.2 84 R 2.5("M-C-H" backw)151.2 96 R(ard-kill-w)-.1 E +(ord)-.1 E 2.5("M-C-I" tab-insert)151.2 108 R 2.5 +("M-C-J" vi-editing-mode)151.2 120 R 2.5("M-C-M" vi-editing-mode)151.2 +132 R 2.5("M-C-R" re)151.2 144 R -.15(ve)-.25 G(rt-line).15 E 2.5 +("M-C-Y" yank-nth-ar)151.2 156 R(g)-.18 E 2.5("M-C-[" complete)151.2 168 +R 2.5("M-C-]" character)151.2 180 R(-search-backw)-.2 E(ard)-.1 E 2.5 +("M-space" set-mark)151.2 192 R 2.5("M-#" insert-comment)151.2 204 R 2.5 +("M-&" tilde-e)151.2 216 R(xpand)-.15 E 2.5("M-*" insert-completions) +151.2 228 R 2.5("M--" digit-ar)151.2 240 R(gument)-.18 E 2.5 +("M-." yank-last-ar)151.2 252 R(g)-.18 E 2.5("M-0" digit-ar)151.2 264 R +(gument)-.18 E 2.5("M-1" digit-ar)151.2 276 R(gument)-.18 E 2.5 +("M-2" digit-ar)151.2 288 R(gument)-.18 E 2.5("M-3" digit-ar)151.2 300 R +(gument)-.18 E 2.5("M-4" digit-ar)151.2 312 R(gument)-.18 E 2.5 +("M-5" digit-ar)151.2 324 R(gument)-.18 E 2.5("M-6" digit-ar)151.2 336 R +(gument)-.18 E 2.5("M-7" digit-ar)151.2 348 R(gument)-.18 E 2.5 +("M-8" digit-ar)151.2 360 R(gument)-.18 E 2.5("M-9" digit-ar)151.2 372 R +(gument)-.18 E 2.5("M-<" be)151.2 384 R(ginning-of-history)-.15 E 2.5 +("M-=" possible-completions)151.2 396 R 2.5("M->" end-of-history)151.2 +408 R 2.5("M-?" possible-completions)151.2 420 R 2.5("M-B" backw)151.2 +432 R(ard-w)-.1 E(ord)-.1 E 2.5("M-C" capitalize-w)151.2 444 R(ord)-.1 E +2.5("M-D" kill-w)151.2 456 R(ord)-.1 E 2.5("M-F" forw)151.2 468 R(ard-w) +-.1 E(ord)-.1 E 2.5("M-L" do)151.2 480 R(wncase-w)-.25 E(ord)-.1 E 2.5 +("M-N" non-incremental-forw)151.2 492 R(ard-search-history)-.1 E 2.5 +("M-P" non-incremental-re)151.2 504 R -.15(ve)-.25 G(rse-search-history) +.15 E 2.5("M-R" re)151.2 516 R -.15(ve)-.25 G(rt-line).15 E 2.5 +("M-T" transpose-w)151.2 528 R(ords)-.1 E 2.5("M-U" upcase-w)151.2 540 R +(ord)-.1 E 2.5("M-Y" yank-pop)151.2 552 R 2.5 +("M-\\" delete-horizontal-space)151.2 564 R 2.5("M-~" tilde-e)151.2 576 +R(xpand)-.15 E 2.5("M-C-?" backw)151.2 588 R(ard-kill-w)-.1 E(ord)-.1 E +2.5("M-_" yank-last-ar)151.2 600 R(g)-.18 E(Emacs Control-X bindings) +151.2 616.8 Q 2.5("C-XC-G" abort)151.2 640.8 R 2.5 +("C-XC-R" re-read-init-\214le)151.2 652.8 R 2.5("C-XC-U" undo)151.2 +664.8 R 2.5("C-XC-X" e)151.2 676.8 R(xchange-point-and-mark)-.15 E 2.5 +("C-X\(" start-kbd-macro)151.2 688.8 R 2.5("C-X\)" end-kbd-macro)151.2 +700.8 R 2.5("C-XE" call-last-kbd-macro)151.2 712.8 R 2.5("C-XC-?" backw) +151.2 724.8 R(ard-kill-line)-.1 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(11)190.95 E EP +%%Page: 12 12 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 10 +/Times-Bold@0 SF(VI Mode bindings)87 84 Q F0(VI Insert Mode functions) +151.2 96 Q 2.5("C-D" vi-eof-maybe)151.2 120 R 2.5("C-H" backw)151.2 132 +R(ard-delete-char)-.1 E 2.5("C-I" complete)151.2 144 R 2.5 +("C-J" accept-line)151.2 156 R 2.5("C-M" accept-line)151.2 168 R 2.5 +("C-R" re)151.2 180 R -.15(ve)-.25 G(rse-search-history).15 E 2.5 +("C-S" forw)151.2 192 R(ard-search-history)-.1 E 2.5 +("C-T" transpose-chars)151.2 204 R 2.5("C-U" unix-line-discard)151.2 216 +R 2.5("C-V" quoted-insert)151.2 228 R 2.5("C-W" unix-w)151.2 240 R +(ord-rubout)-.1 E 2.5("C-Y" yank)151.2 252 R 2.5("C-[" vi-mo)151.2 264 R +-.15(ve)-.15 G(ment-mode).15 E 2.5("C-_" undo)151.2 276 R 3.333("")151.2 +288 S(to "~")-.833 E(self-insert)5 E 2.5("C-?" backw)151.2 300 R +(ard-delete-char)-.1 E(VI Command Mode functions)151.2 316.8 Q 2.5 +("C-D" vi-eof-maybe)151.2 340.8 R 2.5("C-E" emacs-editing-mode)151.2 +352.8 R 2.5("C-G" abort)151.2 364.8 R 2.5("C-H" backw)151.2 376.8 R +(ard-char)-.1 E 2.5("C-J" accept-line)151.2 388.8 R 2.5("C-K" kill-line) +151.2 400.8 R 2.5("C-L" clear)151.2 412.8 R(-screen)-.2 E 2.5 +("C-M" accept-line)151.2 424.8 R 2.5("C-N" ne)151.2 436.8 R(xt-history) +-.15 E 2.5("C-P" pre)151.2 448.8 R(vious-history)-.25 E 2.5 +("C-Q" quoted-insert)151.2 460.8 R 2.5("C-R" re)151.2 472.8 R -.15(ve) +-.25 G(rse-search-history).15 E 2.5("C-S" forw)151.2 484.8 R +(ard-search-history)-.1 E 2.5("C-T" transpose-chars)151.2 496.8 R 2.5 +("C-U" unix-line-discard)151.2 508.8 R 2.5("C-V" quoted-insert)151.2 +520.8 R 2.5("C-W" unix-w)151.2 532.8 R(ord-rubout)-.1 E 2.5("C-Y" yank) +151.2 544.8 R 2.5("C-_" vi-undo)151.2 556.8 R -4.166 3.333("" f)151.2 +568.8 T(orw)-3.333 E(ard-char)-.1 E 2.5("#" insert-comment)151.2 580.8 R +2.5("$" end-of-line)151.2 592.8 R 2.5("%" vi-match)151.2 604.8 R 2.5 +("&" vi-tilde-e)151.2 616.8 R(xpand)-.15 E 2.5("*" vi-complete)151.2 +628.8 R 2.5("+" ne)151.2 640.8 R(xt-history)-.15 E 2.5("," vi-char)151.2 +652.8 R(-search)-.2 E 2.5("-" pre)151.2 664.8 R(vious-history)-.25 E 2.5 +("." vi-redo)151.2 676.8 R 2.5("/" vi-search)151.2 688.8 R 2.5("0" be) +151.2 700.8 R(ginning-of-line)-.15 E("1" to "9")151.2 712.8 Q(vi-ar)5 E +(g-digit)-.18 E 2.5(";" vi-char)151.2 724.8 R(-search)-.2 E +(GNU Readline 4.3)72 768 Q(2002 January 22)126.24 E(12)190.95 E EP +%%Page: 13 13 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R 2.5 +("=" vi-complete)151.2 84 R 2.5("?" vi-search)151.2 96 R 2.5 +("A" vi-append-eol)151.2 108 R 2.5("B" vi-pre)151.2 120 R(v-w)-.25 E +(ord)-.1 E 2.5("C" vi-change-to)151.2 132 R 2.5("D" vi-delete-to)151.2 +144 R 2.5("E" vi-end-w)151.2 156 R(ord)-.1 E 2.5("F" vi-char)151.2 168 R +(-search)-.2 E 2.5("G" vi-fetch-history)151.2 180 R 2.5 +("I" vi-insert-be)151.2 192 R(g)-.15 E 2.5("N" vi-search-ag)151.2 204 R +(ain)-.05 E 2.5("P" vi-put)151.2 216 R 2.5("R" vi-replace)151.2 228 R +2.5("S" vi-subst)151.2 240 R 2.5("T" vi-char)151.2 252 R(-search)-.2 E +2.5("U" re)151.2 264 R -.15(ve)-.25 G(rt-line).15 E 2.5("W" vi-ne)151.2 +276 R(xt-w)-.15 E(ord)-.1 E 2.5("X" backw)151.2 288 R(ard-delete-char) +-.1 E 2.5("Y" vi-yank-to)151.2 300 R 2.5("\\" vi-complete)151.2 312 R +2.5("^" vi-\214rst-print)151.2 324 R 2.5("_" vi-yank-ar)151.2 336 R(g) +-.18 E 2.5("`" vi-goto-mark)151.2 348 R 2.5("a" vi-append-mode)151.2 360 +R 2.5("b" vi-pre)151.2 372 R(v-w)-.25 E(ord)-.1 E 2.5("c" vi-change-to) +151.2 384 R 2.5("d" vi-delete-to)151.2 396 R 2.5("e" vi-end-w)151.2 408 +R(ord)-.1 E 2.5("f" vi-char)151.2 420 R(-search)-.2 E 2.5("h" backw) +151.2 432 R(ard-char)-.1 E 2.5("i" vi-insertion-mode)151.2 444 R 2.5 +("j" ne)151.2 456 R(xt-history)-.15 E 2.5("k" pre)151.2 468 R(v-history) +-.25 E 2.5("l" forw)151.2 480 R(ard-char)-.1 E 2.5("m" vi-set-mark)151.2 +492 R 2.5("n" vi-search-ag)151.2 504 R(ain)-.05 E 2.5("p" vi-put)151.2 +516 R 2.5("r" vi-change-char)151.2 528 R 2.5("s" vi-subst)151.2 540 R +2.5("t" vi-char)151.2 552 R(-search)-.2 E 2.5("u" vi-undo)151.2 564 R +2.5("w" vi-ne)151.2 576 R(xt-w)-.15 E(ord)-.1 E 2.5("x" vi-delete)151.2 +588 R 2.5("y" vi-yank-to)151.2 600 R 2.5("|" vi-column)151.2 612 R 2.5 +("~" vi-change-case)151.2 624 R/F1 10.95/Times-Bold@0 SF(SEE ALSO)72 +640.8 Q/F2 10/Times-Italic@0 SF(The Gnu Readline Libr)108 652.8 Q(ary) +-.15 E F0 2.5(,B)C(rian F)-2.5 E(ox and Chet Rame)-.15 E(y)-.15 E F2 +(The Gnu History Libr)108 664.8 Q(ary)-.15 E F0 2.5(,B)C(rian F)-2.5 E +(ox and Chet Rame)-.15 E(y)-.15 E F2(bash)108 676.8 Q F0(\(1\))A F1 +(FILES)72 693.6 Q F2(~/.inputr)109.666 705.6 Q(c)-.37 E F0(Indi)144 +717.6 Q(vidual)-.25 E/F3 10/Times-Bold@0 SF -.18(re)2.5 G(adline).18 E +F0(initialization \214le)2.5 E(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(13)190.95 E EP +%%Page: 14 14 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 10/Times-Roman@0 SF 342.2(READLINE\(3\) READLINE\(3\))72 48 R/F1 +10.95/Times-Bold@0 SF -.548(AU)72 84 S(THORS).548 E F0(Brian F)108 96 Q +(ox, Free Softw)-.15 E(are F)-.1 E(oundation)-.15 E(bfox@gnu.or)108 108 +Q(g)-.18 E(Chet Rame)108 124.8 Q 1.3 -.65(y, C)-.15 H(ase W).65 E +(estern Reserv)-.8 E 2.5(eU)-.15 G(ni)-2.5 E -.15(ve)-.25 G(rsity).15 E +(chet@ins.CWR)108 136.8 Q(U.Edu)-.4 E F1 -.11(BU)72 153.6 S 2.738(GR).11 +G(EPOR)-2.738 E(TS)-.438 E F0 .69(If you \214nd a b)108 165.6 R .69 +(ug in)-.2 F/F2 10/Times-Bold@0 SF -.18(re)3.19 G(adline,).18 E F0 .69 +(you should report it.)3.19 F .691(But \214rst, you should mak)5.69 F +3.191(es)-.1 G .691(ure that it really is a b)-3.191 F(ug,)-.2 E +(and that it appears in the latest v)108 177.6 Q(ersion of the)-.15 E F2 +-.18(re)2.5 G(adline).18 E F0(library that you ha)2.5 E -.15(ve)-.2 G(.) +.15 E .705(Once you ha)108 194.4 R 1.005 -.15(ve d)-.2 H .705 +(etermined that a b).15 F .704(ug actually e)-.2 F .704(xists, mail a b) +-.15 F .704(ug report to)-.2 F/F3 10/Times-Italic@0 SF -.2(bu)3.204 G +(g\255r).2 E(eadline)-.37 E F0(@)A F3(gnu.or)A(g)-.37 E F0 5.704(.I)C +3.204(fy)-5.704 G(ou)-3.204 E(ha)108 206.4 Q 1.809 -.15(ve a \214)-.2 H +1.509(x, you are welcome to mail that as well!).15 F 1.51 +(Suggestions and `philosophical' b)6.51 F 1.51(ug reports may be)-.2 F +(mailed to)108 218.4 Q F3 -.2(bu)2.5 G(g-r).2 E(eadline)-.37 E F0(@)A F3 +(gnu.or)A(g)-.37 E F0(or posted to the Usenet ne)2.5 E(wsgroup)-.25 E F2 +(gnu.bash.b)2.5 E(ug)-.2 E F0(.)A(Comments and b)108 235.2 Q +(ug reports concerning this manual page should be directed to)-.2 E F3 +-.15(ch)2.5 G(et@ins.CWR).15 E -.25(U.)-.4 G(Edu).25 E F0(.).25 E F1 +-.11(BU)72 252 S(GS).11 E F0(It')108 264 Q 2.5(st)-.55 G +(oo big and too slo)-2.5 E -.65(w.)-.25 G(GNU Readline 4.3)72 768 Q +(2002 January 22)126.24 E(14)190.95 E EP +%%Trailer +end +%%EOF diff --git a/readline-doc-4.3/doc/rluserman.dvi b/readline-doc-4.3/doc/rluserman.dvi new file mode 100644 index 0000000..a2339aa Binary files /dev/null and b/readline-doc-4.3/doc/rluserman.dvi differ diff --git a/readline-doc-4.3/doc/rluserman.html b/readline-doc-4.3/doc/rluserman.html new file mode 100644 index 0000000..ac8bfbd --- /dev/null +++ b/readline-doc-4.3/doc/rluserman.html @@ -0,0 +1,2184 @@ + + + + + +GNU Readline Library: + + + + + + + + + + + + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    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. +

    + +

    + +
    1. Command Line Editing  GNU Readline User's Manual.
    +

    + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    + +

    1. Command Line Editing

    + +

    + +This chapter describes the basic features of the GNU +command line editing interface. +

    + +

    + + + + + +
    1.1 Introduction to Line Editing  Notation used in this text.
    1.2 Readline Interaction  The minimum set of commands for editing a line.
    1.3 Readline Init File  Customizing Readline from a user's view.
    1.4 Bindable Readline Commands  A description of most of the Readline commands + available for binding
    1.5 Readline vi Mode  A short description of how to make Readline + behave like the vi editor.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.1 Introduction to Line Editing

    + +

    + +The following paragraphs describe the notation used to represent +keystrokes. +

    + +The text C-k is read as `Control-K' and describes the character +produced when the k key is pressed while the Control key +is depressed. +

    + +The text M-k is read as `Meta-K' and describes the character +produced when the Meta key (if you have one) is depressed, and the k +key is pressed. +The Meta key is labeled ALT on many keyboards. +On keyboards with two keys labeled ALT (usually to either side of +the space bar), the ALT on the left side is generally set to +work as a Meta key. +The 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 ALT key, or another key working as +a Meta key, the identical keystroke can be generated by typing ESC +first, and then typing k. +Either process is known as metafying the k key. +

    + +The text M-C-k is read as `Meta-Control-k' and describes the +character produced by metafying C-k. +

    + +In addition, several keys have their own names. Specifically, +DEL, ESC, LFD, SPC, RET, and TAB all +stand for themselves when seen in this text, or in an init file +(see section 1.3 Readline Init File). +If your keyboard lacks a LFD key, typing C-j will +produce the desired character. +The RET key may be labeled Return or Enter on +some keyboards. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2 Readline Interaction

    + +

    + +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 RET. You do not have to be at the +end of the line to press RET; the entire line is accepted +regardless of the location of the cursor within the line. +

    + +

    + + + + + +
    1.2.1 Readline Bare Essentials  The least you need to know about Readline.
    1.2.2 Readline Movement Commands  Moving about the input line.
    1.2.3 Readline Killing Commands  How to delete text, and how to get it back!
    1.2.4 Readline Arguments  Giving numeric arguments to commands.
    1.2.5 Searching for Commands in the History  Searching through previous lines.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.1 Readline Bare Essentials

    + +

    + +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 C-b to move the cursor to the left, and then +correct your mistake. Afterwards, you can move the cursor to the right +with 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. +

    + +

    +
    C-b +
    Move back one character. +
    C-f +
    Move forward one character. +
    DEL or Backspace +
    Delete the character to the left of the cursor. +
    C-d +
    Delete the character underneath the cursor. +
    Printing characters +
    Insert the character into the line at the cursor. +
    C-_ or C-x C-u +
    Undo the last editing command. You can undo all the way back to an +empty line. +
    +

    + +(Depending on your configuration, the Backspace key be set to +delete the character to the left of the cursor and the DEL key set +to delete the character underneath the cursor, like C-d, rather +than the character to the left of the cursor.) +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.2 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 C-b, C-f, +C-d, and DEL. Here are some commands for moving more rapidly +about the line. +

    + +

    +
    C-a +
    Move to the start of the line. +
    C-e +
    Move to the end of the line. +
    M-f +
    Move forward a word, where a word is composed of letters and digits. +
    M-b +
    Move backward a word. +
    C-l +
    Clear the screen, reprinting the current line at the top. +
    +

    + +Notice how C-f moves forward a character, while M-f moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.3 Readline Killing Commands

    + +

    + + + +

    + +Killing text means to delete the text from the line, but to save +it away for later use, usually by 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 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. + +

    + +Here is the list of commands for killing text. +

    + +

    +
    C-k +
    Kill the text from the current cursor position to the end of the line. +

    + +

    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 M-f. +

    + +

    M-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 M-b. +

    + +

    C-w +
    Kill from the cursor to the previous whitespace. This is different than +M-DEL because the word boundaries differ. +

    + +

    +

    + +Here is how to yank the text back into the line. Yanking +means to copy the most-recently-killed text from the kill buffer. +

    + +

    +
    C-y +
    Yank the most recently killed text back into the buffer at the cursor. +

    + +

    M-y +
    Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is C-y or M-y. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.4 Readline Arguments

    + +

    + +You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the 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 `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 (`-'), 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 C-d command an argument of 10, you could type `M-1 0 C-d', +which will delete the next ten characters on the input line. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.2.5 Searching for Commands in the History

    + +

    + +Readline provides commands for searching through the command history +for lines containing a specified string. +There are two search modes: incremental and 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 +C-r. Typing C-s searches forward through the history. +The characters present in the value of the isearch-terminators variable +are used to terminate an incremental search. +If that variable has not been assigned a value, the ESC and +C-J characters will terminate an incremental search. +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 C-r or +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 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 +C-rs 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. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3 Readline Init File

    + +

    + +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 inputrc file, conventionally in his home directory. +The name of this +file is taken from the value of the environment variable INPUTRC. If +that variable is unset, the default is `~/.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 C-x C-r command re-reads this init file, thus +incorporating any changes that you might have made to it. +

    + +

    + +
    1.3.1 Readline Init File Syntax  Syntax for the commands in the inputrc file.
    + +
    + + +
    1.3.2 Conditional Init Constructs  Conditional key bindings in the inputrc file.
    + +
    + + +
    1.3.3 Sample Init File  An example inputrc file.
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.1 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 `#' are comments. +Lines beginning with a `$' indicate conditional +constructs (see section 1.3.2 Conditional Init Constructs). Other lines +denote variable settings and key bindings. +

    + +

    +
    Variable Settings +
    You can modify the run-time behavior of Readline by +altering the values of variables in Readline +using the set command within the init file. +The syntax is simple: +

    + +
     
    set variable value
    +

    + +Here, for example, is how to +change from the default Emacs-like key binding to use +vi line editing commands: +

    + +
     
    set editing-mode vi
    +

    + +Variable names and values, where appropriate, are recognized without regard +to case. +

    + +A great deal of run-time behavior is changeable with the following +variables. +

    + + +

    + +
    bell-style +
    +Controls what happens when Readline wants to ring the terminal bell. +If set to `none', Readline never rings the bell. If set to +`visible', Readline uses a visible bell if one is available. +If set to `audible' (the default), Readline attempts to ring +the terminal's bell. +

    + +

    comment-begin +
    +The string to insert at the beginning of the line when the +insert-comment command is executed. The default value +is "#". +

    + +

    completion-ignore-case +
    If set to `on', Readline performs filename matching and completion +in a case-insensitive fashion. +The default value is `off'. +

    + +

    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 100. +

    + +

    convert-meta +
    +If set to `on', Readline will convert characters with the +eighth bit set to an ASCII key sequence by stripping the eighth +bit and prefixing an ESC character, converting them to a +meta-prefixed key sequence. The default value is `on'. +

    + +

    disable-completion +
    +If set to `On', Readline will inhibit word completion. +Completion characters will be inserted into the line as if they had +been mapped to self-insert. The default is `off'. +

    + +

    editing-mode +
    +The 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 `emacs' or `vi'. +

    + +

    enable-keypad +
    +When set to `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 `off'. +

    + +

    expand-tilde +
    +If set to `on', tilde expansion is performed when Readline +attempts word completion. The default is `off'. +

    + + +If set to `on', the history code attempts to place point at the +same location on each history line retrived with previous-history +or next-history. +

    + +

    horizontal-scroll-mode +
    +This variable can be set to either `on' or `off'. Setting it +to `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 `off'. +

    + +

    input-meta +
    + +If set to `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 `off'. The name meta-flag is a +synonym for this variable. +

    + +

    isearch-terminators +
    +The string of characters that should terminate an incremental search without +subsequently executing the character as a command (see section 1.2.5 Searching for Commands in the History). +If this variable has not been given a value, the characters ESC and +C-J will terminate an incremental search. +

    + +

    keymap +
    +Sets Readline's idea of the current keymap for key binding commands. +Acceptable keymap names are +emacs, +emacs-standard, +emacs-meta, +emacs-ctlx, +vi, +vi-move, +vi-command, and +vi-insert. +vi is equivalent to vi-command; emacs is +equivalent to emacs-standard. The default value is emacs. +The value of the editing-mode variable also affects the +default keymap. +

    + +

    mark-directories +
    If set to `on', completed directory names have a slash +appended. The default is `on'. +

    + +

    mark-modified-lines +
    +This variable, when set to `on', causes Readline to display an +asterisk (`*') at the start of history lines which have been modified. +This variable is `off' by default. +

    + +

    mark-symlinked-directories +
    +If set to `on', completed names which are symbolic links +to directories have a slash appended (subject to the value of +mark-directories). +The default is `off'. +

    + +

    match-hidden-files +
    +This variable, when set to `on', causes Readline to match files whose +names begin with a `.' (hidden files) when performing filename +completion, unless the leading `.' is +supplied by the user in the filename to be completed. +This variable is `on' by default. +

    + +

    output-meta +
    +If set to `on', Readline will display characters with the +eighth bit set directly rather than as a meta-prefixed escape +sequence. The default is `off'. +

    + +

    page-completions +
    +If set to `on', Readline uses an internal more-like pager +to display a screenful of possible completions at a time. +This variable is `on' by default. +

    + +

    print-completions-horizontally +
    If set to `on', Readline will display completions with matches +sorted horizontally in alphabetical order, rather than down the screen. +The default is `off'. +

    + +

    show-all-if-ambiguous +
    +This alters the default behavior of the completion functions. If +set to `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 `off'. +

    + +

    visible-stats +
    +If set to `on', a character denoting a file's type +is appended to the filename when listing possible +completions. The default is `off'. +

    + +

    +

    + +

    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 macro). +

    + +

    +
    keyname: function-name or macro +
    keyname is the name of a key spelled out in English. For example: +
     
    Control-u: universal-argument
    +Meta-Rubout: backward-kill-word
    +Control-o: "> output"
    +

    + +In the above example, C-u is bound to the function +universal-argument, +M-DEL is bound to the function backward-kill-word, and +C-o is bound to run the macro +expressed on the right hand side (that is, to insert the text +`> output' into the line). +

    + +A number of symbolic character names are recognized while +processing this key binding syntax: +DEL, +ESC, +ESCAPE, +LFD, +NEWLINE, +RET, +RETURN, +RUBOUT, +SPACE, +SPC, +and +TAB. +

    + +

    "keyseq": function-name or macro +
    keyseq differs from keyname above in that strings +denoting an entire key sequence can be specified, by placing +the key sequence in double quotes. Some GNU Emacs style key +escapes can be used, as in the following example, but the +special character names are not recognized. +

    + +
     
    "\C-u": universal-argument
    +"\C-x\C-r": re-read-init-file
    +"\e[11~": "Function Key 1"
    +

    + +In the above example, C-u is again bound to the function +universal-argument (just as it was in the first example), +`C-x C-r' is bound to the function re-read-init-file, +and `ESC [ 1 1 ~' is bound to insert +the text `Function Key 1'. +

    + +

    +

    + +The following GNU Emacs style escape sequences are available when +specifying key sequences: +

    + +

    +
    \C- +
    control prefix +
    \M- +
    meta prefix +
    \e +
    an escape character +
    \\ +
    backslash +
    \" +
    ", a double quotation mark +
    \' +
    ', a single quote or apostrophe +
    +

    + +In addition to the GNU Emacs style escape sequences, a second +set of backslash escapes is available: +

    + +

    +
    \a +
    alert (bell) +
    \b +
    backspace +
    \d +
    delete +
    \f +
    form feed +
    \n +
    newline +
    \r +
    carriage return +
    \t +
    horizontal tab +
    \v +
    vertical tab +
    \nnn +
    the eight-bit character whose value is the octal value nnn +(one to three digits) +
    \xHH +
    the eight-bit character whose value is the hexadecimal value HH +(one or two hex digits) +
    +

    + +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 `"' and `''. +For example, the following binding will make `C-x \' +insert a single `\' into the line: +
     
    "\C-x\\": "\\"
    +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.2 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. +

    + +

    +
    $if +
    The $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. +

    + +

    +
    mode +
    The mode= form of the $if directive is used to test +whether Readline is in emacs or vi mode. +This may be used in conjunction +with the `set keymap' command, for instance, to set bindings in +the emacs-standard and emacs-ctlx keymaps only if +Readline is starting out in emacs mode. +

    + +

    term +
    The 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 +`=' is tested against both the full name of the terminal and +the portion of the terminal name before the first `-'. This +allows sun to match both sun and sun-cmd, +for instance. +

    + +

    application +
    The application construct is used to include +application-specific settings. Each program using the Readline +library sets the 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: +
     
    $if Bash
    +# Quote the current or previous word
    +"\C-xq": "\eb\"\ef\""
    +$endif
    +
    +

    + +

    $endif +
    This command, as seen in the previous example, terminates an +$if command. +

    + +

    $else +
    Commands in this branch of the $if directive are executed if +the test fails. +

    + +

    $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 `/etc/inputrc': +
     
    $include /etc/inputrc
    +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.3.3 Sample Init File

    + +

    + +Here is an example of an inputrc file. This illustrates key +binding, variable assignment, and conditional syntax. +

    + +
     
    # 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
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4 Bindable Readline Commands

    + +

    + +

    + + + + + + + + +
    1.4.1 Commands For Moving  Moving about the line.
    1.4.2 Commands For Manipulating The History  Getting at previous lines.
    1.4.3 Commands For Changing Text  Commands for changing text.
    1.4.4 Killing And Yanking  Commands for killing and yanking.
    1.4.5 Specifying Numeric Arguments  Specifying numeric arguments, repeat counts.
    1.4.6 Letting Readline Type For You  Getting Readline to do the typing for you.
    1.4.7 Keyboard Macros  Saving and re-executing typed characters
    1.4.8 Some Miscellaneous Commands  Other miscellaneous commands.
    +

    + +This section describes Readline commands that may be bound to key +sequences. +Command names without an accompanying key sequence are unbound by default. +

    + +In the following descriptions, point refers to the current cursor +position, and mark refers to a cursor position saved by the +set-mark command. +The text between the point and mark is referred to as the region. +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.1 Commands For Moving

    + +
    + +
    beginning-of-line (C-a) +
    +Move to the start of the current line. +

    + + +

    end-of-line (C-e) +
    +Move to the end of the line. +

    + + +

    forward-char (C-f) +
    +Move forward a character. +

    + + +

    backward-char (C-b) +
    +Move back a character. +

    + + +

    forward-word (M-f) +
    +Move forward to the end of the next word. Words are composed of +letters and digits. +

    + + +

    backward-word (M-b) +
    +Move back to the start of the current or previous word. Words are +composed of letters and digits. +

    + + +

    clear-screen (C-l) +
    +Clear the screen and redraw the current line, +leaving the current line at the top of the screen. +

    + + +

    redraw-current-line () +
    +Refresh the current line. By default, this is unbound. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.2 Commands For Manipulating The History

    + +

    + +

    + +
    accept-line (Newline or Return) +
    +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 +add_history(). +If this line is a modified history line, the history line is restored +to its original state. +

    + + +

    previous-history (C-p) +
    +Move `back' through the history list, fetching the previous command. +

    + + +

    next-history (C-n) +
    +Move `forward' through the history list, fetching the next command. +

    + + +

    beginning-of-history (M-<) +
    +Move to the first line in the history. +

    + + +

    end-of-history (M->) +
    +Move to the end of the input history, i.e., the line currently +being entered. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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 n, +insert the nth word from the previous command (the words +in the previous command begin with word 0). A negative argument +inserts the nth word from the end of the previous command. +

    + + +

    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 yank-nth-arg. +Successive calls to yank-last-arg move back through the history +list, inserting the last argument of each line in turn. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.3 Commands For Changing Text

    + +

    + +

    + +
    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 delete-char, then +return EOF. +

    + + +

    backward-delete-char (Rubout) +
    +Delete the character behind the cursor. A numeric argument means +to kill the characters instead of deleting them. +

    + + +

    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. +

    + + +

    quoted-insert (C-q or C-v) +
    +Add the next character typed to the line verbatim. This is +how to insert key sequences like C-q, for example. +

    + + +

    tab-insert (M-TAB) +
    +Insert a tab character. +

    + + +

    self-insert (a, b, A, 1, !, ...) +
    +Insert yourself. +

    + + +

    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. +

    + + +

    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. +

    + + +

    upcase-word (M-u) +
    +Uppercase the current (or following) word. With a negative argument, +uppercase the previous word, but do not move the cursor. +

    + + +

    downcase-word (M-l) +
    +Lowercase the current (or following) word. With a negative argument, +lowercase the previous word, but do not move the cursor. +

    + + +

    capitalize-word (M-c) +
    +Capitalize the current (or following) word. With a negative argument, +capitalize the previous word, but do not move the cursor. +

    + + +

    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 +emacs mode; vi mode does overwrite differently. +Each call to readline() starts in insert mode. +

    + +In overwrite mode, characters bound to self-insert replace +the text at point rather than pushing the text to the right. +Characters bound to backward-delete-char replace the character +before point with a space. +

    + +By default, this command is unbound. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.4 Killing And Yanking

    + +

    + +

    + + +
    kill-line (C-k) +
    +Kill the text from point to the end of the line. +

    + + +

    backward-kill-line (C-x Rubout) +
    +Kill backward to the beginning of the line. +

    + + +

    unix-line-discard (C-u) +
    +Kill backward from the cursor to the beginning of the current line. +

    + + +

    kill-whole-line () +
    +Kill all characters on the current line, no matter where point is. +By default, this is unbound. +

    + + +

    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 forward-word. +

    + + +

    backward-kill-word (M-DEL) +
    +Kill the word behind point. +Word boundaries are the same as backward-word. +

    + + +

    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. +

    + + +

    delete-horizontal-space () +
    +Delete all spaces and tabs around point. By default, this is unbound. +

    + + +

    kill-region () +
    +Kill the text in the current region. +By default, this command is unbound. +

    + + +

    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. +

    + + +

    copy-backward-word () +
    +Copy the word before point to the kill buffer. +The word boundaries are the same as backward-word. +By default, this command is unbound. +

    + + +

    copy-forward-word () +
    +Copy the word following point to the kill buffer. +The word boundaries are the same as forward-word. +By default, this command is unbound. +

    + + +

    yank (C-y) +
    +Yank the top of the kill ring into the buffer at point. +

    + + +

    yank-pop (M-y) +
    +Rotate the kill-ring, and yank the new top. You can only do this if +the prior command is yank or yank-pop. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.5 Specifying Numeric Arguments

    + +
    + + +
    digit-argument (M-0, M-1, ... M--) +
    +Add this digit to the argument already accumulating, or start a new +argument. M-- starts a negative argument. +

    + + +

    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 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. +
    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.6 Letting Readline Type For You

    + +

    + +

    + +
    complete (TAB) +
    +Attempt to perform completion on the text before point. +The actual completion performed is application-specific. +The default is filename completion. +

    + + +

    possible-completions (M-?) +
    +List the possible completions of the text before point. +

    + + +

    insert-completions (M-*) +
    +Insert all completions of the text before point that would have +been generated by possible-completions. +

    + + +

    menu-complete () +
    +Similar to complete, but replaces the word to be completed +with a single match from the list of possible completions. +Repeated execution of 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 bell-style) +and the original text is restored. +An argument of n moves 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 TAB, but is unbound +by default. +

    + + +

    delete-char-or-list () +
    +Deletes the character under the cursor if not at the beginning or +end of the line (like delete-char). +If at the end of the line, behaves identically to +possible-completions. +This command is unbound by default. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.7 Keyboard Macros

    + +
    + + +
    start-kbd-macro (C-x () +
    +Begin saving the characters typed into the current keyboard macro. +

    + + +

    end-kbd-macro (C-x )) +
    +Stop saving the characters typed into the current keyboard macro +and save the definition. +

    + + +

    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. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.4.8 Some Miscellaneous Commands

    + +
    + + +
    re-read-init-file (C-x C-r) +
    +Read in the contents of the inputrc file, and incorporate +any bindings or variable assignments found there. +

    + + +

    abort (C-g) +
    +Abort the current editing command and +ring the terminal's bell (subject to the setting of +bell-style). +

    + + +

    do-uppercase-version (M-a, M-b, M-x, ...) +
    +If the metafied character x is lowercase, run the command +that is bound to the corresponding uppercase character. +

    + + +

    prefix-meta (ESC) +
    +Metafy the next character typed. This is for keyboards +without a meta key. Typing `ESC f' is equivalent to typing +M-f. +

    + + +

    undo (C-_ or C-x C-u) +
    +Incremental undo, separately remembered for each line. +

    + + +

    revert-line (M-r) +
    +Undo all changes made to this line. This is like executing the undo +command enough times to get back to the beginning. +

    + + +

    tilde-expand (M-~) +
    +Perform tilde expansion on the current word. +

    + + +

    set-mark (C-@) +
    +Set the mark to the point. If a +numeric argument is supplied, the mark is set to that position. +

    + + +

    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. +

    + + +

    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. +

    + + +

    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. +

    + + +

    insert-comment (M-#) +
    +Without a numeric argument, the value of the 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 comment-begin, the value is inserted, otherwise +the characters in comment-begin are deleted from the beginning of +the line. +In either case, the line is accepted as if a newline had been typed. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    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 inputrc file. This command is unbound by default. +

    + + +

    emacs-editing-mode (C-e) +
    +When in vi command mode, this causes a switch to emacs +editing mode. +

    + + +

    vi-editing-mode (M-C-j) +
    +When in emacs editing mode, this causes a switch to vi +editing mode. +

    + +

    +

    + + +


    + + + + + + + + + + + +
    [ < ][ > ]   [ << ][ Up ][ >> ]         [Top][Contents][Index][ ? ]
    +

    1.5 Readline vi Mode

    + +

    + +While the Readline library does not have a full set of vi +editing functions, it does contain enough to allow simple editing +of the line. The Readline vi mode behaves as specified in +the POSIX 1003.2 standard. +

    + +In order to switch interactively between emacs and vi +editing modes, use the command M-C-j (bound to emacs-editing-mode +when in vi mode and to vi-editing-mode in emacs mode). +The Readline default is emacs mode. +

    + +When you enter a line in vi mode, you are already placed in +`insertion' mode, as if you had typed an `i'. Pressing ESC +switches you into `command' mode, where you can edit the text of the +line with the standard vi movement keys, move to previous +history lines with `k' and subsequent lines with `j', and +so forth. +

    + +


    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Table of Contents

    + +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    Short Table of Contents

    +
    +1. Command Line Editing +
    + +
    +
    + + + + + + +
    [Top][Contents][Index][ ? ]
    +

    About this document

    +This document was generated by Chet Ramey on June, 27 2002 +using texi2html +

    +The buttons in the navigation panels have the following meaning: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Button Name Go to From 1.2.3 go to
    + [ < ] +Back + +previous section in reading order + +1.2.2 +
    + [ > ] +Forward + +next section in reading order + +1.2.4 +
    + [ << ] +FastBack + +previous or up-and-previous section + +1.1 +
    + [ Up ] +Up + +up section + +1.2 +
    + [ >> ] +FastForward + +next or up-and-next section + +1.3 +
    + [Top] +Top + +cover (top) of document + +   +
    + [Contents] +Contents + +table of contents + +   +
    + [Index] +Index + +concept index + +   +
    + [ ? ] +About + +this page + +   +
    +

    +where the Example assumes that the current position +is at Subsubsection One-Two-Three of a document of +the following structure: +
      +
    • 1. Section One
    • +
        +
      • 1.1 Subsection One-One
      • +
          +
        • ...
        • +
        +
      • 1.2 Subsection One-Two
      • +
          +
        • 1.2.1 Subsubsection One-Two-One +
        • 1.2.2 Subsubsection One-Two-Two +
        • 1.2.3 Subsubsection One-Two-Three     +<== Current Position +
        • 1.2.4 Subsubsection One-Two-Four +
        +
      • 1.3 Subsection One-Three
      • +
          +
        • ...
        • +
        +
      • 1.4 Subsection One-Four
      • +
      +
    + +
    +
    + +This document was generated +by Chet Ramey on June, 27 2002 +using texi2html + + + diff --git a/readline-doc-4.3/doc/rluserman.info b/readline-doc-4.3/doc/rluserman.info new file mode 100644 index 0000000..3fccbd4 --- /dev/null +++ b/readline-doc-4.3/doc/rluserman.info @@ -0,0 +1,1260 @@ +This is rluserman.info, produced by makeinfo version 4.1 from +/usr/homes/chet/src/bash/readline-src/doc/rluserman.texinfo. + +INFO-DIR-SECTION Libraries +START-INFO-DIR-ENTRY +* RLuserman: (rluserman). The GNU readline library User's Manual. +END-INFO-DIR-ENTRY + + 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. + + 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. + + +File: rluserman.info, Node: Top, Next: Command Line Editing, Up: (dir) + +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. + + +File: rluserman.info, Node: Command Line Editing, Prev: Top, Up: Top + +Command Line Editing +******************** + + This chapter describes the basic features of the GNU command line +editing interface. + +* 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. + + +File: rluserman.info, Node: Introduction and Notation, Next: Readline Interaction, Up: Command Line Editing + +Introduction to Line Editing +============================ + + The following paragraphs describe the notation used to represent +keystrokes. + + The text `C-k' is read as `Control-K' and describes the character +produced when the key is pressed while the Control key is depressed. + + The text `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 is pressed. The Meta key is labeled on many keyboards. On +keyboards with two keys labeled (usually to either side of the +space bar), the on the left side is generally set to work as a +Meta key. The 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, or another key working as a +Meta key, the identical keystroke can be generated by typing +_first_, and then typing . Either process is known as "metafying" +the key. + + The text `M-C-k' is read as `Meta-Control-k' and describes the +character produced by "metafying" `C-k'. + + In addition, several keys have their own names. Specifically, +, , , , , and all stand for themselves +when seen in this text, or in an init file (*note Readline Init File::). +If your keyboard lacks a key, typing will produce the +desired character. The key may be labeled or on +some keyboards. + + +File: rluserman.info, Node: Readline Interaction, Next: Readline Init File, Prev: Introduction and Notation, Up: Command Line Editing + +Readline Interaction +==================== + + 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 . You do not have to be at the end of +the line to press ; 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. + + +File: rluserman.info, Node: Readline Bare Essentials, Next: Readline Movement Commands, Up: Readline Interaction + +Readline Bare Essentials +------------------------ + + 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 `C-b' to move the cursor to the left, and then correct your +mistake. Afterwards, you can move the cursor to the right with `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. + +`C-b' + Move back one character. + +`C-f' + Move forward one character. + + or + Delete the character to the left of the cursor. + +`C-d' + Delete the character underneath the cursor. + +Printing characters + Insert the character into the line at the cursor. + +`C-_' or `C-x C-u' + Undo the last editing command. You can undo all the way back to an + empty line. + +(Depending on your configuration, the key be set to delete +the character to the left of the cursor and the key set to delete +the character underneath the cursor, like `C-d', rather than the +character to the left of the cursor.) + + +File: rluserman.info, Node: Readline Movement Commands, Next: Readline Killing Commands, Prev: Readline Bare Essentials, Up: Readline Interaction + +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 `C-b', `C-f', `C-d', and +. Here are some commands for moving more rapidly about the line. + +`C-a' + Move to the start of the line. + +`C-e' + Move to the end of the line. + +`M-f' + Move forward a word, where a word is composed of letters and + digits. + +`M-b' + Move backward a word. + +`C-l' + Clear the screen, reprinting the current line at the top. + + Notice how `C-f' moves forward a character, while `M-f' moves +forward a word. It is a loose convention that control keystrokes +operate on characters while meta keystrokes operate on words. + + +File: rluserman.info, Node: Readline Killing Commands, Next: Readline Arguments, Prev: Readline Movement Commands, Up: Readline Interaction + +Readline Killing Commands +------------------------- + + "Killing" text means to delete the text from the line, but to save +it away for later use, usually by "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 "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. + + Here is the list of commands for killing text. + +`C-k' + Kill the text from the current cursor position to the end of the + line. + +`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 `M-f'. + +`M-' + 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 `M-b'. + +`C-w' + Kill from the cursor to the previous whitespace. This is + different than `M-' because the word boundaries differ. + + Here is how to "yank" the text back into the line. Yanking means to +copy the most-recently-killed text from the kill buffer. + +`C-y' + Yank the most recently killed text back into the buffer at the + cursor. + +`M-y' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `C-y' or `M-y'. + + +File: rluserman.info, Node: Readline Arguments, Next: Searching, Prev: Readline Killing Commands, Up: Readline Interaction + +Readline Arguments +------------------ + + You can pass numeric arguments to Readline commands. Sometimes the +argument acts as a repeat count, other times it is the 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 `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 (`-'), 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 `C-d' command an argument of 10, you could type `M-1 0 C-d', which +will delete the next ten characters on the input line. + + +File: rluserman.info, Node: Searching, Prev: Readline Arguments, Up: Readline Interaction + +Searching for Commands in the History +------------------------------------- + + Readline provides commands for searching through the command history +for lines containing a specified string. There are two search modes: +"incremental" and "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 `C-r'. Typing `C-s' searches +forward through the history. The characters present in the value of +the `isearch-terminators' variable are used to terminate an incremental +search. If that variable has not been assigned a value, the and +`C-J' characters will terminate an incremental search. `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 `C-r' or +`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 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 +`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. + + +File: rluserman.info, Node: Readline Init File, Next: Bindable Readline Commands, Prev: Readline Interaction, Up: Command Line Editing + +Readline Init File +================== + + 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 "inputrc" file, conventionally in his home +directory. The name of this file is taken from the value of the +environment variable `INPUTRC'. If that variable is unset, the default +is `~/.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 `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. + + +File: rluserman.info, Node: Readline Init File Syntax, Next: Conditional Init Constructs, Up: Readline Init File + +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 `#' are +comments. Lines beginning with a `$' indicate conditional constructs +(*note Conditional Init Constructs::). Other lines denote variable +settings and key bindings. + +Variable Settings + You can modify the run-time behavior of Readline by altering the + values of variables in Readline using the `set' command within the + init file. The syntax is simple: + + set VARIABLE VALUE + + Here, for example, is how to change from the default Emacs-like + key binding to use `vi' line editing commands: + + set editing-mode vi + + Variable names and values, where appropriate, are recognized + without regard to case. + + A great deal of run-time behavior is changeable with the following + variables. + + `bell-style' + Controls what happens when Readline wants to ring the + terminal bell. If set to `none', Readline never rings the + bell. If set to `visible', Readline uses a visible bell if + one is available. If set to `audible' (the default), + Readline attempts to ring the terminal's bell. + + `comment-begin' + The string to insert at the beginning of the line when the + `insert-comment' command is executed. The default value is + `"#"'. + + `completion-ignore-case' + If set to `on', Readline performs filename matching and + completion in a case-insensitive fashion. The default value + is `off'. + + `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 `100'. + + `convert-meta' + If set to `on', Readline will convert characters with the + eighth bit set to an ASCII key sequence by stripping the + eighth bit and prefixing an character, converting them + to a meta-prefixed key sequence. The default value is `on'. + + `disable-completion' + If set to `On', Readline will inhibit word completion. + Completion characters will be inserted into the line as if + they had been mapped to `self-insert'. The default is `off'. + + `editing-mode' + The `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 `emacs' or `vi'. + + `enable-keypad' + When set to `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 `off'. + + `expand-tilde' + If set to `on', tilde expansion is performed when Readline + attempts word completion. The default is `off'. + + If set to `on', the history code attempts to place point at + the same location on each history line retrived with + `previous-history' or `next-history'. + + `horizontal-scroll-mode' + This variable can be set to either `on' or `off'. Setting it + to `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 `off'. + + `input-meta' + If set to `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 `off'. The name `meta-flag' is a synonym + for this variable. + + `isearch-terminators' + The string of characters that should terminate an incremental + search without subsequently executing the character as a + command (*note Searching::). If this variable has not been + given a value, the characters and `C-J' will terminate + an incremental search. + + `keymap' + Sets Readline's idea of the current keymap for key binding + commands. Acceptable `keymap' names are `emacs', + `emacs-standard', `emacs-meta', `emacs-ctlx', `vi', `vi-move', + `vi-command', and `vi-insert'. `vi' is equivalent to + `vi-command'; `emacs' is equivalent to `emacs-standard'. The + default value is `emacs'. The value of the `editing-mode' + variable also affects the default keymap. + + `mark-directories' + If set to `on', completed directory names have a slash + appended. The default is `on'. + + `mark-modified-lines' + This variable, when set to `on', causes Readline to display an + asterisk (`*') at the start of history lines which have been + modified. This variable is `off' by default. + + `mark-symlinked-directories' + If set to `on', completed names which are symbolic links to + directories have a slash appended (subject to the value of + `mark-directories'). The default is `off'. + + `match-hidden-files' + This variable, when set to `on', causes Readline to match + files whose names begin with a `.' (hidden files) when + performing filename completion, unless the leading `.' is + supplied by the user in the filename to be completed. This + variable is `on' by default. + + `output-meta' + If set to `on', Readline will display characters with the + eighth bit set directly rather than as a meta-prefixed escape + sequence. The default is `off'. + + `page-completions' + If set to `on', Readline uses an internal `more'-like pager + to display a screenful of possible completions at a time. + This variable is `on' by default. + + `print-completions-horizontally' + If set to `on', Readline will display completions with matches + sorted horizontally in alphabetical order, rather than down + the screen. The default is `off'. + + `show-all-if-ambiguous' + This alters the default behavior of the completion functions. + If set to `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 `off'. + + `visible-stats' + If set to `on', a character denoting a file's type is + appended to the filename when listing possible completions. + The default is `off'. + +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 MACRO). + + KEYNAME: FUNCTION-NAME or MACRO + KEYNAME is the name of a key spelled out in English. For + example: + Control-u: universal-argument + Meta-Rubout: backward-kill-word + Control-o: "> output" + + In the above example, `C-u' is bound to the function + `universal-argument', `M-DEL' is bound to the function + `backward-kill-word', and `C-o' is bound to run the macro + expressed on the right hand side (that is, to insert the text + `> output' into the line). + + A number of symbolic character names are recognized while + processing this key binding syntax: DEL, ESC, ESCAPE, LFD, + NEWLINE, RET, RETURN, RUBOUT, SPACE, SPC, and TAB. + + "KEYSEQ": FUNCTION-NAME or MACRO + KEYSEQ differs from KEYNAME above in that strings denoting an + entire key sequence can be specified, by placing the key + sequence in double quotes. Some GNU Emacs style key escapes + can be used, as in the following example, but the special + character names are not recognized. + + "\C-u": universal-argument + "\C-x\C-r": re-read-init-file + "\e[11~": "Function Key 1" + + In the above example, `C-u' is again bound to the function + `universal-argument' (just as it was in the first example), + `C-x C-r' is bound to the function `re-read-init-file', and + ` <[> <1> <1> <~>' is bound to insert the text `Function + Key 1'. + + The following GNU Emacs style escape sequences are available when + specifying key sequences: + + `\C-' + control prefix + + `\M-' + meta prefix + + `\e' + an escape character + + `\\' + backslash + + `\"' + <">, a double quotation mark + + `\'' + <'>, a single quote or apostrophe + + In addition to the GNU Emacs style escape sequences, a second set + of backslash escapes is available: + + `\a' + alert (bell) + + `\b' + backspace + + `\d' + delete + + `\f' + form feed + + `\n' + newline + + `\r' + carriage return + + `\t' + horizontal tab + + `\v' + vertical tab + + `\NNN' + the eight-bit character whose value is the octal value NNN + (one to three digits) + + `\xHH' + the eight-bit character whose value is the hexadecimal value + HH (one or two hex digits) + + 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 `"' and `''. For example, + the following binding will make `C-x \' insert a single `\' into + the line: + "\C-x\\": "\\" + + +File: rluserman.info, Node: Conditional Init Constructs, Next: Sample Init File, Prev: Readline Init File Syntax, Up: Readline Init File + +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. + +`$if' + The `$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. + + `mode' + The `mode=' form of the `$if' directive is used to test + whether Readline is in `emacs' or `vi' mode. This may be + used in conjunction with the `set keymap' command, for + instance, to set bindings in the `emacs-standard' and + `emacs-ctlx' keymaps only if Readline is starting out in + `emacs' mode. + + `term' + The `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 + `=' is tested against both the full name of the terminal and + the portion of the terminal name before the first `-'. This + allows `sun' to match both `sun' and `sun-cmd', for instance. + + `application' + The APPLICATION construct is used to include + application-specific settings. Each program using the + Readline library sets the 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: + $if Bash + # Quote the current or previous word + "\C-xq": "\eb\"\ef\"" + $endif + +`$endif' + This command, as seen in the previous example, terminates an `$if' + command. + +`$else' + Commands in this branch of the `$if' directive are executed if the + test fails. + +`$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 `/etc/inputrc': + $include /etc/inputrc + + +File: rluserman.info, Node: Sample Init File, Prev: Conditional Init Constructs, Up: Readline Init File + +Sample Init File +---------------- + + Here is an example of an INPUTRC file. This illustrates key +binding, variable assignment, and conditional syntax. + + + # 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 + + +File: rluserman.info, Node: Bindable Readline Commands, Next: Readline vi Mode, Prev: Readline Init File, Up: Command Line Editing + +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. + + This section describes Readline commands that may be bound to key +sequences. Command names without an accompanying key sequence are +unbound by default. + + In the following descriptions, "point" refers to the current cursor +position, and "mark" refers to a cursor position saved by the +`set-mark' command. The text between the point and mark is referred to +as the "region". + + +File: rluserman.info, Node: Commands For Moving, Next: Commands For History, Up: Bindable Readline Commands + +Commands For Moving +------------------- + +`beginning-of-line (C-a)' + Move to the start of the current line. + +`end-of-line (C-e)' + Move to the end of the line. + +`forward-char (C-f)' + Move forward a character. + +`backward-char (C-b)' + Move back a character. + +`forward-word (M-f)' + Move forward to the end of the next word. Words are composed of + letters and digits. + +`backward-word (M-b)' + Move back to the start of the current or previous word. Words are + composed of letters and digits. + +`clear-screen (C-l)' + Clear the screen and redraw the current line, leaving the current + line at the top of the screen. + +`redraw-current-line ()' + Refresh the current line. By default, this is unbound. + + +File: rluserman.info, Node: Commands For History, Next: Commands For Text, Prev: Commands For Moving, Up: Bindable Readline Commands + +Commands For Manipulating The History +------------------------------------- + +`accept-line (Newline or Return)' + 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 `add_history()'. If this line is a modified history line, + the history line is restored to its original state. + +`previous-history (C-p)' + Move `back' through the history list, fetching the previous + command. + +`next-history (C-n)' + Move `forward' through the history list, fetching the next command. + +`beginning-of-history (M-<)' + Move to the first line in the history. + +`end-of-history (M->)' + Move to the end of the input history, i.e., the line currently + being entered. + +`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. + +`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. + +`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. + +`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. + +`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. + +`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. + +`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 N, + insert the Nth word from the previous command (the words in the + previous command begin with word 0). A negative argument inserts + the Nth word from the end of the previous command. + +`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 + `yank-nth-arg'. Successive calls to `yank-last-arg' move back + through the history list, inserting the last argument of each line + in turn. + + +File: rluserman.info, Node: Commands For Text, Next: Commands For Killing, Prev: Commands For History, Up: Bindable Readline Commands + +Commands For Changing Text +-------------------------- + +`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 `delete-char', then return EOF. + +`backward-delete-char (Rubout)' + Delete the character behind the cursor. A numeric argument means + to kill the characters instead of deleting them. + +`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. + +`quoted-insert (C-q or C-v)' + Add the next character typed to the line verbatim. This is how to + insert key sequences like `C-q', for example. + +`tab-insert (M-)' + Insert a tab character. + +`self-insert (a, b, A, 1, !, ...)' + Insert yourself. + +`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. + +`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. + +`upcase-word (M-u)' + Uppercase the current (or following) word. With a negative + argument, uppercase the previous word, but do not move the cursor. + +`downcase-word (M-l)' + Lowercase the current (or following) word. With a negative + argument, lowercase the previous word, but do not move the cursor. + +`capitalize-word (M-c)' + Capitalize the current (or following) word. With a negative + argument, capitalize the previous word, but do not move the cursor. + +`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 + `emacs' mode; `vi' mode does overwrite differently. Each call to + `readline()' starts in insert mode. + + In overwrite mode, characters bound to `self-insert' replace the + text at point rather than pushing the text to the right. + Characters bound to `backward-delete-char' replace the character + before point with a space. + + By default, this command is unbound. + + +File: rluserman.info, Node: Commands For Killing, Next: Numeric Arguments, Prev: Commands For Text, Up: Bindable Readline Commands + +Killing And Yanking +------------------- + +`kill-line (C-k)' + Kill the text from point to the end of the line. + +`backward-kill-line (C-x Rubout)' + Kill backward to the beginning of the line. + +`unix-line-discard (C-u)' + Kill backward from the cursor to the beginning of the current line. + +`kill-whole-line ()' + Kill all characters on the current line, no matter where point is. + By default, this is unbound. + +`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 `forward-word'. + +`backward-kill-word (M-)' + Kill the word behind point. Word boundaries are the same as + `backward-word'. + +`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. + +`delete-horizontal-space ()' + Delete all spaces and tabs around point. By default, this is + unbound. + +`kill-region ()' + Kill the text in the current region. By default, this command is + unbound. + +`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. + +`copy-backward-word ()' + Copy the word before point to the kill buffer. The word + boundaries are the same as `backward-word'. By default, this + command is unbound. + +`copy-forward-word ()' + Copy the word following point to the kill buffer. The word + boundaries are the same as `forward-word'. By default, this + command is unbound. + +`yank (C-y)' + Yank the top of the kill ring into the buffer at point. + +`yank-pop (M-y)' + Rotate the kill-ring, and yank the new top. You can only do this + if the prior command is `yank' or `yank-pop'. + + +File: rluserman.info, Node: Numeric Arguments, Next: Commands For Completion, Prev: Commands For Killing, Up: Bindable Readline Commands + +Specifying Numeric Arguments +---------------------------- + +`digit-argument (M-0, M-1, ... M--)' + Add this digit to the argument already accumulating, or start a new + argument. `M--' starts a negative argument. + +`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 `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. + + +File: rluserman.info, Node: Commands For Completion, Next: Keyboard Macros, Prev: Numeric Arguments, Up: Bindable Readline Commands + +Letting Readline Type For You +----------------------------- + +`complete ()' + Attempt to perform completion on the text before point. The + actual completion performed is application-specific. The default + is filename completion. + +`possible-completions (M-?)' + List the possible completions of the text before point. + +`insert-completions (M-*)' + Insert all completions of the text before point that would have + been generated by `possible-completions'. + +`menu-complete ()' + Similar to `complete', but replaces the word to be completed with + a single match from the list of possible completions. Repeated + execution of `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 + `bell-style') and the original text is restored. An argument of N + moves 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 , but is unbound by + default. + +`delete-char-or-list ()' + Deletes the character under the cursor if not at the beginning or + end of the line (like `delete-char'). If at the end of the line, + behaves identically to `possible-completions'. This command is + unbound by default. + + +File: rluserman.info, Node: Keyboard Macros, Next: Miscellaneous Commands, Prev: Commands For Completion, Up: Bindable Readline Commands + +Keyboard Macros +--------------- + +`start-kbd-macro (C-x ()' + Begin saving the characters typed into the current keyboard macro. + +`end-kbd-macro (C-x ))' + Stop saving the characters typed into the current keyboard macro + and save the definition. + +`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. + + +File: rluserman.info, Node: Miscellaneous Commands, Prev: Keyboard Macros, Up: Bindable Readline Commands + +Some Miscellaneous Commands +--------------------------- + +`re-read-init-file (C-x C-r)' + Read in the contents of the INPUTRC file, and incorporate any + bindings or variable assignments found there. + +`abort (C-g)' + Abort the current editing command and ring the terminal's bell + (subject to the setting of `bell-style'). + +`do-uppercase-version (M-a, M-b, M-X, ...)' + If the metafied character X is lowercase, run the command that is + bound to the corresponding uppercase character. + +`prefix-meta ()' + Metafy the next character typed. This is for keyboards without a + meta key. Typing ` f' is equivalent to typing `M-f'. + +`undo (C-_ or C-x C-u)' + Incremental undo, separately remembered for each line. + +`revert-line (M-r)' + Undo all changes made to this line. This is like executing the + `undo' command enough times to get back to the beginning. + +`tilde-expand (M-~)' + Perform tilde expansion on the current word. + +`set-mark (C-@)' + Set the mark to the point. If a numeric argument is supplied, the + mark is set to that position. + +`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. + +`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. + +`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. + +`insert-comment (M-#)' + Without a numeric argument, the value of the `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 `comment-begin', the value is inserted, otherwise the + characters in `comment-begin' are deleted from the beginning of + the line. In either case, the line is accepted as if a newline + had been typed. + +`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 INPUTRC + file. This command is unbound by default. + +`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 + INPUTRC file. This command is unbound by default. + +`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 + INPUTRC file. This command is unbound by default. + +`emacs-editing-mode (C-e)' + When in `vi' command mode, this causes a switch to `emacs' editing + mode. + +`vi-editing-mode (M-C-j)' + When in `emacs' editing mode, this causes a switch to `vi' editing + mode. + + +File: rluserman.info, Node: Readline vi Mode, Prev: Bindable Readline Commands, Up: Command Line Editing + +Readline vi Mode +================ + + While the Readline library does not have a full set of `vi' editing +functions, it does contain enough to allow simple editing of the line. +The Readline `vi' mode behaves as specified in the POSIX 1003.2 +standard. + + In order to switch interactively between `emacs' and `vi' editing +modes, use the command `M-C-j' (bound to emacs-editing-mode when in +`vi' mode and to vi-editing-mode in `emacs' mode). The Readline +default is `emacs' mode. + + When you enter a line in `vi' mode, you are already placed in +`insertion' mode, as if you had typed an `i'. Pressing switches +you into `command' mode, where you can edit the text of the line with +the standard `vi' movement keys, move to previous history lines with +`k' and subsequent lines with `j', and so forth. + + + +Tag Table: +Node: Top1208 +Node: Command Line Editing1604 +Node: Introduction and Notation2218 +Node: Readline Interaction3837 +Node: Readline Bare Essentials5025 +Node: Readline Movement Commands6807 +Node: Readline Killing Commands7765 +Node: Readline Arguments9675 +Node: Searching10712 +Node: Readline Init File12856 +Node: Readline Init File Syntax13918 +Node: Conditional Init Constructs24802 +Node: Sample Init File27328 +Node: Bindable Readline Commands30513 +Node: Commands For Moving31564 +Node: Commands For History32414 +Node: Commands For Text35273 +Node: Commands For Killing37988 +Node: Numeric Arguments39940 +Node: Commands For Completion41069 +Node: Keyboard Macros42602 +Node: Miscellaneous Commands43162 +Node: Readline vi Mode46512 + +End Tag Table diff --git a/readline-doc-4.3/doc/rluserman.ps b/readline-doc-4.3/doc/rluserman.ps new file mode 100644 index 0000000..b46417a --- /dev/null +++ b/readline-doc-4.3/doc/rluserman.ps @@ -0,0 +1,2001 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: rluserman.dvi +%%Pages: 24 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -D 300 -t letter -o rluserman.ps rluserman.dvi +%DVIPSParameters: dpi=300, compressed +%DVIPSSource: TeX output 2002.06.27:1354 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 300 300 (rluserman.dvi) +@start +%DVIPSBitmapFont: Fa cmbxti10 14.4 1 +/Fa 1 47 df<120E123FEA7F80A212FFA21300127E123C0909798815>46 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmbx12 13.14 46 +/Fb 46 122 df<123C127E12FFA4127E123C08087C8711>46 D<131C133C13FC12FFA212 +00B3AA387FFFFCA216237CA21F>49 D<48B4FC000713C0381E07F0383803F8386001FC38 +7C00FE12FE14FF147FA2127C003813FFC7FC14FEA2EB01FC14F8EB03F0EB07E01480EB0F +00131E5B1370EBE003EA01C038038007380700061206380FFFFE5A5A4813FCB5FCA21823 +7DA21F>I<48B4FC000713E0381E03F0383801F8003C13FC387E00FEA3123EEA1C010000 +13FCA2EB03F8EB07F0EB0FC03801FF00A2380007E0EB01F014F8EB00FC14FE14FFA21210 +127C12FEA214FEA2387C01FC007013F8383E07F0380FFFC00001130018237DA21F>I<14 +381478A214F81301130313071306130C131C13381330136013E0EA01C01380EA03005A12 +0E5A12185A12705AB612C0A2390001F800A790387FFFC0A21A237EA21F>I<0018130C00 +1F137CEBFFF814F014E014C01480EBFC000018C7FCA513FF001B13E0381F03F0381C00F8 +000813FCC7127EA3147FA2127812FCA3147E5A006013FC1270383801F8381E07E03807FF +C03801FE0018237DA21F>II<1230123C +003FB512C0A215804814005C5C38600018A200E05B485B5CC6485AA249C7FC1306130EA2 +5BA2133CA25BA213F8A41201A66C5A13601A257DA41F>II<141CA2143EA3147FA24A7EA39038019F +C0A29038031FE0140F01077FEB0607A2010C7F1403011C7FEB1801A2496C7EA2017FB5FC +A29039E0007F8049133FA2484880151F00038190C7120FA2486E7ED8FFF090B51280A229 +257EA42E>65 DI<9138FF8008010FEBF0 +1890393FC03C789039FE0006F8D801F81303484813014848130048481478121F48481438 +A2007F151890C8FCA2481500A97E16187F123FA26C6C1430120F6C6C14606C6C14C06C6C +EB0180D800FEEB070090383FC01E90380FFFF8010013C025257DA42C>I69 +DI72 DI75 +DIII82 +D<01FF1380000713E3380F80F7381E001F48130F481307140312F81401A27E91C7FCB4FC +EA7FE013FE383FFFE014F86C13FE00077F6C1480C67E010313C0EB003FEC0FE01407A200 +C01303A315C07E6C13076C14806CEB0F0038FFC03E38E3FFF838803FE01B257DA422>I< +007FB612F8A2397E00FE010078EC00780070153800601518A200E0151C160C5AA4C71400 +B3A390B512FEA226247EA32B>I89 +D97 +DIII<137F3803FFC03807C1F0380F80F8EA1F0048137C127E147E +12FEA2B512FEA248C7FCA3127EA214067E6C130C380F80183807E0703803FFE038007F80 +17187E971C>II<3901FF07C00007EBDFE0380F83F1EA1F01393E00F800 +007E7FA6003E5B6C485A380F83E0EBFFC0001190C7FC0030C8FCA21238123C383FFFE06C +13FC806C7F481480383C003F48EB0FC000F81307A4007CEB0F806CEB1F00381F807E3807 +FFF8C613C01B247E971F>II<120FEA1F80EA3FC0A4EA1F80EA0F00 +C7FCA7EA7FC0A2120FB3A2EAFFF8A20D277EA611>I107 DI<26FF80FE137F903A83FF81FFC03B0F8E0FC707E0019813CC903A9007E803F001 +A013F0A201C013E0AF3BFFFC7FFE3FFFA230187E9733>I<38FF80FE903883FF80390F8E +0FC0139890389007E013A0A213C0AF39FFFC7FFEA21F187E9722>II<38FFC1FCEBCFFF390FFC1FC09038F007E001 +C013F0140315F8140115FCA8EC03F8A215F0EBE0079038F00FE09038DC1F809038CFFF00 +EBC3F801C0C7FCA9EAFFFCA21E237F9722>I<38FF83E0EB8FF8380F8C7CEB90FC13B013 +A01478EBE0005BAEEAFFFEA216187F9719>114 D<3807F8C0EA1FFFEA3C07EA7001EAF0 +00A300FC1300B47EEA7FFC7F383FFF80000F13C0120338001FE01303EAC001A212E014C0 +EAF00338FC078038EFFF00EAC3FC13187E9718>I<13C0A41201A312031207120F121FB5 +12C0A2380FC000AC1460A63807E0C013E13801FF8038007E0013237FA218>I<39FFC07F +E0A2000F1307B0140FA200071317EBE0673903FFC7FE38007F071F187E9722>I<39FFF8 +0FF8A2390FC001C015803907E00300A26D5A00031306EBF80E0001130C13FC00005B13FE +EB7E30A26D5AA214E06D5AA26D5AA26DC7FCA21D187F9720>I<39FFF83FF0A2390FC00F +003807E00E6C6C5A6D5A6C6C5A00001360EB7EC06D5AA2131F6D7E497E80EB33F81361EB +E0FC3801C07E3803807F3907003F8048131F39FFC07FF8A21D187F9720>120 +D<39FFF80FF8A2390FC001C015803907E00300A26D5A00031306EBF80E0001130C13FC00 +005B13FEEB7E30A26D5AA214E06D5AA26D5AA26DC7FCA21306A25B1230EA781CEAFC185B +1370EA68E0EA7FC0001FC8FC1D237F9720>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmsl10 10.95 40 +/Fc 40 122 df45 D<1408140C141C143CA2147C147E149EA2EB +011EA21302801304A21308A20110138014071320A2EB7FFF90384007C0EB8003A2EA0100 +A21202EC01E01206001F130339FF801FFE1F207F9F22>65 D<0007B5FC3900F803C09038 +7801E0EC00F04913F8A515F03801E001EC03E015C0EC0F809038FFFE009038E00F803903 +C003C0EC01E015F0A21400A2485A1401A215E01403EC07C0390F000F80EC3E00B512F01D +1F7E9E20>II<0007B57E3900F801E09038780070 +81497F151E150E150FA348481480A6484814005DA3151E153E4848133C5DA25D4A5A4A5A +260F000FC7FC143CB512F0211F7E9E23>I<0007B512FC3900F8007C0178131C150C5B15 +04A414043901E00800A31438EBFFF8EBE0383803C010A4EC00081510485AA21520A21560 +15C0380F00011407B612801E1F7E9E1F>I<0007B512F83900F800780178133815185B15 +08A53901E00800A314181438EBFFF83803C0301410A491C7FC485AA648C8FC7FEAFFFC1D +1F7E9E1E>I<3A07FF83FFC03A00F8007C000178133CA2495BA648485BA490B5FCEBE000 +4848485AA64848485AA64848485A01807F39FFF07FF8221F7E9E22>72 +D<3807FF803800F8001378A25BA6485AA6485AA6485AA648C7FC7FEAFFF0111F7E9E10> +I<3A07FF803FE03A00F8001F000178130C5D4913205D5D4AC7FC1402140848485A5C1460 +14F013E1EBE4F83803C878EBD07CEBE03CEBC03E141E141F48487E81140781140381380F +00016D487E39FFF00FFE231F7E9E23>75 D<3807FFE0D800FCC7FC1378A25BA6485AA648 +5AA41580EC0100EA0780A25C14021406140E380F001E147CB512FC191F7E9E1C>I78 DI< +0007B5FC3900F803C090387800F015785B157CA41578484813F815F0EC01E0EC03C0EC0F +00EBFFFCD803C0C7FCA6485AA648C8FC7FEAFFF81E1F7E9E1F>I<3807FFFE3900F80780 +90387801E0EC00F05B15F8A415F03801E00115E0EC03C0EC0780EC1E00EBFFF03803C038 +80141E140EA2140F48485AA51501D80F0013029038800F8239FFF8078CC7EA01F020207E +9E22>82 DI<003FB512F0383C07800030 +1430126039400F0010A212C01280A3D8001E1300A65BA65BA65B7F383FFFE01C1F7A9E21 +>I<39FFF00FF8391F0003E06CEB01801400001EEB0100A6481302A6485BA600705BA25C +A200785B1238001813C06C48C7FCEA0706EA01F81D20799E22>I<3BFFF07FF81FF03B1F +000FC007C0001E903907800380001FED01006C1502140F5EEC17C002135B142301805C00 +0713435E14C3913883E0401481D981015B13C1D803C213E193C7FC13C415F2EBC80015F4 +EA01F015F85B5D5B15605B000014402C207A9E2F>87 D97 D<1207123F120F7EA2120EA65A137CEA1D83381E0180001C13C0EB00E05A14 +F0A5387001E0A214C013031480EB0700EAE80EEACC38EA83E014207B9F19>I<13FEEA03 +83380E0780121C0038130090C7FC12785AA45AA37E5BEA70026C5AEA1C18EA07E011147D +9314>I<13F8EA070EEA0E07381C038012381278127012F0B5FC00F0C7FCA25AA46C5AEA +7002EA3004EA1C18EA07E011147D9314>101 DI<140EEB +3E11EBE1A33801C1C2380381E0EA07801301120FA3380703C01480EB8700EA04FC48C7FC +A21218121CEA0FFF14C014E0381800F04813305A5AA3006013606C13C0381C0700EA07FC +181F809417>I105 D<13E0120712011200A2485AA6485AEB81FCEB +80F014C0EB81801400EA07045B13181338137C131C120E7FA2130F7F1480EA1C03381E07 +C038FF8FF016207E9F18>107 D<13E0120712011200A2EA01C0A6EA0380A6EA0700A612 +0EA65A121EEAFF800B207F9F0C>I<390387C07C391F9861863907A072073903C03403EB +80380007EB7807EB0070A5000EEBE00EA64848485A001EEBE01E3AFFCFFCFFC022147E93 +26>I<38038F80381F90E0EA07A03803C0601380000713E01300A5380E01C0A6381C0380 +001E13C038FF8FF014147E9319>I<13FCEA0387380E0180381C00C04813E0A24813F012 +F0A438E001E0A214C0130300F0138038700700EA380E6C5AEA07E014147D9317>IIIII<1380EA0100A35A5A5A121EEAFFF8EA0E00A45AA65A1310A41320A2 +EA1840EA0F800D1C7C9B12>I<381C0380EAFC1FEA3C07EA1C03A238380700A6EA700EA4 +131EA25BEA305E381F9F8011147B9319>I<38FF83F8381E00E0001C13C01480121E380E +01005B13025B12075BA25BEA039013A013E05B5B120190C7FC15147C9318>I<381FF0FF +3803C0780001137014403800E0C0EBE180EB73001376133CA2131C132E134E1387EA0107 +380203801204380C01C0383C03E038FE07FC18147F9318>120 D<390FF83F803901E00E +00EBC00C140813E000005B143014205C13705CA20171C7FC1339133A133E133C13381318 +1310A25BA25BEA70C0EAF08000F1C8FC12E61278191D809318>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd cmti10 10.95 8 +/Fd 8 117 df12 +D<127012F8A212F012E005057B840E>46 D103 D<13C0EA01E0A213C0C7FCA7120E12131223EA +4380EA4700A21287120EA35AA3EA38401380A21270EA31001232121C0B1F7C9E0E>105 +D<381C0F80382630C0384740601380EB0070A2008E13E0120EA3381C01C0A3EB03840038 +1388A2EB0708EB031000701330383001C016147C931A>110 D114 +D<13FCEA0302EA0601EA0C03130713061300EA0F8013F0EA07F8EA03FCEA003E130E1270 +EAF00CA2EAE008EA4010EA2060EA1F8010147D9313>II +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe cmr8 8 26 +/Fe 26 118 df<126012F0A212701210A21220A21240A2040A7D960A>39 +D45 D<1206120E12FE120EB1EAFFE00B157D9412>49 +D<13101338A3135CA3138EA3EA0107A238020380A33807FFC0EA0401A2380800E0A20018 +13F0123838FE03FE17177F961A>65 DIIIII76 D80 D82 +DI<387FFFF8386038180040 +1308A200801304A300001300AF3803FF8016177F9619>I<12FCA212C0B3AB12FCA20621 +7D980A>91 D97 D99 D101 D<1203EA0780A2EA0300C7FCA5 +EA1F801203AF1243EAE30012E7127C091D82960B>106 D<12F81238A8133E1338133013 +4013801239EA3FC0EA39E0123813F01378133CA2EAFE7F10177F9613>I110 D112 D114 DI<1208A31218A21238EAFFC0EA3800A7 +1340A4EA1C80EA0F000A147F930E>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmsy9 9 2 +/Ff 2 106 df<13801201EA0300A31206A25AA35AA35AA25AA35AA21260A37EA27EA37E +A37EA27EA3EA0180120009267D9B0F>104 D<12C0A21260A37EA27EA37EA37EA27EA3EA +0180A2EA0300A31206A25AA35AA35AA25AA35AA209267E9B0F>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg cmsltt10 10.95 29 +/Fg 29 122 df<1206120FEA1F80120FA21203EA0700A25A120E123C127C12F01260090E +769B18>39 D<387FFFC0B512E0A26C13C013047C8F18>45 D<133E13FF000313803807C3 +C0EA0F01000E13E0EA1C00123C003813F014705AA34813E0A4EB01C0A2130300F01380EA +7007EB0F00EA781E6C5AEA1FF85BEA07C0141C7C9B18>48 D<13181338A2137813F81203 +120F137012041200A413E0A6EA01C0A6EA7FFE12FF127F0F1C7B9B18>I67 D<3807FFC014E014F03801C0F814 +78143C141CEA0380141EA2140EA33807001CA4143C1438120E147014F0EB01E0EB03C013 +07387FFF8038FFFE00EA7FF8171C7F9B18>I<0007B5FC5A7E3801C007A3140638038000 +A2EB818014C0A213FF481380A21303A2140090C7FC120E140C141CA4387FFFF8B5FC7E18 +1C7F9B18>I74 D76 D<3907E01F80000FEB3FC0000714803903 +B02E00146EA214CE380730DC1331149CA21333141C000E5B13371336133E133C131848C6 +5AA638FE03F800FF7F00FE5B1A1C7F9B18>I<126012F0A37E1278A3127C123CA3123E12 +1EA3121F7EA313801207A313C01203A413E01201A313F0120013600C24789F18>92 +D<387FFFC0B512E0A26C13C013047E7F18>95 D97 D<127EA3120EA45A137CEA1DFF001F13801383381E01C0123CEB00E012 +38A4387801C0A2EB0380A2EB0F00EA7C1FEAFFFCEAEFF8EA63E0131C7C9B18>I100 D<13F8EA07FE487E381F +0780EA3C03387801C0127012E0A2B5FCA2148000E0C7FCA213033870078038780F00EA3F +FE6C5AEA07F012147B9318>III<14C0EB01E013031301EB00C01400A4EBFFC0A31301A2EB0380A6 +EB0700A6130EA65BA2EA6038EAF078B45A5BEA3F8013277F9C18>106 +DII<13FCEA03FF000F1380 +EA1F07383C03C0EA7801007013E0EAE000A4EB01C0A2EB0380EAF007EB0F00EA7C3EEA3F +FC6C5AEA07E013147C9318>111 D113 D<381FE1F8EBE7FCEBEFFE3800FE1EEBFC0C3801F8005B5B5BA3485AA6EA +FFFC7F5B17147E9318>II<387E07E0EAFE0FEA7E07EA0E00A2381C01C0A638380380A41307131F383FFF +E06C13F03807E3E014147D9318>117 D<38FF87F8138F1387383800E0EB01C0A3148013 +E3EA39F31233EB7700A212371376EA3666136EEA3C7CA2EA383815147C9318>119 +D<381FE3FC13E713E33803C3C000011380EBE700EA00EE13FC137C1338137813FCEA01DC +EA038E12071307120E38FF1FE0EB9FF0EB1FE016147E9318>I<380FF1FE381FF9FF380F +F1FE3803807013C0000113E0A213C114C0A23800E380A2EBE700A213E6136E136C137C13 +78A21370A25BA2485A12F3EAF780B4C7FC5A1278181E7F9318>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh cmcsc10 10.95 12 +/Fh 12 121 df<1318A2133CA3134EA213CF1387A238010380A2000313C0EA0201A23807 +FFE0EA0400A2481370A2001813380038137838FE01FF18177F961C>97 +D99 +D101 DII105 D<38FC01FC381E007014201217EA1380A2EA11C0EA10E0A213701338A2131C13 +0E1307A2EB03A0EB01E0A213001460123800FE132016177E961C>110 +D<13FE38038380380E00E0481370003C1378003813380078133C0070131C00F0131EA700 +70131C0078133C00381338003C1378001C13706C13E0380383803800FE0017177E961D> +II115 +D<38FF81FC381C00701420B0000C1340120E6C138038018300EA007C16177E961C>117 +D<38FF80FE381F0070000E13606C1340EB80803803C100EA01C3EA00E213F4137813387F +133E134E13C7EB8780380103C0EA0201380600E0000413F0000C1370003C137800FE13FF +18177F961C>120 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi cmbx12 17.28 18 +/Fi 18 117 df49 D<913A03FF800180023FEBF00349B5EAFC0701079038003F0FD91FF8EB +079FD93FC0EB01FFD9FF807F4848C8127F4848153F0007161F49150F485A001F1607A248 +5A1703127FA24992C7FCA212FFA9127FA27FEF0380123FA26C7E1707000F17006C7E6D15 +0E0003161E6C6C151C6C6C6C1478D93FC05CD91FF8EB03E0D907FFEB3F800101D9FFFEC7 +FCD9003F13F80203138031317CB03A>67 D69 +D76 D<007FB8FCA39039C00FF801D87E00EC003F007C82007882A200708200F01780 +A3481603A5C792C7FCB3AA017FB6FCA331307DAF38>84 D97 DI100 DII<90 +391FF007C09039FFFE3FE03A01F83F79F03907E00FC3000F14E19039C007E0E0001FECF0 +00A2003F80A5001F5CA2000F5CEBE00F00075C2603F83FC7FC3806FFFE380E1FF090C9FC +121EA2121F7F90B57E6C14F015FC6C806C801680000F15C0003FC7127F007EEC1FE0007C +140F00FC1407A4007EEC0FC0003E1580003F141FD80FC0EB7E003907F803FC0001B512F0 +D8001F90C7FC242F7E9F28>I105 D108 D<2703F007F8EB1FE000FFD93FFEEBFFF8913A783F01E0FC02C09038 +8300FE280FF1801FC6137F2607F30013CC01F602F8148001FC5CA3495CB3B500C3B5380F +FFFCA33E207D9F43>I<3903F007F800FFEB3FFEEC783F02C013803A0FF1801FC03807F3 +0001F614E013FCA35BB3B500C3B5FCA328207D9F2D>II<3801FF86000713FEEA1F00003C133E48131E140E12F8A36C90 +C7FCB47E13FC387FFFC06C13F0806C7F00077F00017FEA003F01001380143F0060131F00 +E0130FA27E15007E6C131E6C131C38FF807838F3FFF038C07F8019207D9F20>115 +D<131CA5133CA3137CA213FC120112031207381FFFFEB5FCA2D803FCC7FCB0EC0380A712 +01EC0700EA00FEEB7F0EEB3FFCEB07F0192E7FAD1F>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj cmsy10 10.95 1 +/Fj 1 14 df<14FE903807FFC090381F01F0903878003C01E0130ED80180130348C7EA01 +800006EC00C0481560A2481530481518A248150CA4481506A90060150CA46C1518A26C15 +306C1560A26C15C06CEC01806C6CEB0300D800E0130E0178133C90381F01F0903807FFC0 +D900FEC7FC272B7DA02E>13 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk cmbx12 14.4 39 +/Fk 39 122 df<123C127FEAFF80A213C0A3127F123E1200A2EA0180A3EA0300A2120612 +0E5A5A12100A157B8813>44 D<121C127FA2EAFF80A3EA7F00A2121C09097B8813>46 +D<130E131E137EEA07FE12FFA212F81200B3ABB512FEA317277BA622>49 +DII<140FA25C5C5C5C5BA2EB03 +BFEB073F130E131C133C1338137013E0EA01C0EA038012071300120E5A5A5A12F0B612F8 +A3C7EA7F00A890381FFFF8A31D277EA622>I<00181303381F801FEBFFFE5C5C5C14C091 +C7FC001CC8FCA7EB7FC0381DFFF8381F80FC381E003F1208C7EA1F8015C0A215E0A21218 +127C12FEA315C05A0078EB3F80A26CEB7F00381F01FE6CB45A000313F0C613801B277DA6 +22>I66 +D<91387FE003903907FFFC07011FEBFF0F90397FF00F9F9039FF0001FFD801FC7F484814 +7F4848143F4848141F485A160F485A1607127FA290C9FC5AA97E7F1607123FA26C7E160E +6C7E6C6C141C6C6C143C6C6C14786CB4EB01F090397FF007C0011FB512800107EBFE0090 +38007FF028297CA831>I69 DI73 +D76 DI82 +D<9038FF80600003EBF0E0000F13F8381F80FD383F001F003E1307481303A200FC1301A2 +14007EA26C140013C0EA7FFCEBFFE06C13F86C13FE80000714806C14C0C6FC010F13E0EB +007FEC1FF0140F140700E01303A46C14E0A26C13076C14C0B4EB0F80EBE03F39E3FFFE00 +00E15B38C01FF01C297CA825>I85 D87 D<3803FF80000F13F0381F01FC383F80FE147F801580EA1F00C7FCA4 +EB3FFF3801FC3FEA0FE0EA1F80EA3F00127E5AA4145F007E13DF393F839FFC381FFE0F38 +03FC031E1B7E9A21>97 DIIIII<90 +38FF80F00003EBE3F8390FC1FE1C391F007C7C48137E003EEB3E10007EEB3F00A6003E13 +3E003F137E6C137C380FC1F8380BFFE00018138090C8FC1238A2123C383FFFF814FF6C14 +C06C14E06C14F0121F383C0007007CEB01F8481300A4007CEB01F0A2003FEB07E0390FC0 +1F806CB5120038007FF01E287E9A22>II<1207EA0F80EA +1FC0EA3FE0A3EA1FC0EA0F80EA0700C7FCA7EAFFE0A3120FB3A3EAFFFEA30F2B7EAA12> +I108 D<26FFC07FEB1FC0903AC1FFC07FF0 +903AC307E0C1F8D80FC49038F101FC9039C803F20001D801FE7F01D05BA201E05BB03CFF +FE3FFF8FFFE0A3331B7D9A38>I<38FFC07E9038C1FF809038C30FC0D80FC413E0EBC807 +01D813F013D0A213E0B039FFFE3FFFA3201B7D9A25>II<38FFC1F0EBC7FC +EBC63E380FCC7F13D813D0A2EBF03EEBE000B0B5FCA3181B7F9A1B>114 +D<3803FE30380FFFF0EA3E03EA7800127000F01370A27E00FE1300EAFFE06CB4FC14C06C +13E06C13F0000713F8C6FCEB07FC130000E0137C143C7E14387E6C137038FF01E038E7FF +C000C11300161B7E9A1B>I<13E0A41201A31203A21207120F381FFFE0B5FCA2380FE000 +AD1470A73807F0E0000313C03801FF8038007F0014267FA51A>I<39FFE07FF0A3000F13 +07B2140FA2000713173903F067FF3801FFC738007F87201B7D9A25>I<39FFFC03FFA339 +0FF000F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0EA214 +9EEB3F9C14FC6D5AA26D5AA36D5AA26D5AA2201B7F9A23>I<3BFFFC7FFC1FFCA33B0FE0 +0FE001C02607F007EB0380A201F8EBF00700031600EC0FF801FC5C0001150EEC1FFC2600 +FE1C5B15FE9039FF387E3C017F1438EC787F6D486C5A16F0ECE01F011F5CA26D486C5AA2 +EC800701075CA22E1B7F9A31>I<39FFFC1FFEA33907F003803803F8079038FC0F003801 +FE1E00005BEB7F3814F86D5A6D5A130F806D7E130F497EEB3CFEEB38FFEB787F9038F03F +803901E01FC0D803C013E0EB800F39FFF03FFFA3201B7F9A23>I<39FFFC03FFA3390FF0 +00F0000714E07F0003EB01C0A2EBFC0300011480EBFE070000140013FFEB7F0EA2149EEB +3F9C14FC6D5AA26D5AA36D5AA26D5AA25CA21307003890C7FCEA7C0FEAFE0E131E131C5B +EA74F0EA3FE0EA0F8020277F9A23>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl cmtt10 10.95 77 +/Fl 77 127 df<127012F8B012701200A5127012F8A31270051C779B18>33 +DI +I<13C01201A3EA03F0EA0FFCEA3FFEEA7DCFEA71C738E1C38013C7A338F1C0001279123F +6C7EEA0FF8EA01FC13DE13CF13C73861C38012F1A212E1EBC7001271EA79DEEA3FFEEA1F +F8EA07E0EA01C0A3120011247D9F18>I<1238127CA2127E123E120EA3121CA2123812F8 +12F012C0070E789B18>39 D<137013F0EA01E0EA03C0EA0780EA0F00121E121C5AA25AA4 +5AA81270A47EA27E121E7EEA0780EA03C0EA01F0120013700C24799F18>I<126012F012 +787E7E7EEA07801203EA01C0A2EA00E0A41370A813E0A4EA01C0A2EA03801207EA0F0012 +1E5A5A5A12600C247C9F18>II<121C123E127E +127F123F121F1207120E121E127C12F81260080C788518>44 D<387FFFC0B512E0A26C13 +C013047E8F18>I<1230127812FCA2127812300606778518>I<1303EB0780A2130F14005B +131EA2133E133C137C1378A213F85B12015B12035BA212075B120F90C7FCA25A121E123E +123CA2127C127812F85AA2126011247D9F18>III<383FFF80A30038C7FCA8EA3BF8EA3FFE7F383C +0780383003C0EA0001EB00E0A2126012F0A238E001C0EA7003387C0F80383FFF00EA1FFC +EA03F0131C7E9B18>53 D<12E0B512E0A214C038E00380EB0700C65A131E131C5BA25B13 +F05BA2485AA3485AA448C7FCA7131D7E9C18>55 DI<1230127812 +FCA2127812301200A81230127812FCA2127812300614779318>58 +D<14C0EB03E01307EB1FC0EB3F80EBFE00485AEA07F0485AEA3F8048C7FC12FCA2127F6C +7EEA0FE06C7EEA01FC6C7EEB3F80EB1FC0EB07E01303EB00C013187E9918>60 +D<387FFFC0B512E0A26C13C0C8FCA4387FFFC0B512E0A26C13C0130C7E9318>I<126012 +F87E127F6C7EEA0FE06C7EEA01FC6C7EEB3F80EB1FC0EB07E0A2EB1FC0EB3F80EBFE0048 +5AEA07F0485AEA3F8048C7FC12FC5A126013187E9918>II<137CEA01FEEA07FF380F8780381E03C0EA3C1DEA387F3870FFE0EA71E313C1 +12E1EAE380A638E1C1C0127113E33870FF8038387F00EA3C1C381E00E0EA0F833807FFC0 +0001138038007E00131C7E9B18>I<137013F8A213D8A2EA01DCA3138CEA038EA4EA0707 +A5380FFF80A3EA0E03381C01C0A3387F07F000FF13F8007F13F0151C7F9B18>III +III<3801F1C0EA03FDEA0FFFEA1F0FEA1C03123813011270A290C7FC5AA5 +EB0FF0131F130F387001C0A213031238A2EA1C07EA1F0FEA0FFFEA03FDEA01F1141C7E9B +18>I<387F07F038FF8FF8387F07F0381C01C0A9EA1FFFA3EA1C01AA387F07F038FF8FF8 +387F07F0151C7F9B18>II<387F07F038FF87F8387F07F0381C03C0EB07801400130E131E5B13385B13F0 +121DA2EA1FB8A2131C121EEA1C0EA27FA2EB0380A2EB01C0387F03F038FF87F8387F03F0 +151C7F9B18>75 DI<38FC01F8EAFE +03A2383B06E0A4138EA2EA398CA213DCA3EA38D8A213F81370A21300A638FE03F8A3151C +7F9B18>I<387E07F038FF0FF8387F07F0381D81C0A313C1121CA213E1A313611371A213 +311339A31319A2131D130DA3EA7F07EAFF87EA7F03151C7F9B18>IIIII<3803F1C0EA1FFF5AEA7C0FEA7003EAE001A390C7FC12701278123FEA1FF0EA07FE +C67EEB0F80EB03C01301EB00E0A2126012E0130100F013C038F80780B5FCEBFE00EAE7F8 +131C7E9B18>I<387FFFF8B5FCA238E07038A400001300B2EA07FFA3151C7F9B18>I<38FF +83FEA3381C0070B36C13E0EA0F01380783C03803FF806C1300EA007C171C809B18>I<38 +FE03F8EAFF07EAFE03381C01C0EA1E03000E1380EA0F0700071300A2EA038EA2EA01DCA3 +EA00F8A21370A9EA01FC487E6C5A151C7F9B18>89 D91 D<126012F0A27E1278127C123CA2123E121E121F7EA27F12077F1203A27F +12017F12007F1378A2137C133C133E131EA2131F7F14801307A2EB030011247D9F18>I< +EAFFF8A3EA0038B3ACEAFFF8A30D247F9F18>I<387FFFC0B512E0A26C13C013047E7F18> +95 D97 D<127E12FE127E120EA5133EEB +FF80000F13C0EBC1E01380EB0070120E1438A6000F1370A2EB80E013C1EBFFC0000E1380 +38063E00151C809B18>IIIII<3801E1F03807FFF85A381E1E30381C0E00487EA5EA1C0EEA1E1EEA +1FFC5BEA39E00038C7FC7EEA1FFEEBFFC04813E0387801F038700070481338A4007813F0 +EA7E03381FFFC06C13803801FC00151F7F9318>I<127E12FE127E120EA5133EEBFF8000 +0F13C013C1EB80E01300120EAB387FC7FC38FFE7FE387FC7FC171C809B18>II<1338137CA31338 +1300A4EA0FFCA3EA001CB3A4EA6038EAF078EAFFF0EA7FE0EA3F800E277E9C18>I<127E +12FE127E120EA5EB3FF0A3EB0780EB0F00131E5B5B5BEA0FF87F139C130EEA0E0F7FEB03 +8014C0387FC7F812FF127F151C7F9B18>II< +38F9C1C038FFF7F013FF383E3E38EA3C3CA2EA3838AB38FE3E3EEB7E7EEB3E3E17148093 +18>IIII<3801F380EA07FBEA1FFFEA3E1FEA38 +0FEA7007A2EAE003A6EA7007A2EA380FEA3C1FEA1FFFEA0FFBEA03E3EA0003A7EB1FF0EB +3FF8EB1FF0151E7E9318>I<38FF0FC0EB3FE0EB7FF0EA07F0EBE060EBC0005BA290C7FC +A9EAFFFC7F5B14147E9318>II<48 +7E1203A4387FFFC0B5FCA238038000A9144014E0A33801C1C013FF6C1380EB3E0013197F +9818>I<387E07E0EAFE0FEA7E07EA0E00AC1301EA0F033807FFFC6C13FE3801FCFC1714 +809318>I<387F8FF000FF13F8007F13F0381C01C0380E0380A338070700A3138FEA038E +A3EA01DCA3EA00F8A2137015147F9318>I<38FF07F8138F1307383800E0A4381C01C013 +7113F9A213D9EA1DDD000D1380A3138DEA0F8FA23807070015147F9318>I<387F8FF013 +9F138F380F0700EA078EEA039EEA01DC13F81200137013F07FEA01DCEA039E138EEA0707 +000E1380387F8FF000FF13F8007F13F015147F9318>I<387F8FF000FF13F8007F13F038 +0E01C0EB0380A21207EB0700A2EA0387A2138EEA01CEA213CC120013DC1378A31370A313 +F05B1279EA7BC0EA7F806CC7FC121E151E7F9318>I<383FFFF05AA2387001E0EB03C0EB +078038000F00131E5B13F8485AEA03C0485A380F0070121E5A5AB512F0A314147F9318> +II<127CB4FC13C01203C67EAB7FEB7FC0EB3FE0A2EB7FC0EBF0005B +ABEA03C012FF90C7FC127C13247E9F18>125 DI E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm cmr10 10.95 71 +/Fm 71 123 df<90381F83E09038F06E303901C07878380380F8903800F03048EB7000A7 +B612803907007000B2383FE3FF1D20809F1B>11 D<133FEBE0C0EA01C0380381E0EA0701 +A290C7FCA6B512E0EA0700B2383FC3FC1620809F19>I<127012F812FCA212741204A312 +08A21210A212201240060E7C9F0D>39 D<13401380EA01005A12061204120C5AA2123812 +30A212701260A412E0AC1260A412701230A212381218A27E120412067E7EEA008013400A +2E7BA112>I<7E12407E12307E1208120C7EA212077EA213801201A413C0AC1380A41203 +1300A25A1206A25A120812185A12205A5A0A2E7EA112>I<127012F012F8A212781208A3 +1210A31220A21240050E7C840D>44 DI<127012F8A312700505 +7C840D>I48 D<13801203120F12F31203B3A6 +EA07C0EA7FFE0F1E7C9D17>III<1306A2130EA2131E132EA2134E138EA2 +EA010E1202A212041208A212101220A2124012C0B512F038000E00A7EBFFE0141E7F9D17 +>II<137C +EA0182EA0701380E0380EA0C0712183838030090C7FC12781270A2EAF1F0EAF21CEAF406 +EAF807EB0380A200F013C0A51270A214801238EB07001218EA0C0E6C5AEA01F0121F7E9D +17>I<1240387FFFE014C0A23840008038800100A21302485AA25B5BA25BA21360A213E0 +5B1201A41203A76C5A131F7E9D17>III<127012F8A3 +12701200AA127012F8A3127005147C930D>I<127012F8A312701200AA127012F012F8A2 +12781208A31210A31220A21240051D7C930D>I<5B497EA3497EA3EB09E0A3EB10F0A3EB +2078A3497EA2EBC03EEB801EA248B5FCEB000FA20002EB0780A348EB03C0A2120C001E14 +E039FF801FFE1F207F9F22>65 DI<90380FE0109038381C309038E002703803C00139078000F048C71270121E15305A +1510127C127800F81400A91278007C1410123CA26C1420A27E6C6C13406C6C13803900E0 +0300EB380CEB0FF01C217E9F21>IIII<90380FE02090387818609038E004E03803800238070001481300001E14 +60A25A1520127C127800F81400A7EC7FFCEC03E000781301127C123CA27EA27E7E380380 +023900E00460903878182090380FE0001E217D9F24>I<39FFF07FF8390F000780AD90B5 +FCEB0007AF39FFF07FF81D1F7E9E22>II<39FF +F007FC390F0003E0EC0180150014025C5C5C5C5C5C49C7FC5B497E130FEB13C0EB21E013 +41EB80F0EB0078A28080A280EC0780A2EC03C015E015F039FFF01FFE1F1F7E9E23>75 +DI +IIII82 +D<3803F040380C0CC0EA1803EA3001EA6000A212E01440A36C13007E127CEA7F80EA3FF8 +6CB4FC00071380C613C0EB1FE013031301EB00F014707EA46C136014E06C13C038F80180 +38C60300EA81FC14217E9F19>I<007FB512E038780F010060EB006000401420A200C014 +3000801410A400001400B3497E3803FFFC1C1F7E9E21>I<39FFF00FF8390F0003E0EC00 +80B3A46CEB01001380120314026C6C5A6C6C5AEB3830EB0FC01D207E9E22>I<39FFF003 +FE391F8000F86CC7126015206C6C1340A36C6C1380A2EBE00100011400A23800F002A213 +F8EB7804A26D5AA36D5AA2131F6D5AA2EB07C0A36D5AA36DC7FC1F207F9E22>I<3BFFF0 +7FF81FF03B1F000FC007C06C903907800180170015C001805C00071502EC09E013C00003 +5DEC19F01410D801E05CA2EC2078D800F05CA2EC403C01785CA2EC801E017C1460013C14 +4090383D000F133F6D5CA2011E1307010E91C7FCA2010C7F010413022C207F9E2F>I<39 +FFF001FF391F800078000F146012076D1340000314807F3901F001001200EBF802EB7C06 +EB3C04EB3E08131EEB1F10EB0FB0EB07A014E06D5AACEB3FFC201F7F9E22>89 +D<12FFA212C0B3B3A512FFA2082D7CA10D>91 D<12FFA21203B3B3A512FFA2082D80A10D +>93 D<120812101220A21240A21280A312B812FCA2127C1238060E7D9F0D>96 +DI<121C12FC121CAA137CEA1D87381E0180EB00 +C0001C13E01470A21478A6147014F014E0001E13C0381A018038198700EA107C15207E9F +19>IIII<137CEA01C6EA030F1207EA0E061300A7EAFFF0EA0E00B2EA7FE010 +20809F0E>I<14E03803E330EA0E3CEA1C1C38380E00EA780FA5EA380E6C5AEA1E38EA33 +E00020C7FCA21230A2EA3FFE381FFF8014C0383001E038600070481330A4006013606C13 +C0381C03803803FC00141F7F9417>I<121C12FC121CAA137C1386EA1D03001E1380A212 +1CAE38FF8FF014207E9F19>I<1238127CA31238C7FCA6121C12FC121CB1EAFF80091F7F +9E0C>I<13E0EA01F0A3EA00E01300A61370EA07F012001370B3A31260EAF06013C0EA61 +80EA3F000C28829E0E>I<121C12FC121CAAEB1FE0EB0780EB060013045B5B5B136013E0 +EA1DF0EA1E70EA1C38133C131C7F130F7F148014C038FF9FF014207E9F18>I<121C12FC +121CB3ABEAFF8009207F9F0C>I<391C3E03E039FCC30C30391D019018001EEBE01CA200 +1C13C0AE3AFF8FF8FF8021147E9326>IIII<3801F04038070CC0EA0E02EA1C03EA38011278127012F0A61270 +12781238EA1C03EA0C05EA0709EA01F1EA0001A8EB0FF8151D7F9318>III<1202A31206A2120EA2123EEAFFF8EA0E00AB1304A5EA07081203EA01F00E1C7F +9B12>I<381C0380EAFC1FEA1C03AE1307120CEA061B3803E3F014147E9319>I<38FF83F8 +383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8A21370A3 +132015147F9318>I<39FF9FE1FC393C078070391C030060EC8020000E1440A214C0D807 +04138014E0A239038861001471A23801D032143A143E3800E01CA2EB6018EB40081E147F +9321>I<38FF87F8381E03C0380E0180EB0300EA0702EA0384EA01C813D8EA00F0137013 +7813F8139CEA010E1202EA060738040380000C13C0003C13E038FE07FC16147F9318>I< +38FF83F8383E00E0001C13C06C1380A338070100A21383EA0382A2EA01C4A213E4EA00E8 +A21370A31320A25BA3EAF080A200F1C7FC1262123C151D7F9318>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn cmbx12 20.736 19 +/Fn 19 122 df71 D73 +D76 D78 D82 +D85 D97 D<13FE12FFA412071203B04AB4 +FC021F13F0027F13FC9138FC03FE9039FFF000FF02C0EB3F8091C7EA1FC04915E0EE0FF0 +17F8A2EE07FCA317FEA917FCA3160F17F817F0161F6D15E06EEB3FC06EEB7F80D9F9E0EB +FF009039F0FC07FE91387FFFF8D9E01F13E09026C003FEC7FC2F3C7DBB36>I<903801FF +F0010F13FE013FEBFF809039FF801FC03901FE003F4848EB7FE0485A485A121F4848EB3F +C0ED1F80007FEC0F004990C7FCA212FFAA127F7FA2123F6D14F0121F6C6CEB01E012076C +6CEB03C06CB4EB0F806C9038C03F0090383FFFFE010F13F8010113C024267DA52B>II<49B47E01 +0F13F0017F13FC9038FF81FE3A03FE007F80D807F8133F4848EB1FC0ED0FE0485A003F15 +F01507485A16F8A212FFA290B6FCA301C0C8FCA4127FA36C7E1678121F7F000F15F06C6C +13016C6CEB03E06C6CEB0FC03A00FFC07F8090393FFFFE00010F13F8010013C025267DA5 +2C>II< +EA01E0EA07F8487EA2487EA46C5AA26C5AEA01E0C8FCAB13FE127FA412071203B3AAB512 +F0A4143D7DBC1A>105 D<13FE12FFA412071203B3B3AEB512F8A4153C7DBB1A>108 +D110 +D<3901FC03F000FFEB0FFC4AB4FC91383C3F80EC707F00079038E0FFC000035BEBFD80A2 +01FFEB7F809138003F00151E92C7FC5BB3A3B512FCA422267DA528>114 +D<90383FF0383903FFFE7848EBFFF8381FC00F383F0003003E13005A157812FCA27E6C14 +0013C013FC387FFFF06C13FEECFF806C14C06C14E0000314F0C614F8011F13FCEB007FEC +07FE0070130100F01300157E7EA27E157C6C14FC6C14F890388001F09038F00FE000F9B5 +12C0D8F07F130038C01FF81F267DA526>I<130FA55BA45BA25BA25B5A5A5A001FEBFFF0 +B6FCA3000190C7FCB3153CA86C14781480017F13F090383FC1E090381FFFC06D13809038 +01FE001E377EB626>I121 D E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin +%%BeginPaperSize: Letter +letter +%%EndPaperSize + +%%EndSetup +%%Page: 1 1 +1 0 bop 75 659 a Fn(GNU)33 b(Readline)h(Library)e(User)h(In)m(terface)p +75 709 1800 17 v 936 757 a Fm(Edition)17 b(4.3,)c(for)i +Fl(Readline)f(Library)g Fm(V)l(ersion)i(4.3.)1643 811 +y(Marc)o(h)e(2002)75 2467 y Fk(Brian)23 b(F)-6 b(o)n(x,)23 +b(F)-6 b(ree)23 b(Soft)n(w)n(are)f(F)-6 b(oundation)75 +2534 y(Chet)22 b(Ramey)-6 b(,)23 b(Case)e(W)-6 b(estern)23 +b(Reserv)n(e)f(Univ)n(ersit)n(y)p 75 2570 1800 9 v eop +%%Page: 2 2 +2 1 bop 75 217 a Fm(This)22 b(do)q(cumen)o(t)f(describ)q(es)i(the)f +(end)f(user)h(in)o(terface)f(of)g(the)g(GNU)g(Readline)i(Library)l(,)g +(a)e(utilit)o(y)75 271 y(whic)o(h)14 b(aids)f(in)g(the)g(consistency)h +(of)e(user)h(in)o(terface)g(across)f(discrete)h(programs)f(that)g(need) +h(to)f(pro)o(vide)75 326 y(a)j(command)g(line)i(in)o(terface.)75 +394 y(Published)g(b)o(y)f(the)f(F)l(ree)g(Soft)o(w)o(are)f(F)l +(oundation)75 448 y(59)h(T)l(emple)h(Place,)f(Suite)i(330,)75 +503 y(Boston,)d(MA)h(02111)f(USA)75 570 y(P)o(ermission)j(is)f(gran)o +(ted)g(to)f(mak)o(e)h(and)g(distribute)i(v)o(erbatim)d(copies)i(of)f +(this)h(man)o(ual)f(pro)o(vided)h(the)75 625 y(cop)o(yrigh)o(t)e +(notice)h(and)f(this)h(p)q(ermission)g(notice)g(are)f(preserv)o(ed)h +(on)f(all)h(copies.)75 692 y(P)o(ermission)c(is)h(gran)o(ted)e(to)g +(cop)o(y)h(and)g(distribute)h(mo)q(di\014ed)g(v)o(ersions)f(of)f(this)h +(man)o(ual)g(under)h(the)f(con-)75 747 y(ditions)k(for)e(v)o(erbatim)h +(cop)o(ying,)g(pro)o(vided)h(that)e(the)h(en)o(tire)h(resulting)g +(deriv)o(ed)g(w)o(ork)e(is)h(distributed)75 802 y(under)h(the)f(terms)g +(of)g(a)f(p)q(ermission)j(notice)f(iden)o(tical)h(to)e(this)g(one.)75 +869 y(P)o(ermission)i(is)g(gran)o(ted)f(to)g(cop)o(y)h(and)f +(distribute)i(translations)f(of)f(this)h(man)o(ual)g(in)o(to)f(another) +g(lan-)75 924 y(guage,)e(under)h(the)f(ab)q(o)o(v)o(e)g(conditions)i +(for)d(mo)q(di\014ed)j(v)o(ersions,)e(except)h(that)f(this)h(p)q +(ermission)g(notice)75 979 y(ma)o(y)f(b)q(e)i(stated)f(in)h(a)f +(translation)g(appro)o(v)o(ed)g(b)o(y)g(the)g(F)l(ree)h(Soft)o(w)o(are) +d(F)l(oundation.)75 2661 y(Cop)o(yrigh)o(t)301 2660 y(c)289 +2661 y Fj(\015)h Fm(1988-2002)f(F)l(ree)i(Soft)o(w)o(are)f(F)l +(oundation,)h(Inc.)p eop +%%Page: 1 3 +1 2 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(1)75 149 y Fi(1)41 b(Command)28 b(Line)e(Editing)137 +271 y Fm(This)16 b(c)o(hapter)f(describ)q(es)i(the)e(basic)h(features)f +(of)g(the)g Fh(gnu)g Fm(command)g(line)i(editing)f(in)o(terface.)75 +403 y Fk(1.1)33 b(In)n(tro)r(duction)24 b(to)e(Line)i(Editing)137 +501 y Fm(The)16 b(follo)o(wing)g(paragraphs)e(describ)q(e)j(the)e +(notation)g(used)h(to)e(represen)o(t)i(k)o(eystrok)o(es.)137 +569 y(The)h(text)f Fg(C-k)h Fm(is)g(read)g(as)f(`Con)o(trol-K')g(and)h +(describ)q(es)h(the)f(c)o(haracter)f(pro)q(duced)h(when)h(the)1831 +567 y Ff(h)p 1844 541 19 2 v 1844 569 a Fe(k)p 1844 577 +V 1860 567 a Ff(i)75 624 y Fm(k)o(ey)d(is)h(pressed)g(while)g(the)f +(Con)o(trol)g(k)o(ey)g(is)h(depressed.)137 693 y(The)g(text)g +Fg(M-k)f Fm(is)i(read)f(as)f(`Meta-K')g(and)h(describ)q(es)i(the)e(c)o +(haracter)f(pro)q(duced)i(when)g(the)f(Meta)75 747 y(k)o(ey)e(\(if)g(y) +o(ou)g(ha)o(v)o(e)g(one\))g(is)h(depressed,)g(and)f(the)930 +745 y Ff(h)p 942 719 V 942 747 a Fe(k)p 942 755 V 958 +745 a Ff(i)987 747 y Fm(k)o(ey)g(is)h(pressed.)20 b(The)15 +b(Meta)e(k)o(ey)h(is)h(lab)q(eled)1779 745 y Ff(h)p 1791 +719 72 2 v 1791 747 a Fe(AL)m(T)p 1791 755 V 1860 745 +a Ff(i)75 802 y Fm(on)e(man)o(y)g(k)o(eyb)q(oards.)19 +b(On)13 b(k)o(eyb)q(oards)g(with)h(t)o(w)o(o)e(k)o(eys)g(lab)q(eled) +1213 800 y Ff(h)p 1225 774 V 1225 802 a Fe(AL)m(T)p 1225 +810 V 1294 800 a Ff(i)1322 802 y Fm(\(usually)i(to)e(either)i(side)g +(of)f(the)75 857 y(space)j(bar\),)f(the)388 855 y Ff(h)p +400 829 V 400 857 a Fe(AL)m(T)p 400 865 V 469 855 a Ff(i)499 +857 y Fm(on)h(the)g(left)g(side)g(is)g(generally)h(set)f(to)f(w)o(ork)g +(as)g(a)g(Meta)g(k)o(ey)l(.)22 b(The)1697 855 y Ff(h)p +1709 829 V 1709 857 a Fe(AL)m(T)p 1709 865 V 1778 855 +a Ff(i)1808 857 y Fm(k)o(ey)75 912 y(on)17 b(the)f(righ)o(t)h(ma)o(y)f +(also)h(b)q(e)g(con\014gured)g(to)f(w)o(ork)g(as)g(a)h(Meta)f(k)o(ey)g +(or)g(ma)o(y)g(b)q(e)i(con\014gured)f(as)f(some)75 967 +y(other)f(mo)q(di\014er,)h(suc)o(h)f(as)g(a)g(Comp)q(ose)g(k)o(ey)g +(for)f(t)o(yping)i(accen)o(ted)f(c)o(haracters.)137 1035 +y(If)c(y)o(ou)g(do)g(not)f(ha)o(v)o(e)h(a)f(Meta)h(or)694 +1033 y Ff(h)p 706 1007 V 706 1035 a Fe(AL)m(T)p 706 1043 +V 775 1033 a Ff(i)801 1035 y Fm(k)o(ey)l(,)g(or)g(another)f(k)o(ey)h(w) +o(orking)f(as)h(a)f(Meta)h(k)o(ey)l(,)g(the)g(iden)o(tical)75 +1090 y(k)o(eystrok)o(e)f(can)i(b)q(e)g(generated)f(b)o(y)g(t)o(yping) +809 1088 y Ff(h)p 822 1062 70 2 v 822 1090 a Fe(ESC)p +822 1098 V 888 1088 a Ff(i)915 1090 y Fd(\014rst)p Fm(,)g(and)g(then)h +(t)o(yping)1339 1088 y Ff(h)p 1351 1062 19 2 v 1351 1090 +a Fe(k)p 1351 1098 V 1368 1088 a Ff(i)1383 1090 y Fm(.)18 +b(Either)12 b(pro)q(cess)f(is)h(kno)o(wn)75 1145 y(as)j +Fc(metafying)k Fm(the)425 1143 y Ff(h)p 437 1117 V 437 +1145 a Fe(k)p 437 1153 V 454 1143 a Ff(i)484 1145 y Fm(k)o(ey)l(.)137 +1214 y(The)i(text)e Fg(M-C-k)h Fm(is)h(read)f(as)f(`Meta-Con)o(trol-k') +g(and)h(describ)q(es)i(the)e(c)o(haracter)g(pro)q(duced)h(b)o(y)75 +1268 y Fc(metafying)e Fg(C-k)p Fm(.)137 1337 y(In)g(addition,)h(sev)o +(eral)f(k)o(eys)f(ha)o(v)o(e)g(their)h(o)o(wn)f(names.)30 +b(Sp)q(eci\014cally)l(,)1384 1335 y Ff(h)p 1396 1309 +73 2 v 1396 1337 a Fe(DEL)p 1396 1345 V 1467 1335 a Ff(i)1482 +1337 y Fm(,)1514 1335 y Ff(h)p 1526 1309 70 2 v 1526 +1337 a Fe(ESC)p 1526 1345 V 1593 1335 a Ff(i)1608 1337 +y Fm(,)1640 1335 y Ff(h)p 1652 1309 72 2 v 1652 1337 +a Fe(LFD)p 1652 1345 V 1722 1335 a Ff(i)1737 1337 y Fm(,)1768 +1335 y Ff(h)p 1780 1309 70 2 v 1780 1337 a Fe(SPC)p 1780 +1345 V 1847 1335 a Ff(i)1862 1337 y Fm(,)75 1390 y Ff(h)p +87 1364 76 2 v 87 1392 a Fe(RET)p 87 1399 V 160 1390 +a Ff(i)175 1392 y Fm(,)23 b(and)306 1390 y Ff(h)p 318 +1364 74 2 v 318 1392 a Fe(T)m(AB)p 318 1399 V 390 1390 +a Ff(i)427 1392 y Fm(all)f(stand)g(for)f(themselv)o(es)h(when)h(seen)f +(in)g(this)g(text,)h(or)e(in)i(an)e(init)i(\014le)g(\(see)75 +1447 y(Section)d(1.3)f([Readline)h(Init)g(File],)h(page)e(4\).)32 +b(If)19 b(y)o(our)g(k)o(eyb)q(oard)h(lac)o(ks)f(a)1444 +1445 y Ff(h)p 1456 1419 72 2 v 1456 1447 a Fe(LFD)p 1456 +1454 V 1526 1445 a Ff(i)1560 1447 y Fm(k)o(ey)l(,)h(t)o(yping)1802 +1445 y Ff(h)p 1814 1419 49 2 v 1814 1447 a Fe(C-j)p 1814 +1454 V 1860 1445 a Ff(i)75 1501 y Fm(will)c(pro)q(duce)g(the)f(desired) +h(c)o(haracter.)j(The)874 1499 y Ff(h)p 886 1473 76 2 +v 886 1501 a Fe(RET)p 886 1509 V 959 1499 a Ff(i)989 +1501 y Fm(k)o(ey)c(ma)o(y)f(b)q(e)h(lab)q(eled)1385 1499 +y Ff(h)p 1397 1473 109 2 v 1397 1501 a Fe(Return)p 1397 +1509 V 1503 1499 a Ff(i)1533 1501 y Fm(or)1588 1499 y +Ff(h)p 1600 1473 86 2 v 1600 1501 a Fe(En)o(ter)p 1600 +1509 V 1684 1499 a Ff(i)1714 1501 y Fm(on)f(some)75 1556 +y(k)o(eyb)q(oards.)75 1688 y Fk(1.2)33 b(Readline)23 +b(In)n(teraction)137 1786 y Fm(Often)13 b(during)h(an)e(in)o(teractiv)o +(e)h(session)g(y)o(ou)g(t)o(yp)q(e)f(in)i(a)e(long)h(line)h(of)e(text,) +h(only)g(to)f(notice)h(that)f(the)75 1841 y(\014rst)k(w)o(ord)f(on)h +(the)h(line)h(is)e(missp)q(elled.)26 b(The)16 b(Readline)i(library)f +(giv)o(es)f(y)o(ou)g(a)g(set)g(of)g(commands)g(for)75 +1896 y(manipulating)g(the)f(text)g(as)f(y)o(ou)h(t)o(yp)q(e)g(it)g(in,) +g(allo)o(wing)h(y)o(ou)f(to)f(just)h(\014x)g(y)o(our)f(t)o(yp)q(o,)g +(and)h(not)g(forcing)75 1950 y(y)o(ou)f(to)f(ret)o(yp)q(e)h(the)g(ma)s +(jorit)o(y)f(of)h(the)g(line.)21 b(Using)15 b(these)f(editing)h +(commands,)f(y)o(ou)g(mo)o(v)o(e)f(the)h(cursor)75 2005 +y(to)i(the)i(place)g(that)e(needs)i(correction,)g(and)f(delete)h(or)f +(insert)g(the)h(text)e(of)h(the)g(corrections.)26 b(Then,)75 +2060 y(when)16 b(y)o(ou)f(are)h(satis\014ed)g(with)g(the)f(line,)i(y)o +(ou)e(simply)i(press)1160 2058 y Ff(h)p 1172 2032 76 +2 v 1172 2060 a Fe(RET)p 1172 2068 V 1245 2058 a Ff(i)1260 +2060 y Fm(.)k(Y)l(ou)16 b(do)f(not)h(ha)o(v)o(e)f(to)g(b)q(e)h(at)f +(the)75 2115 y(end)k(of)e(the)h(line)i(to)d(press)563 +2113 y Ff(h)p 575 2087 V 575 2115 a Fe(RET)p 575 2122 +V 648 2113 a Ff(i)663 2115 y Fm(;)i(the)f(en)o(tire)h(line)g(is)g +(accepted)f(regardless)g(of)g(the)g(lo)q(cation)g(of)g(the)75 +2170 y(cursor)d(within)h(the)g(line.)75 2284 y Fb(1.2.1)30 +b(Readline)20 b(Bare)g(Essen)n(tials)137 2382 y Fm(In)12 +b(order)g(to)f(en)o(ter)g(c)o(haracters)g(in)o(to)g(the)h(line,)h +(simply)g(t)o(yp)q(e)f(them.)18 b(The)12 b(t)o(yp)q(ed)g(c)o(haracter)f +(app)q(ears)75 2437 y(where)16 b(the)h(cursor)f(w)o(as,)f(and)h(then)h +(the)f(cursor)g(mo)o(v)o(es)g(one)g(space)g(to)g(the)g(righ)o(t.)23 +b(If)17 b(y)o(ou)f(mist)o(yp)q(e)g(a)75 2492 y(c)o(haracter,)e(y)o(ou)h +(can)g(use)h(y)o(our)f(erase)g(c)o(haracter)f(to)h(bac)o(k)g(up)g(and)h +(delete)g(the)f(mist)o(yp)q(ed)h(c)o(haracter.)137 2560 +y(Sometimes)g(y)o(ou)f(ma)o(y)g(mist)o(yp)q(e)h(a)f(c)o(haracter,)f +(and)i(not)f(notice)h(the)f(error)g(un)o(til)i(y)o(ou)e(ha)o(v)o(e)g(t) +o(yp)q(ed)75 2615 y(sev)o(eral)g(other)f(c)o(haracters.)19 +b(In)c(that)e(case,)i(y)o(ou)f(can)g(t)o(yp)q(e)h Fg(C-b)f +Fm(to)g(mo)o(v)o(e)f(the)i(cursor)f(to)g(the)g(left,)h(and)75 +2670 y(then)h(correct)e(y)o(our)h(mistak)o(e.)20 b(Afterw)o(ards,)13 +b(y)o(ou)i(can)g(mo)o(v)o(e)g(the)g(cursor)g(to)g(the)g(righ)o(t)g +(with)g Fg(C-f)p Fm(.)p eop +%%Page: 2 4 +2 3 bop 75 -58 a Fm(2)1322 b(GNU)15 b(Readline)h(Library)137 +149 y(When)h(y)o(ou)f(add)g(text)g(in)h(the)g(middle)h(of)e(a)f(line,)j +(y)o(ou)e(will)i(notice)f(that)f(c)o(haracters)f(to)h(the)g(righ)o(t)75 +204 y(of)e(the)g(cursor)g(are)g(`pushed)h(o)o(v)o(er')f(to)f(mak)o(e)h +(ro)q(om)g(for)f(the)i(text)f(that)f(y)o(ou)h(ha)o(v)o(e)g(inserted.)21 +b(Lik)o(ewise,)75 259 y(when)e(y)o(ou)g(delete)h(text)e(b)q(ehind)j +(the)e(cursor,)g(c)o(haracters)f(to)g(the)h(righ)o(t)f(of)g(the)h +(cursor)g(are)f(`pulled)75 314 y(bac)o(k')11 b(to)g(\014ll)h(in)h(the)e +(blank)h(space)g(created)f(b)o(y)h(the)f(remo)o(v)m(al)g(of)g(the)h +(text.)18 b(A)11 b(list)h(of)f(the)h(bare)f(essen)o(tials)75 +369 y(for)k(editing)h(the)f(text)g(of)g(an)g(input)h(line)h(follo)o +(ws.)75 449 y Fg(C-b)168 b Fm(Mo)o(v)o(e)14 b(bac)o(k)h(one)h(c)o +(haracter.)75 530 y Fg(C-f)168 b Fm(Mo)o(v)o(e)14 b(forw)o(ard)g(one)h +(c)o(haracter.)75 608 y Ff(h)p 87 582 73 2 v 87 610 a +Fe(DEL)p 87 618 V 158 608 a Ff(i)188 610 y Fm(or)244 +608 y Ff(h)p 256 582 159 2 v 256 610 a Fe(Bac)o(kspace)p +256 618 V 412 608 a Ff(i)315 665 y Fm(Delete)h(the)f(c)o(haracter)g(to) +f(the)h(left)h(of)f(the)g(cursor.)75 745 y Fg(C-d)168 +b Fm(Delete)16 b(the)f(c)o(haracter)g(underneath)h(the)f(cursor.)75 +825 y(Prin)o(ting)h(c)o(haracters)315 880 y(Insert)f(the)h(c)o +(haracter)e(in)o(to)h(the)h(line)h(at)d(the)h(cursor.)75 +961 y Fg(C-_)g Fm(or)f Fg(C-x)h(C-u)315 1015 y Fm(Undo)i(the)g(last)f +(editing)i(command.)25 b(Y)l(ou)17 b(can)g(undo)g(all)g(the)g(w)o(a)o +(y)f(bac)o(k)h(to)f(an)g(empt)o(y)315 1070 y(line.)75 +1151 y(\(Dep)q(ending)i(on)f(y)o(our)g(con\014guration,)g(the)863 +1149 y Ff(h)p 875 1123 V 875 1151 a Fe(Bac)o(kspace)p +875 1159 V 1032 1149 a Ff(i)1063 1151 y Fm(k)o(ey)g(b)q(e)h(set)f(to)f +(delete)i(the)f(c)o(haracter)g(to)f(the)75 1206 y(left)h(of)f(the)h +(cursor)f(and)g(the)596 1204 y Ff(h)p 608 1178 73 2 v +608 1206 a Fe(DEL)p 608 1213 V 679 1204 a Ff(i)710 1206 +y Fm(k)o(ey)h(set)f(to)g(delete)h(the)g(c)o(haracter)f(underneath)h +(the)g(cursor,)f(lik)o(e)75 1260 y Fg(C-d)p Fm(,)e(rather)h(than)g(the) +g(c)o(haracter)g(to)f(the)i(left)f(of)g(the)g(cursor.\))75 +1374 y Fb(1.2.2)30 b(Readline)20 b(Mo)n(v)n(emen)n(t)i(Commands)137 +1471 y Fm(The)14 b(ab)q(o)o(v)o(e)e(table)i(describ)q(es)g(the)g(most)e +(basic)i(k)o(eystrok)o(es)d(that)i(y)o(ou)g(need)h(in)f(order)g(to)g +(do)g(editing)75 1526 y(of)f(the)h(input)h(line.)21 b(F)l(or)12 +b(y)o(our)g(con)o(v)o(enience,)i(man)o(y)f(other)f(commands)h(ha)o(v)o +(e)f(b)q(een)i(added)f(in)h(addition)75 1580 y(to)h Fg(C-b)p +Fm(,)h Fg(C-f)p Fm(,)f Fg(C-d)p Fm(,)g(and)522 1578 y +Ff(h)p 534 1552 V 534 1580 a Fe(DEL)p 534 1588 V 605 +1578 a Ff(i)619 1580 y Fm(.)23 b(Here)16 b(are)g(some)f(commands)h(for) +f(mo)o(ving)h(more)g(rapidly)h(ab)q(out)f(the)75 1635 +y(line.)75 1716 y Fg(C-a)168 b Fm(Mo)o(v)o(e)14 b(to)h(the)g(start)f +(of)h(the)g(line.)75 1796 y Fg(C-e)168 b Fm(Mo)o(v)o(e)14 +b(to)h(the)g(end)h(of)f(the)g(line.)75 1876 y Fg(M-f)168 +b Fm(Mo)o(v)o(e)14 b(forw)o(ard)g(a)h(w)o(ord,)f(where)i(a)e(w)o(ord)h +(is)h(comp)q(osed)f(of)g(letters)g(and)h(digits.)75 1957 +y Fg(M-b)168 b Fm(Mo)o(v)o(e)14 b(bac)o(kw)o(ard)h(a)g(w)o(ord.)75 +2037 y Fg(C-l)168 b Fm(Clear)15 b(the)h(screen,)f(reprin)o(ting)h(the)f +(curren)o(t)g(line)i(at)e(the)g(top.)137 2118 y(Notice)e(ho)o(w)f +Fg(C-f)g Fm(mo)o(v)o(es)f(forw)o(ard)g(a)h(c)o(haracter,)g(while)i +Fg(M-f)e Fm(mo)o(v)o(es)f(forw)o(ard)g(a)h(w)o(ord.)18 +b(It)13 b(is)g(a)f(lo)q(ose)75 2173 y(con)o(v)o(en)o(tion)j(that)f(con) +o(trol)h(k)o(eystrok)o(es)f(op)q(erate)h(on)f(c)o(haracters)h(while)h +(meta)e(k)o(eystrok)o(es)g(op)q(erate)h(on)75 2227 y(w)o(ords.)75 +2341 y Fb(1.2.3)30 b(Readline)20 b(Killing)h(Commands)137 +2438 y Fc(Killing)26 b Fm(text)18 b(means)g(to)g(delete)i(the)f(text)f +(from)g(the)h(line,)i(but)d(to)g(sa)o(v)o(e)g(it)h(a)o(w)o(a)o(y)e(for) +h(later)h(use,)75 2493 y(usually)f(b)o(y)f Fc(y)o(anking)22 +b Fm(\(re-inserting\))17 b(it)g(bac)o(k)g(in)o(to)g(the)h(line.)27 +b(\(`Cut')15 b(and)j(`paste')e(are)g(more)h(recen)o(t)75 +2547 y(jargon)d(for)h(`kill')h(and)g(`y)o(ank'.\))137 +2615 y(If)g(the)f(description)h(for)f(a)g(command)g(sa)o(ys)f(that)h +(it)g(`kills')h(text,)e(then)i(y)o(ou)f(can)g(b)q(e)h(sure)f(that)f(y)o +(ou)75 2670 y(can)h(get)g(the)g(text)g(bac)o(k)g(in)h(a)f(di\013eren)o +(t)g(\(or)g(the)g(same\))g(place)h(later.)p eop +%%Page: 3 5 +3 4 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(3)137 149 y(When)12 b(y)o(ou)g(use)g(a)f(kill)i(command,)f(the)g +(text)f(is)h(sa)o(v)o(ed)f(in)i(a)e Fc(kill-ring)p Fm(.)21 +b(An)o(y)12 b(n)o(um)o(b)q(er)g(of)f(consecutiv)o(e)75 +204 y(kills)17 b(sa)o(v)o(e)e(all)h(of)f(the)h(killed)i(text)d +(together,)f(so)h(that)g(when)h(y)o(ou)f(y)o(ank)g(it)h(bac)o(k,)f(y)o +(ou)g(get)g(it)h(all.)22 b(The)75 259 y(kill)c(ring)f(is)f(not)g(line)i +(sp)q(eci\014c;)g(the)e(text)g(that)f(y)o(ou)h(killed)j(on)d(a)g +(previously)h(t)o(yp)q(ed)g(line)h(is)e(a)o(v)m(ailable)75 +314 y(to)f(b)q(e)g(y)o(ank)o(ed)g(bac)o(k)h(later,)e(when)i(y)o(ou)f +(are)g(t)o(yping)g(another)g(line.)137 380 y(Here)h(is)f(the)h(list)g +(of)e(commands)h(for)g(killing)j(text.)75 458 y Fg(C-k)168 +b Fm(Kill)17 b(the)f(text)e(from)h(the)g(curren)o(t)g(cursor)g(p)q +(osition)h(to)f(the)g(end)h(of)f(the)g(line.)75 535 y +Fg(M-d)168 b Fm(Kill)15 b(from)e(the)g(cursor)g(to)f(the)i(end)g(of)e +(the)i(curren)o(t)f(w)o(ord,)f(or,)h(if)g(b)q(et)o(w)o(een)h(w)o(ords,) +e(to)h(the)315 590 y(end)j(of)f(the)g(next)g(w)o(ord.)k(W)l(ord)c(b)q +(oundaries)i(are)e(the)g(same)g(as)g(those)f(used)i(b)o(y)f +Fg(M-f)p Fm(.)75 668 y Fg(M-)123 666 y Ff(h)p 135 640 +73 2 v 135 668 a Fe(DEL)p 135 675 V 206 666 a Ff(i)315 +668 y Fm(Kill)i(from)e(the)g(cursor)g(the)h(start)e(of)h(the)g(curren)o +(t)g(w)o(ord,)f(or,)h(if)g(b)q(et)o(w)o(een)h(w)o(ords,)e(to)h(the)315 +723 y(start)j(of)h(the)g(previous)h(w)o(ord.)31 b(W)l(ord)19 +b(b)q(oundaries)h(are)f(the)h(same)e(as)h(those)g(used)h(b)o(y)315 +777 y Fg(M-b)p Fm(.)75 855 y Fg(C-w)168 b Fm(Kill)18 +b(from)d(the)g(cursor)h(to)f(the)g(previous)i(whitespace.)22 +b(This)16 b(is)g(di\013eren)o(t)g(than)f Fg(M-)1777 853 +y Ff(h)p 1789 827 V 1789 855 a Fe(DEL)p 1789 863 V 1860 +853 a Ff(i)315 910 y Fm(b)q(ecause)h(the)f(w)o(ord)g(b)q(oundaries)h +(di\013er.)137 987 y(Here)21 b(is)h(ho)o(w)e(to)g Fc(y)o(ank)j +Fm(the)e(text)f(bac)o(k)h(in)o(to)g(the)f(line.)39 b(Y)l(anking)21 +b(means)g(to)f(cop)o(y)h(the)g(most-)75 1042 y(recen)o(tly-killed)d +(text)d(from)f(the)i(kill)h(bu\013er.)75 1120 y Fg(C-y)168 +b Fm(Y)l(ank)15 b(the)h(most)e(recen)o(tly)i(killed)h(text)e(bac)o(k)g +(in)o(to)g(the)h(bu\013er)f(at)f(the)i(cursor.)75 1198 +y Fg(M-y)168 b Fm(Rotate)16 b(the)h(kill-ring,)j(and)d(y)o(ank)g(the)h +(new)f(top.)26 b(Y)l(ou)17 b(can)h(only)g(do)f(this)h(if)f(the)h(prior) +315 1252 y(command)d(is)h Fg(C-y)f Fm(or)f Fg(M-y)p Fm(.)75 +1361 y Fb(1.2.4)30 b(Readline)20 b(Argumen)n(ts)137 1457 +y Fm(Y)l(ou)15 b(can)g(pass)f(n)o(umeric)i(argumen)o(ts)e(to)g +(Readline)h(commands.)20 b(Sometimes)15 b(the)g(argumen)o(t)e(acts)75 +1511 y(as)20 b(a)f(rep)q(eat)i(coun)o(t,)f(other)g(times)g(it)h(is)f +(the)g Fd(sign)j Fm(of)c(the)h(argumen)o(t)g(that)f(is)i(signi\014can)o +(t.)35 b(If)20 b(y)o(ou)75 1566 y(pass)d(a)f(negativ)o(e)h(argumen)o(t) +f(to)g(a)g(command)h(whic)o(h)h(normally)f(acts)f(in)i(a)e(forw)o(ard)g +(direction,)i(that)75 1621 y(command)g(will)h(act)e(in)i(a)e(bac)o(kw)o +(ard)g(direction.)28 b(F)l(or)17 b(example,)i(to)e(kill)j(text)d(bac)o +(k)g(to)g(the)h(start)e(of)75 1676 y(the)f(line,)i(y)o(ou)e(migh)o(t)g +(t)o(yp)q(e)g(`)p Fl(M--)f(C-k)p Fm('.)137 1742 y(The)h(general)f(w)o +(a)o(y)f(to)h(pass)g(n)o(umeric)h(argumen)o(ts)e(to)g(a)h(command)g(is) +h(to)e(t)o(yp)q(e)h(meta)g(digits)h(b)q(efore)75 1797 +y(the)h(command.)k(If)c(the)f(\014rst)g(`digit')h(t)o(yp)q(ed)f(is)h(a) +g(min)o(us)g(sign)g(\(`)p Fl(-)p Fm('\),)d(then)j(the)f(sign)h(of)f +(the)h(argumen)o(t)75 1852 y(will)21 b(b)q(e)f(negativ)o(e.)31 +b(Once)20 b(y)o(ou)f(ha)o(v)o(e)g(t)o(yp)q(ed)g(one)g(meta)g(digit)h +(to)e(get)h(the)g(argumen)o(t)f(started,)h(y)o(ou)75 +1906 y(can)c(t)o(yp)q(e)f(the)h(remainder)g(of)f(the)g(digits,)h(and)g +(then)g(the)f(command.)20 b(F)l(or)13 b(example,)i(to)f(giv)o(e)h(the)f +Fg(C-d)75 1961 y Fm(command)19 b(an)f(argumen)o(t)g(of)g(10,)h(y)o(ou)f +(could)i(t)o(yp)q(e)f(`)p Fl(M-1)14 b(0)h(C-d)p Fm(',)k(whic)o(h)g +(will)h(delete)g(the)f(next)g(ten)75 2016 y(c)o(haracters)14 +b(on)i(the)f(input)h(line.)75 2125 y Fb(1.2.5)30 b(Searc)n(hing)21 +b(for)f(Commands)h(in)f(the)h(History)137 2220 y Fm(Readline)d(pro)o +(vides)e(commands)g(for)g(searc)o(hing)g(through)g(the)g(command)g +(history)g(for)g(lines)i(con-)75 2275 y(taining)e(a)f(sp)q(eci\014ed)i +(string.)j(There)c(are)e(t)o(w)o(o)g(searc)o(h)h(mo)q(des:)20 +b Fc(incremen)o(tal)e Fm(and)e Fc(non-incremen)o(tal)p +Fm(.)137 2341 y(Incremen)o(tal)e(searc)o(hes)f(b)q(egin)h(b)q(efore)f +(the)g(user)g(has)g(\014nished)h(t)o(yping)f(the)g(searc)o(h)g(string.) +19 b(As)13 b(eac)o(h)75 2396 y(c)o(haracter)k(of)g(the)h(searc)o(h)g +(string)f(is)h(t)o(yp)q(ed,)h(Readline)g(displa)o(ys)f(the)g(next)g(en) +o(try)f(from)g(the)h(history)75 2451 y(matc)o(hing)12 +b(the)g(string)g(t)o(yp)q(ed)g(so)g(far.)18 b(An)13 b(incremen)o(tal)g +(searc)o(h)f(requires)g(only)h(as)f(man)o(y)f(c)o(haracters)g(as)75 +2506 y(needed)16 b(to)d(\014nd)j(the)e(desired)i(history)e(en)o(try)l +(.)19 b(T)l(o)c(searc)o(h)f(bac)o(kw)o(ard)f(in)j(the)e(history)g(for)g +(a)g(particular)75 2560 y(string,)g(t)o(yp)q(e)h Fg(C-r)p +Fm(.)k(T)o(yping)d Fg(C-s)e Fm(searc)o(hes)h(forw)o(ard)e(through)h +(the)h(history)l(.)20 b(The)15 b(c)o(haracters)f(presen)o(t)75 +2615 y(in)20 b(the)f(v)m(alue)h(of)f(the)g Fl(isearch-terminators)d +Fm(v)m(ariable)k(are)f(used)h(to)e(terminate)h(an)g(incremen)o(tal)75 +2670 y(searc)o(h.)31 b(If)19 b(that)f(v)m(ariable)i(has)f(not)f(b)q +(een)i(assigned)g(a)e(v)m(alue,)j(the)1289 2668 y Ff(h)p +1301 2642 70 2 v 1301 2670 a Fe(ESC)p 1301 2678 V 1368 +2668 a Ff(i)1402 2670 y Fm(and)e Fg(C-J)f Fm(c)o(haracters)g(will)p +eop +%%Page: 4 6 +4 5 bop 75 -58 a Fm(4)1322 b(GNU)15 b(Readline)h(Library)75 +149 y(terminate)21 b(an)g(incremen)o(tal)i(searc)o(h.)37 +b Fg(C-g)21 b Fm(will)i(ab)q(ort)e(an)g(incremen)o(tal)h(searc)o(h)f +(and)g(restore)g(the)75 204 y(original)16 b(line.)21 +b(When)15 b(the)f(searc)o(h)g(is)h(terminated,)g(the)f(history)h(en)o +(try)f(con)o(taining)h(the)g(searc)o(h)f(string)75 259 +y(b)q(ecomes)i(the)f(curren)o(t)g(line.)137 325 y(T)l(o)g(\014nd)i +(other)e(matc)o(hing)g(en)o(tries)h(in)h(the)e(history)h(list,)g(t)o +(yp)q(e)f Fg(C-r)g Fm(or)g Fg(C-s)g Fm(as)h(appropriate.)k(This)75 +380 y(will)15 b(searc)o(h)e(bac)o(kw)o(ard)f(or)g(forw)o(ard)g(in)i +(the)f(history)g(for)g(the)g(next)g(en)o(try)g(matc)o(hing)g(the)g +(searc)o(h)g(string)75 434 y(t)o(yp)q(ed)19 b(so)g(far.)30 +b(An)o(y)19 b(other)f(k)o(ey)h(sequence)h(b)q(ound)g(to)e(a)h(Readline) +h(command)e(will)j(terminate)e(the)75 489 y(searc)o(h)10 +b(and)h(execute)g(that)f(command.)18 b(F)l(or)10 b(instance,)i(a)1063 +487 y Ff(h)p 1076 461 76 2 v 1076 489 a Fe(RET)p 1076 +497 V 1149 487 a Ff(i)1174 489 y Fm(will)g(terminate)f(the)g(searc)o(h) +f(and)h(accept)75 544 y(the)k(line,)h(thereb)o(y)f(executing)g(the)g +(command)g(from)f(the)g(history)h(list.)20 b(A)15 b(mo)o(v)o(emen)o(t)f +(command)g(will)75 599 y(terminate)h(the)g(searc)o(h,)g(mak)o(e)g(the)g +(last)g(line)i(found)f(the)f(curren)o(t)g(line,)h(and)g(b)q(egin)g +(editing.)137 665 y(Readline)j(remem)o(b)q(ers)e(the)h(last)f(incremen) +o(tal)i(searc)o(h)e(string.)27 b(If)17 b(t)o(w)o(o)f +Fg(C-r)p Fm(s)h(are)g(t)o(yp)q(ed)h(without)75 719 y(an)o(y)g(in)o +(terv)o(ening)h(c)o(haracters)f(de\014ning)h(a)f(new)h(searc)o(h)f +(string,)g(an)o(y)g(remem)o(b)q(ered)h(searc)o(h)f(string)g(is)75 +774 y(used.)137 840 y(Non-incremen)o(tal)25 b(searc)o(hes)e(read)h(the) +f(en)o(tire)h(searc)o(h)f(string)g(b)q(efore)h(starting)f(to)f(searc)o +(h)i(for)75 895 y(matc)o(hing)d(history)h(lines.)39 b(The)22 +b(searc)o(h)f(string)g(ma)o(y)g(b)q(e)h(t)o(yp)q(ed)f(b)o(y)h(the)f +(user)h(or)e(b)q(e)i(part)f(of)g(the)75 950 y(con)o(ten)o(ts)15 +b(of)f(the)i(curren)o(t)f(line.)75 1074 y Fk(1.3)33 b(Readline)23 +b(Init)h(File)137 1169 y Fm(Although)f(the)g(Readline)h(library)f +(comes)g(with)g(a)f(set)g(of)g(Emacs-lik)o(e)i(k)o(eybindings)g +(installed)75 1224 y(b)o(y)d(default,)h(it)f(is)h(p)q(ossible)g(to)e +(use)i(a)e(di\013eren)o(t)h(set)g(of)f(k)o(eybindings.)39 +b(An)o(y)20 b(user)h(can)g(customize)75 1278 y(programs)15 +b(that)h(use)g(Readline)i(b)o(y)e(putting)g(commands)g(in)i(an)e +Fc(inputrc)k Fm(\014le,)d(con)o(v)o(en)o(tionally)g(in)g(his)75 +1333 y(home)g(directory)l(.)24 b(The)17 b(name)g(of)f(this)h(\014le)g +(is)g(tak)o(en)g(from)e(the)i(v)m(alue)h(of)e(the)h(en)o(vironmen)o(t)g +(v)m(ariable)75 1388 y Fl(INPUTRC)p Fm(.)i(If)c(that)g(v)m(ariable)h +(is)g(unset,)f(the)g(default)h(is)g(`)p Fl(~/.inputrc)p +Fm('.)137 1454 y(When)f(a)g(program)f(whic)o(h)h(uses)g(the)g(Readline) +h(library)g(starts)d(up,)i(the)g(init)h(\014le)g(is)f(read,)g(and)g +(the)75 1509 y(k)o(ey)g(bindings)i(are)e(set.)137 1574 +y(In)f(addition,)h(the)e Fl(C-x)i(C-r)e Fm(command)g(re-reads)h(this)g +(init)g(\014le,)h(th)o(us)e(incorp)q(orating)h(an)o(y)f(c)o(hanges)75 +1629 y(that)h(y)o(ou)h(migh)o(t)g(ha)o(v)o(e)g(made)g(to)g(it.)75 +1737 y Fb(1.3.1)30 b(Readline)20 b(Init)g(File)h(Syn)n(tax)137 +1832 y Fm(There)c(are)g(only)g(a)g(few)f(basic)i(constructs)e(allo)o(w) +o(ed)i(in)f(the)g(Readline)h(init)g(\014le.)26 b(Blank)18 +b(lines)g(are)75 1886 y(ignored.)36 b(Lines)22 b(b)q(eginning)h(with)d +(a)h(`)p Fl(#)p Fm(')e(are)h(commen)o(ts.)35 b(Lines)22 +b(b)q(eginning)h(with)e(a)f(`)p Fl($)p Fm(')f(indicate)75 +1941 y(conditional)c(constructs)f(\(see)g(Section)g(1.3.2)f +([Conditional)h(Init)h(Constructs],)e(page)h(9\).)k(Other)c(lines)75 +1996 y(denote)h(v)m(ariable)i(settings)e(and)h(k)o(ey)f(bindings.)75 +2073 y(V)l(ariable)h(Settings)315 2128 y(Y)l(ou)k(can)h(mo)q(dify)g +(the)f(run-time)h(b)q(eha)o(vior)g(of)e(Readline)j(b)o(y)e(altering)h +(the)f(v)m(alues)h(of)315 2182 y(v)m(ariables)d(in)g(Readline)g(using)f +(the)g Fl(set)g Fm(command)f(within)i(the)f(init)h(\014le.)26 +b(The)17 b(syn)o(tax)315 2237 y(is)f(simple:)435 2300 +y Fl(set)23 b Fc(v)m(ariable)28 b(v)m(alue)315 2366 y +Fm(Here,)14 b(for)f(example,)h(is)g(ho)o(w)f(to)g(c)o(hange)h(from)f +(the)h(default)g(Emacs-lik)o(e)h(k)o(ey)e(binding)j(to)315 +2421 y(use)g Fl(vi)e Fm(line)j(editing)g(commands:)435 +2484 y Fl(set)23 b(editing-mode)g(vi)315 2549 y Fm(V)l(ariable)c(names) +e(and)h(v)m(alues,)h(where)e(appropriate,)h(are)f(recognized)i(without) +e(regard)315 2604 y(to)e(case.)315 2670 y(A)g(great)g(deal)g(of)g +(run-time)h(b)q(eha)o(vior)g(is)g(c)o(hangeable)g(with)f(the)h(follo)o +(wing)f(v)m(ariables.)p eop +%%Page: 5 7 +5 6 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(5)315 149 y Fl(bell-style)555 204 y Fm(Con)o(trols)21 +b(what)h(happ)q(ens)h(when)f(Readline)h(w)o(an)o(ts)e(to)g(ring)i(the)f +(termi-)555 259 y(nal)d(b)q(ell.)32 b(If)19 b(set)f(to)g(`)p +Fl(none)p Fm(',)g(Readline)i(nev)o(er)f(rings)g(the)f(b)q(ell.)32 +b(If)19 b(set)g(to)555 314 y(`)p Fl(visible)p Fm(',)c(Readline)i(uses)g +(a)f(visible)j(b)q(ell)g(if)e(one)f(is)h(a)o(v)m(ailable.)26 +b(If)16 b(set)h(to)555 369 y(`)p Fl(audible)p Fm(')g(\(the)h +(default\),)i(Readline)g(attempts)e(to)g(ring)h(the)g(terminal's)555 +423 y(b)q(ell.)315 504 y Fl(comment-begin)555 559 y Fm(The)c(string)f +(to)g(insert)i(at)d(the)i(b)q(eginning)i(of)d(the)h(line)h(when)f(the)g +Fl(insert-)555 614 y(comment)f Fm(command)h(is)h(executed.)21 +b(The)15 b(default)h(v)m(alue)g(is)g Fl("#")p Fm(.)315 +694 y Fl(completion-ignore-case)555 749 y Fm(If)e(set)f(to)g(`)p +Fl(on)p Fm(',)g(Readline)i(p)q(erforms)e(\014lename)i(matc)o(hing)f +(and)g(completion)555 804 y(in)i(a)f(case-insensitiv)o(e)i(fashion.)k +(The)15 b(default)h(v)m(alue)g(is)g(`)p Fl(off)p Fm('.)315 +884 y Fl(completion-query-items)555 939 y Fm(The)d(n)o(um)o(b)q(er)h +(of)e(p)q(ossible)j(completions)g(that)d(determines)i(when)g(the)f +(user)555 994 y(is)21 b(ask)o(ed)g(whether)g(he)h(w)o(an)o(ts)d(to)i +(see)g(the)g(list)h(of)e(p)q(ossibilitie)q(s.)40 b(If)21 +b(the)555 1049 y(n)o(um)o(b)q(er)14 b(of)f(p)q(ossible)i(completions)f +(is)g(greater)f(than)g(this)h(v)m(alue,)h(Readline)555 +1104 y(will)g(ask)e(the)g(user)h(whether)f(or)g(not)g(he)g(wishes)h(to) +f(view)h(them;)f(otherwise,)555 1158 y(they)f(are)g(simply)i(listed.)20 +b(This)13 b(v)m(ariable)g(m)o(ust)f(b)q(e)h(set)f(to)f(an)h(in)o(teger) +h(v)m(alue)555 1213 y(greater)h(than)h(or)g(equal)h(to)f(0.)k(The)d +(default)f(limit)i(is)f Fl(100)p Fm(.)315 1294 y Fl(convert-meta)555 +1348 y Fm(If)11 b(set)g(to)g(`)p Fl(on)p Fm(',)f(Readline)i(will)h(con) +o(v)o(ert)d(c)o(haracters)h(with)g(the)g(eigh)o(th)h(bit)f(set)555 +1403 y(to)f(an)h Fh(asci)q(i)e Fm(k)o(ey)i(sequence)g(b)o(y)g +(stripping)h(the)e(eigh)o(th)h(bit)h(and)e(pre\014xing)i(an)555 +1456 y Ff(h)p 567 1430 70 2 v 567 1458 a Fe(ESC)p 567 +1466 V 634 1456 a Ff(i)666 1458 y Fm(c)o(haracter,)k(con)o(v)o(erting)h +(them)g(to)f(a)h(meta-pre\014xed)g(k)o(ey)g(sequence.)555 +1513 y(The)e(default)h(v)m(alue)h(is)e(`)p Fl(on)p Fm('.)315 +1593 y Fl(disable-completion)555 1648 y Fm(If)k(set)f(to)f(`)p +Fl(On)p Fm(',)h(Readline)i(will)g(inhibit)g(w)o(ord)e(completion.)30 +b(Completion)555 1703 y(c)o(haracters)12 b(will)j(b)q(e)f(inserted)g +(in)o(to)f(the)g(line)h(as)f(if)h(they)f(had)g(b)q(een)h(mapp)q(ed)555 +1758 y(to)h Fl(self-insert)p Fm(.)j(The)d(default)h(is)g(`)p +Fl(off)p Fm('.)315 1838 y Fl(editing-mode)555 1893 y +Fm(The)f Fl(editing-mode)d Fm(v)m(ariable)k(con)o(trols)e(whic)o(h)h +(default)g(set)f(of)g(k)o(ey)g(bind-)555 1948 y(ings)f(is)g(used.)20 +b(By)12 b(default,)i(Readline)f(starts)f(up)h(in)g(Emacs)f(editing)i +(mo)q(de,)555 2003 y(where)h(the)f(k)o(eystrok)o(es)g(are)g(most)g +(similar)i(to)d(Emacs.)20 b(This)15 b(v)m(ariable)h(can)555 +2058 y(b)q(e)g(set)f(to)f(either)i(`)p Fl(emacs)p Fm(')e(or)h(`)p +Fl(vi)p Fm('.)315 2138 y Fl(enable-keypad)555 2193 y +Fm(When)d(set)f(to)h(`)p Fl(on)p Fm(',)e(Readline)j(will)h(try)d(to)g +(enable)i(the)f(application)h(k)o(eypad)555 2248 y(when)h(it)f(is)h +(called.)21 b(Some)13 b(systems)g(need)h(this)g(to)f(enable)h(the)g +(arro)o(w)e(k)o(eys.)555 2303 y(The)j(default)h(is)g(`)p +Fl(off)p Fm('.)315 2383 y Fl(expand-tilde)555 2438 y +Fm(If)e(set)g(to)f(`)p Fl(on)p Fm(',)f(tilde)k(expansion)e(is)h(p)q +(erformed)f(when)g(Readline)h(attempts)555 2493 y(w)o(ord)g +(completion.)21 b(The)15 b(default)h(is)f(`)p Fl(off)p +Fm('.)555 2560 y(If)g(set)g(to)f(`)p Fl(on)p Fm(',)g(the)g(history)h +(co)q(de)h(attempts)e(to)g(place)i(p)q(oin)o(t)f(at)f(the)h(same)555 +2615 y(lo)q(cation)20 b(on)f(eac)o(h)g(history)h(line)g(retriv)o(ed)g +(with)f Fl(previous-history)e Fm(or)555 2670 y Fl(next-history)p +Fm(.)p eop +%%Page: 6 8 +6 7 bop 75 -58 a Fm(6)1322 b(GNU)15 b(Readline)h(Library)315 +149 y Fl(horizontal-scroll-mode)555 204 y Fm(This)j(v)m(ariable)g(can)f +(b)q(e)g(set)g(to)f(either)i(`)p Fl(on)p Fm(')e(or)g(`)p +Fl(off)p Fm('.)27 b(Setting)19 b(it)f(to)f(`)p Fl(on)p +Fm(')555 259 y(means)c(that)f(the)i(text)e(of)h(the)g(lines)i(b)q(eing) +f(edited)g(will)h(scroll)f(horizon)o(tally)555 314 y(on)i(a)f(single)i +(screen)g(line)g(when)g(they)f(are)f(longer)h(than)g(the)g(width)g(of)g +(the)555 369 y(screen,)e(instead)f(of)g(wrapping)g(on)o(to)f(a)h(new)g +(screen)h(line.)21 b(By)13 b(default,)h(this)555 423 +y(v)m(ariable)j(is)e(set)g(to)g(`)p Fl(off)p Fm('.)315 +506 y Fl(input-meta)555 560 y Fm(If)h(set)f(to)g(`)p +Fl(on)p Fm(',)f(Readline)j(will)h(enable)e(eigh)o(t-bit)h(input)f(\(it) +g(will)h(not)e(clear)555 615 y(the)20 b(eigh)o(th)g(bit)g(in)h(the)f(c) +o(haracters)f(it)h(reads\),)g(regardless)g(of)g(what)f(the)555 +670 y(terminal)i(claims)g(it)f(can)g(supp)q(ort.)34 b(The)20 +b(default)h(v)m(alue)g(is)g(`)p Fl(off)p Fm('.)33 b(The)555 +725 y(name)15 b Fl(meta-flag)f Fm(is)i(a)f(synon)o(ym)g(for)f(this)i(v) +m(ariable.)315 807 y Fl(isearch-terminators)555 862 y +Fm(The)26 b(string)g(of)f(c)o(haracters)g(that)g(should)i(terminate)f +(an)g(incremen)o(tal)555 917 y(searc)o(h)12 b(without)h(subsequen)o +(tly)g(executing)h(the)e(c)o(haracter)g(as)g(a)g(command)555 +971 y(\(see)22 b(Section)h(1.2.5)e([Searc)o(hing],)j(page)e(3\).)40 +b(If)23 b(this)g(v)m(ariable)g(has)f(not)555 1026 y(b)q(een)17 +b(giv)o(en)f(a)g(v)m(alue,)g(the)g(c)o(haracters)1247 +1024 y Ff(h)p 1259 998 70 2 v 1259 1026 a Fe(ESC)p 1259 +1034 V 1326 1024 a Ff(i)1357 1026 y Fm(and)g Fg(C-J)f +Fm(will)i(terminate)f(an)555 1081 y(incremen)o(tal)g(searc)o(h.)315 +1163 y Fl(keymap)96 b Fm(Sets)19 b(Readline's)i(idea)f(of)f(the)g +(curren)o(t)h(k)o(eymap)f(for)f(k)o(ey)i(binding)h(com-)555 +1218 y(mands.)41 b(Acceptable)23 b Fl(keymap)f Fm(names)g(are)f +Fl(emacs)p Fm(,)i Fl(emacs-standard)p Fm(,)555 1273 y +Fl(emacs-meta)p Fm(,)49 b Fl(emacs-ctlx)p Fm(,)g Fl(vi)p +Fm(,)h Fl(vi-move)p Fm(,)f Fl(vi-command)p Fm(,)g(and)555 +1328 y Fl(vi-insert)p Fm(.)31 b Fl(vi)20 b Fm(is)g(equiv)m(alen)o(t)h +(to)e Fl(vi-command)p Fm(;)g Fl(emacs)g Fm(is)h(equiv)m(alen)o(t)555 +1382 y(to)15 b Fl(emacs-standard)p Fm(.)20 b(The)d(default)f(v)m(alue)h +(is)g Fl(emacs)p Fm(.)k(The)16 b(v)m(alue)h(of)f(the)555 +1437 y Fl(editing-mode)e Fm(v)m(ariable)i(also)f(a\013ects)g(the)g +(default)h(k)o(eymap.)315 1519 y Fl(mark-directories)555 +1574 y Fm(If)j(set)g(to)g(`)p Fl(on)p Fm(',)f(completed)i(directory)g +(names)f(ha)o(v)o(e)f(a)h(slash)h(app)q(ended.)555 1629 +y(The)15 b(default)h(is)g(`)p Fl(on)p Fm('.)315 1711 +y Fl(mark-modified-lines)555 1766 y Fm(This)j(v)m(ariable,)g(when)g +(set)e(to)h(`)p Fl(on)p Fm(',)f(causes)h(Readline)h(to)e(displa)o(y)i +(an)f(as-)555 1821 y(terisk)f(\(`)p Fl(*)p Fm('\))e(at)i(the)f(start)g +(of)h(history)f(lines)j(whic)o(h)e(ha)o(v)o(e)g(b)q(een)h(mo)q +(di\014ed.)555 1875 y(This)e(v)m(ariable)g(is)g(`)p Fl(off)p +Fm(')e(b)o(y)h(default.)315 1958 y Fl(mark-symlinked-directories)555 +2012 y Fm(If)23 b(set)f(to)f(`)p Fl(on)p Fm(',)i(completed)g(names)g +(whic)o(h)g(are)f(sym)o(b)q(olic)i(links)f(to)f(di-)555 +2067 y(rectories)h(ha)o(v)o(e)g(a)g(slash)g(app)q(ended)i(\(sub)s(ject) +e(to)f(the)i(v)m(alue)g(of)f Fl(mark-)555 2122 y(directories)p +Fm(\).)18 b(The)d(default)h(is)g(`)p Fl(off)p Fm('.)315 +2204 y Fl(match-hidden-files)555 2259 y Fm(This)c(v)m(ariable,)h(when)e +(set)g(to)g(`)p Fl(on)p Fm(',)f(causes)h(Readline)i(to)d(matc)o(h)h +(\014les)h(whose)555 2314 y(names)22 b(b)q(egin)h(with)g(a)e(`)p +Fl(.)p Fm(')h(\(hidden)h(\014les\))g(when)f(p)q(erforming)h(\014lename) +555 2369 y(completion,)g(unless)f(the)f(leading)h(`)p +Fl(.)p Fm(')e(is)h(supplied)i(b)o(y)e(the)f(user)h(in)h(the)555 +2423 y(\014lename)16 b(to)f(b)q(e)h(completed.)21 b(This)15 +b(v)m(ariable)i(is)f(`)p Fl(on)p Fm(')e(b)o(y)h(default.)315 +2506 y Fl(output-meta)555 2560 y Fm(If)j(set)f(to)g(`)p +Fl(on)p Fm(',)g(Readline)i(will)h(displa)o(y)f(c)o(haracters)d(with)j +(the)e(eigh)o(th)h(bit)555 2615 y(set)g(directly)i(rather)d(than)h(as)g +(a)g(meta-pre\014xed)h(escap)q(e)g(sequence.)30 b(The)555 +2670 y(default)16 b(is)f(`)p Fl(off)p Fm('.)p eop +%%Page: 7 9 +7 8 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(7)315 149 y Fl(page-completions)555 204 y Fm(If)17 +b(set)g(to)f(`)p Fl(on)p Fm(',)g(Readline)i(uses)g(an)e(in)o(ternal)i +Fl(more)p Fm(-lik)o(e)g(pager)f(to)f(displa)o(y)555 259 +y(a)g(screenful)h(of)f(p)q(ossible)i(completions)f(at)f(a)g(time.)23 +b(This)17 b(v)m(ariable)g(is)g(`)p Fl(on)p Fm(')555 314 +y(b)o(y)e(default.)315 395 y Fl(print-completions-horizont)o(ally)555 +450 y Fm(If)d(set)g(to)f(`)p Fl(on)p Fm(',)h(Readline)h(will)g(displa)o +(y)h(completions)f(with)f(matc)o(hes)f(sorted)555 505 +y(horizon)o(tally)23 b(in)f(alphab)q(etical)i(order,)f(rather)e(than)g +(do)o(wn)h(the)g(screen.)555 560 y(The)15 b(default)h(is)g(`)p +Fl(off)p Fm('.)315 641 y Fl(show-all-if-ambiguous)555 +696 y Fm(This)g(alters)e(the)i(default)f(b)q(eha)o(vior)h(of)e(the)h +(completion)h(functions.)21 b(If)15 b(set)555 751 y(to)e(`)p +Fl(on)p Fm(',)g(w)o(ords)g(whic)o(h)h(ha)o(v)o(e)g(more)f(than)g(one)h +(p)q(ossible)i(completion)f(cause)555 806 y(the)20 b(matc)o(hes)f(to)f +(b)q(e)j(listed)f(immediately)h(instead)f(of)f(ringing)i(the)e(b)q +(ell.)555 861 y(The)c(default)h(v)m(alue)h(is)e(`)p Fl(off)p +Fm('.)315 942 y Fl(visible-stats)555 997 y Fm(If)h(set)g(to)f(`)p +Fl(on)p Fm(',)g(a)h(c)o(haracter)f(denoting)h(a)g(\014le's)h(t)o(yp)q +(e)f(is)g(app)q(ended)i(to)d(the)555 1052 y(\014lename)h(when)g +(listing)h(p)q(ossible)g(completions.)j(The)c(default)g(is)f(`)p +Fl(off)p Fm('.)75 1133 y(Key)h(Bindings)315 1188 y(The)21 +b(syn)o(tax)f(for)h(con)o(trolling)h(k)o(ey)f(bindings)h(in)g(the)f +(init)h(\014le)g(is)g(simple.)39 b(First)20 b(y)o(ou)315 +1243 y(need)15 b(to)e(\014nd)h(the)g(name)g(of)g(the)f(command)h(that)f +(y)o(ou)h(w)o(an)o(t)f(to)g(c)o(hange.)19 b(The)14 b(follo)o(wing)315 +1298 y(sections)k(con)o(tain)h(tables)f(of)f(the)h(command)g(name,)g +(the)g(default)h(k)o(eybinding,)h(if)e(an)o(y)l(,)315 +1353 y(and)d(a)g(short)g(description)i(of)d(what)h(the)g(command)g(do)q +(es.)315 1421 y(Once)k(y)o(ou)f(kno)o(w)f(the)h(name)g(of)g(the)g +(command,)g(simply)h(place)g(on)f(a)f(line)j(in)f(the)f(init)315 +1476 y(\014le)g(the)f(name)g(of)f(the)h(k)o(ey)g(y)o(ou)f(wish)i(to)e +(bind)i(the)f(command)g(to,)f(a)g(colon,)i(and)f(then)315 +1530 y(the)f(name)g(of)g(the)g(command.)22 b(The)16 b(name)g(of)g(the)g +(k)o(ey)f(can)i(b)q(e)f(expressed)h(in)g(di\013eren)o(t)315 +1585 y(w)o(a)o(ys,)d(dep)q(ending)j(on)e(what)g(y)o(ou)g(\014nd)h(most) +e(comfortable.)315 1653 y(In)19 b(addition)g(to)e(command)h(names,)g +(readline)i(allo)o(ws)e(k)o(eys)g(to)f(b)q(e)i(b)q(ound)g(to)e(a)h +(string)315 1708 y(that)c(is)i(inserted)g(when)g(the)f(k)o(ey)g(is)h +(pressed)g(\(a)e Fc(macro)r Fm(\).)315 1790 y Fc(k)o(eyname)s +Fm(:)19 b Fc(function-name)g Fm(or)c Fc(macro)555 1845 +y(k)o(eyname)i Fm(is)e(the)f(name)h(of)f(a)g(k)o(ey)g(sp)q(elled)j(out) +d(in)h(English.)21 b(F)l(or)13 b(example:)675 1910 y +Fl(Control-u:)22 b(universal-argument)675 1962 y(Meta-Rubout:)g +(backward-kill-word)675 2014 y(Control-o:)g(">)i(output")555 +2082 y Fm(In)c(the)f(ab)q(o)o(v)o(e)g(example,)i Fg(C-u)e +Fm(is)h(b)q(ound)g(to)f(the)g(function)h Fl(universal-)555 +2137 y(argument)p Fm(,)e Fg(M-DEL)h Fm(is)g(b)q(ound)h(to)e(the)h +(function)h Fl(backward-kill-word)p Fm(,)555 2191 y(and)g +Fg(C-o)f Fm(is)h(b)q(ound)g(to)f(run)h(the)f(macro)g(expressed)h(on)g +(the)f(righ)o(t)h(hand)555 2246 y(side)c(\(that)e(is,)i(to)e(insert)i +(the)f(text)g(`)p Fl(>)f(output)p Fm(')g(in)o(to)i(the)f(line\).)555 +2314 y(A)k(n)o(um)o(b)q(er)f(of)g(sym)o(b)q(olic)i(c)o(haracter)e +(names)g(are)g(recognized)i(while)g(pro-)555 2369 y(cessing)13 +b(this)f(k)o(ey)g(binding)h(syn)o(tax:)18 b Fc(DEL)p +Fm(,)11 b Fc(ESC)p Fm(,)h Fc(ESCAPE)p Fm(,)f Fc(LFD)p +Fm(,)g Fc(NEW-)555 2424 y(LINE)p Fm(,)16 b Fc(RET)p Fm(,)e +Fc(RETURN)p Fm(,)f Fc(R)o(UBOUT)p Fm(,)i Fc(SP)l(A)o(CE)p +Fm(,)g Fc(SPC)p Fm(,)f(and)i Fc(T)l(AB)p Fm(.)315 2506 +y Fl(")p Fc(k)o(eyseq)q Fl(")p Fm(:)k Fc(function-name)e +Fm(or)d Fc(macro)555 2560 y(k)o(eyseq)i Fm(di\013ers)e(from)g +Fc(k)o(eyname)j Fm(ab)q(o)o(v)o(e)d(in)i(that)d(strings)i(denoting)g +(an)f(en-)555 2615 y(tire)i(k)o(ey)g(sequence)h(can)f(b)q(e)g(sp)q +(eci\014ed,)i(b)o(y)e(placing)h(the)f(k)o(ey)g(sequence)h(in)555 +2670 y(double)e(quotes.)j(Some)c Fh(gnu)g Fm(Emacs)f(st)o(yle)h(k)o(ey) +g(escap)q(es)g(can)g(b)q(e)g(used,)g(as)p eop +%%Page: 8 10 +8 9 bop 75 -58 a Fm(8)1322 b(GNU)15 b(Readline)h(Library)555 +149 y(in)i(the)f(follo)o(wing)g(example,)h(but)f(the)g(sp)q(ecial)i(c)o +(haracter)d(names)h(are)f(not)555 204 y(recognized.)675 +270 y Fl("\\C-u":)23 b(universal-argument)675 322 y("\\C-x\\C-r":)f +(re-read-init-file)675 373 y("\\e[11~":)h("Function)f(Key)i(1")555 +442 y Fm(In)33 b(the)f(ab)q(o)o(v)o(e)g(example,)37 b +Fg(C-u)32 b Fm(is)h(again)f(b)q(ound)h(to)f(the)g(function)555 +497 y Fl(universal-argument)19 b Fm(\(just)j(as)f(it)h(w)o(as)f(in)i +(the)f(\014rst)f(example\),)j(`)p Fg(C-x)555 551 y(C-r)p +Fm(')c(is)h(b)q(ound)g(to)f(the)h(function)g Fl(re-read-init-file)p +Fm(,)f(and)g(`)1731 549 y Ff(h)p 1743 523 70 2 v 1743 +551 a Fe(ESC)p 1743 559 V 1810 549 a Ff(i)15 b(h)p 1852 +523 10 2 v 1852 551 a Fe([)p 1852 560 V 1860 549 a Ff(i)555 +604 y(h)p 567 578 18 2 v 567 606 a Fe(1)p 567 614 V 583 +604 a Ff(i)g(h)p 625 578 V 625 606 a Fe(1)p 625 614 V +640 604 a Ff(i)g(h)p 683 578 24 2 v 683 606 a Fl(~)p +683 614 V 704 604 a Ff(i)719 606 y Fm(')g(is)h(b)q(ound)g(to)e(insert)i +(the)f(text)g(`)p Fl(Function)f(Key)g(1)p Fm('.)315 688 +y(The)h(follo)o(wing)h Fh(gnu)e Fm(Emacs)h(st)o(yle)g(escap)q(e)h +(sequences)g(are)e(a)o(v)m(ailable)j(when)e(sp)q(ecifying)315 +743 y(k)o(ey)g(sequences:)315 825 y Fg(\\C-)168 b Fm(con)o(trol)15 +b(pre\014x)315 907 y Fg(\\M-)168 b Fm(meta)15 b(pre\014x)315 +989 y Fg(\\e)192 b Fm(an)15 b(escap)q(e)h(c)o(haracter)315 +1071 y Fg(\\\\)192 b Fm(bac)o(kslash)315 1152 y Fg(\\)p +Fl(")555 1150 y Ff(h)p 567 1124 V 567 1152 a Fl(")p 567 +1160 V 589 1150 a Ff(i)604 1152 y Fm(,)15 b(a)f(double)j(quotation)e +(mark)315 1234 y Fg(\\')555 1232 y Ff(h)p 567 1206 10 +2 v 567 1234 a Fe(')p 567 1242 V 575 1232 a Ff(i)590 +1234 y Fm(,)g(a)f(single)j(quote)e(or)g(ap)q(ostrophe)315 +1316 y(In)f(addition)h(to)f(the)f Fh(gnu)h Fm(Emacs)g(st)o(yle)f(escap) +q(e)i(sequences,)g(a)e(second)i(set)e(of)h(bac)o(kslash)315 +1371 y(escap)q(es)i(is)g(a)o(v)m(ailable:)315 1453 y +Fl(\\a)192 b Fm(alert)15 b(\(b)q(ell\))315 1535 y Fl(\\b)192 +b Fm(bac)o(kspace)315 1617 y Fl(\\d)g Fm(delete)315 1699 +y Fl(\\f)g Fm(form)14 b(feed)315 1781 y Fl(\\n)192 b +Fm(newline)315 1862 y Fl(\\r)g Fm(carriage)15 b(return)315 +1944 y Fl(\\t)192 b Fm(horizon)o(tal)16 b(tab)315 2026 +y Fl(\\v)192 b Fm(v)o(ertical)16 b(tab)315 2108 y Fl(\\)p +Fc(nnn)141 b Fm(the)17 b(eigh)o(t-bit)h(c)o(haracter)f(whose)g(v)m +(alue)i(is)e(the)h(o)q(ctal)f(v)m(alue)i Fc(nnn)f Fm(\(one)f(to)555 +2163 y(three)e(digits\))315 2245 y Fl(\\x)p Fc(HH)124 +b Fm(the)20 b(eigh)o(t-bit)g(c)o(haracter)f(whose)h(v)m(alue)h(is)f +(the)g(hexadecimal)h(v)m(alue)g Fc(HH)555 2300 y Fm(\(one)15 +b(or)g(t)o(w)o(o)f(hex)h(digits\))315 2382 y(When)k(en)o(tering)g(the)g +(text)f(of)g(a)h(macro,)f(single)i(or)e(double)i(quotes)f(m)o(ust)f(b)q +(e)h(used)h(to)315 2436 y(indicate)12 b(a)f(macro)f(de\014nition.)20 +b(Unquoted)11 b(text)f(is)i(assumed)e(to)h(b)q(e)g(a)f(function)i +(name.)18 b(In)315 2491 y(the)11 b(macro)f(b)q(o)q(dy)l(,)i(the)f(bac)o +(kslash)g(escap)q(es)g(describ)q(ed)i(ab)q(o)o(v)o(e)d(are)g(expanded.) +20 b(Bac)o(kslash)315 2546 y(will)i(quote)d(an)o(y)h(other)g(c)o +(haracter)f(in)i(the)f(macro)f(text,)h(including)j(`)p +Fl(")p Fm(')c(and)h(`)p Fl(')p Fm('.)34 b(F)l(or)315 +2601 y(example,)14 b(the)f(follo)o(wing)g(binding)i(will)g(mak)o(e)d(`) +p Fg(C-x)i Fl(\\)p Fm(')f(insert)g(a)g(single)h(`)p Fl(\\)p +Fm(')e(in)o(to)h(the)g(line:)435 2666 y Fl("\\C-x\\\\":)23 +b("\\\\")p eop +%%Page: 9 11 +9 10 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1077 +b(9)75 149 y Fb(1.3.2)30 b(Conditional)20 b(Init)g(Constructs)137 +246 y Fm(Readline)f(implemen)o(ts)g(a)f(facilit)o(y)g(similar)h(in)g +(spirit)f(to)f(the)h(conditional)h(compilation)g(features)75 +301 y(of)e(the)g(C)g(prepro)q(cessor)g(whic)o(h)i(allo)o(ws)e(k)o(ey)g +(bindings)i(and)f(v)m(ariable)g(settings)f(to)g(b)q(e)h(p)q(erformed)f +(as)75 355 y(the)e(result)h(of)f(tests.)k(There)c(are)g(four)g(parser)g +(directiv)o(es)h(used.)75 435 y Fl($if)168 b Fm(The)16 +b Fl($if)f Fm(construct)g(allo)o(ws)h(bindings)i(to)d(b)q(e)h(made)g +(based)g(on)f(the)h(editing)h(mo)q(de,)f(the)315 490 +y(terminal)k(b)q(eing)g(used,)g(or)f(the)g(application)i(using)e +(Readline.)33 b(The)19 b(text)g(of)f(the)i(test)315 545 +y(extends)c(to)e(the)h(end)h(of)f(the)g(line;)i(no)e(c)o(haracters)f +(are)h(required)i(to)d(isolate)i(it.)315 624 y Fl(mode)144 +b Fm(The)11 b Fl(mode=)e Fm(form)h(of)g(the)h Fl($if)f +Fm(directiv)o(e)h(is)g(used)g(to)f(test)g(whether)h(Readline)555 +679 y(is)k(in)h Fl(emacs)e Fm(or)g Fl(vi)g Fm(mo)q(de.)20 +b(This)c(ma)o(y)e(b)q(e)h(used)g(in)h(conjunction)g(with)f(the)555 +734 y(`)p Fl(set)f(keymap)p Fm(')f(command,)g(for)h(instance,)g(to)f +(set)h(bindings)h(in)g(the)f Fl(emacs-)555 789 y(standard)d +Fm(and)i Fl(emacs-ctlx)e Fm(k)o(eymaps)h(only)i(if)f(Readline)g(is)g +(starting)f(out)555 844 y(in)k Fl(emacs)f Fm(mo)q(de.)315 +923 y Fl(term)144 b Fm(The)14 b Fl(term=)e Fm(form)h(ma)o(y)g(b)q(e)h +(used)g(to)f(include)j(terminal-sp)q(eci\014c)g(k)o(ey)d(bind-)555 +978 y(ings,)19 b(p)q(erhaps)g(to)e(bind)i(the)g(k)o(ey)e(sequences)j +(output)e(b)o(y)g(the)g(terminal's)555 1033 y(function)13 +b(k)o(eys.)18 b(The)13 b(w)o(ord)e(on)h(the)g(righ)o(t)g(side)g(of)g +(the)g(`)p Fl(=)p Fm(')f(is)h(tested)g(against)555 1088 +y(b)q(oth)j(the)g(full)i(name)e(of)f(the)h(terminal)h(and)f(the)g(p)q +(ortion)h(of)e(the)h(terminal)555 1142 y(name)i(b)q(efore)g(the)g +(\014rst)f(`)p Fl(-)p Fm('.)24 b(This)17 b(allo)o(ws)g +Fl(sun)f Fm(to)g(matc)o(h)h(b)q(oth)f Fl(sun)h Fm(and)555 +1197 y Fl(sun-cmd)p Fm(,)d(for)g(instance.)315 1277 y +Fl(application)555 1332 y Fm(The)d Fc(application)i Fm(construct)e(is)g +(used)h(to)e(include)j(application-sp)q(eci)q(\014c)h(set-)555 +1386 y(tings.)19 b(Eac)o(h)12 b(program)f(using)j(the)e(Readline)i +(library)f(sets)f(the)g Fc(application)555 1441 y(name)p +Fm(,)g(and)g(y)o(ou)f(can)h(test)f(for)g(a)g(particular)h(v)m(alue.)20 +b(This)12 b(could)h(b)q(e)f(used)h(to)555 1496 y(bind)18 +b(k)o(ey)e(sequences)i(to)d(functions)j(useful)f(for)f(a)g(sp)q +(eci\014c)i(program.)23 b(F)l(or)555 1551 y(instance,)17 +b(the)g(follo)o(wing)g(command)g(adds)f(a)g(k)o(ey)h(sequence)g(that)f +(quotes)555 1606 y(the)f(curren)o(t)g(or)g(previous)h(w)o(ord)e(in)j +(Bash:)675 1670 y Fl($if)23 b(Bash)675 1722 y(#)h(Quote)f(the)g +(current)g(or)h(previous)f(word)675 1774 y("\\C-xq":)g +("\\eb\\"\\ef\\"")675 1826 y($endif)75 1905 y($endif)96 +b Fm(This)16 b(command,)e(as)h(seen)h(in)g(the)f(previous)h(example,)g +(terminates)f(an)g Fl($if)f Fm(command.)75 1985 y Fl($else)120 +b Fm(Commands)15 b(in)h(this)f(branc)o(h)h(of)e(the)i +Fl($if)e Fm(directiv)o(e)j(are)e(executed)h(if)g(the)f(test)g(fails.)75 +2065 y Fl($include)48 b Fm(This)22 b(directiv)o(e)h(tak)o(es)e(a)h +(single)h(\014lename)g(as)e(an)h(argumen)o(t)f(and)h(reads)f(commands) +315 2120 y(and)e(bindings)j(from)c(that)h(\014le.)33 +b(F)l(or)19 b(example,)i(the)e(follo)o(wing)h(directiv)o(e)h(reads)e +(from)315 2174 y(`)p Fl(/etc/inputrc)p Fm(':)435 2239 +y Fl($include)k(/etc/inputrc)75 2351 y Fb(1.3.3)30 b(Sample)20 +b(Init)h(File)137 2447 y Fm(Here)16 b(is)g(an)f(example)h(of)f(an)g +Fc(inputrc)k Fm(\014le.)i(This)16 b(illustrates)g(k)o(ey)f(binding,)i +(v)m(ariable)f(assignmen)o(t,)75 2502 y(and)f(conditional)i(syn)o(tax.) +p eop +%%Page: 10 12 +10 11 bop 75 -58 a Fm(10)1299 b(GNU)15 b(Readline)h(Library)195 +201 y Fl(#)24 b(This)f(file)g(controls)g(the)h(behaviour)e(of)i(line)f +(input)g(editing)g(for)195 253 y(#)h(programs)e(that)i(use)f(the)h(GNU) +f(Readline)g(library.)47 b(Existing)195 305 y(#)24 b(programs)e +(include)h(FTP,)h(Bash,)f(and)g(GDB.)195 357 y(#)195 +409 y(#)h(You)f(can)h(re-read)f(the)g(inputrc)g(file)g(with)h(C-x)f +(C-r.)195 461 y(#)h(Lines)f(beginning)g(with)g('#')g(are)h(comments.) +195 513 y(#)195 565 y(#)g(First,)f(include)g(any)g(systemwide)g +(bindings)f(and)i(variable)195 616 y(#)g(assignments)e(from)h +(/etc/Inputrc)195 668 y($include)g(/etc/Inputrc)195 772 +y(#)195 824 y(#)h(Set)f(various)g(bindings)g(for)g(emacs)g(mode.)195 +928 y(set)g(editing-mode)g(emacs)195 1032 y($if)g(mode=emacs)195 +1135 y(Meta-Control-h:)46 b(backward-kill-word)21 b(Text)i(after)h(the) +f(function)g(name)g(is)h(ignored)p 1986 1145 21 38 v +195 1239 a(#)195 1291 y(#)g(Arrow)f(keys)g(in)h(keypad)f(mode)195 +1343 y(#)195 1395 y(#"\\M-OD":)190 b(backward-char)195 +1447 y(#"\\M-OC":)g(forward-char)195 1499 y(#"\\M-OA":)g +(previous-history)195 1550 y(#"\\M-OB":)g(next-history)195 +1602 y(#)195 1654 y(#)24 b(Arrow)f(keys)g(in)h(ANSI)f(mode)195 +1706 y(#)195 1758 y("\\M-[D":)190 b(backward-char)195 +1810 y("\\M-[C":)g(forward-char)195 1862 y("\\M-[A":)g +(previous-history)195 1914 y("\\M-[B":)g(next-history)195 +1966 y(#)195 2017 y(#)24 b(Arrow)f(keys)g(in)h(8)g(bit)f(keypad)g(mode) +195 2069 y(#)195 2121 y(#"\\M-\\C-OD":)165 b(backward-char)195 +2173 y(#"\\M-\\C-OC":)g(forward-char)195 2225 y(#"\\M-\\C-OA":)g +(previous-history)195 2277 y(#"\\M-\\C-OB":)g(next-history)195 +2329 y(#)195 2381 y(#)24 b(Arrow)f(keys)g(in)h(8)g(bit)f(ANSI)g(mode) +195 2433 y(#)195 2484 y(#"\\M-\\C-[D":)165 b(backward-char)195 +2536 y(#"\\M-\\C-[C":)g(forward-char)195 2588 y(#"\\M-\\C-[A":)g +(previous-history)195 2640 y(#"\\M-\\C-[B":)g(next-history)p +eop +%%Page: 11 13 +11 12 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(11)195 201 y Fl(C-q:)23 b(quoted-insert)195 305 y($endif)195 +409 y(#)h(An)f(old-style)g(binding.)47 b(This)23 b(happens)g(to)g(be)h +(the)f(default.)195 461 y(TAB:)g(complete)195 565 y(#)h(Macros)f(that)g +(are)h(convenient)e(for)h(shell)h(interaction)195 616 +y($if)f(Bash)195 668 y(#)h(edit)f(the)g(path)195 720 +y("\\C-xp":)g("PATH=${PATH}\\e\\C-e\\C-a\\)o(ef\\C-f")195 +772 y(#)h(prepare)f(to)g(type)h(a)f(quoted)g(word)h(--)195 +824 y(#)g(insert)f(open)g(and)h(close)f(double)g(quotes)195 +876 y(#)h(and)f(move)g(to)h(just)f(after)h(the)f(open)g(quote)195 +928 y("\\C-x\\"":)g("\\"\\"\\C-b")195 980 y(#)h(insert)f(a)g(backslash) +g(\(testing)g(backslash)g(escapes)195 1032 y(#)h(in)f(sequences)g(and)g +(macros\))195 1083 y("\\C-x\\\\":)g("\\\\")195 1135 y(#)h(Quote)f(the)g +(current)g(or)h(previous)f(word)195 1187 y("\\C-xq":)g +("\\eb\\"\\ef\\"")195 1239 y(#)h(Add)f(a)h(binding)f(to)g(refresh)g +(the)h(line,)f(which)g(is)h(unbound)195 1291 y("\\C-xr":)f +(redraw-current-line)195 1343 y(#)h(Edit)f(variable)g(on)g(current)g +(line.)195 1395 y("\\M-\\C-v":)f("\\C-a\\C-k$\\C-y\\M-\\C-e\\C-a\\C-y=) +o(")195 1447 y($endif)195 1550 y(#)i(use)f(a)h(visible)f(bell)g(if)h +(one)f(is)h(available)195 1602 y(set)f(bell-style)g(visible)195 +1706 y(#)h(don't)f(strip)g(characters)g(to)g(7)h(bits)f(when)h(reading) +195 1758 y(set)f(input-meta)g(on)195 1862 y(#)h(allow)f(iso-latin1)f +(characters)h(to)g(be)h(inserted)f(rather)195 1914 y(#)h(than)f +(converted)g(to)g(prefix-meta)g(sequences)195 1966 y(set)g +(convert-meta)g(off)195 2069 y(#)h(display)f(characters)f(with)h(the)h +(eighth)f(bit)g(set)h(directly)195 2121 y(#)g(rather)f(than)g(as)h +(meta-prefixed)e(characters)195 2173 y(set)h(output-meta)g(on)195 +2277 y(#)h(if)f(there)g(are)h(more)f(than)h(150)f(possible)g +(completions)f(for)195 2329 y(#)i(a)f(word,)h(ask)f(the)h(user)f(if)g +(he)h(wants)f(to)h(see)f(all)h(of)f(them)195 2381 y(set)g +(completion-query-items)e(150)195 2484 y(#)j(For)f(FTP)195 +2536 y($if)g(Ftp)195 2588 y("\\C-xg":)g("get)g(\\M-?")195 +2640 y("\\C-xt":)g("put)g(\\M-?")p eop +%%Page: 12 14 +12 13 bop 75 -58 a Fm(12)1299 b(GNU)15 b(Readline)h(Library)195 +149 y Fl("\\M-.":)23 b(yank-last-arg)195 201 y($endif)75 +329 y Fk(1.4)33 b(Bindable)24 b(Readline)f(Commands)137 +425 y Fm(This)17 b(section)f(describ)q(es)h(Readline)g(commands)f(that) +e(ma)o(y)h(b)q(e)i(b)q(ound)f(to)f(k)o(ey)h(sequences.)22 +b(Com-)75 480 y(mand)15 b(names)g(without)h(an)f(accompan)o(ying)g(k)o +(ey)g(sequence)i(are)e(un)o(b)q(ound)h(b)o(y)f(default.)137 +547 y(In)f(the)f(follo)o(wing)h(descriptions,)h Fc(p)q(oin)o(t)f +Fm(refers)f(to)g(the)g(curren)o(t)g(cursor)f(p)q(osition,)j(and)e +Fc(mark)i Fm(refers)75 601 y(to)k(a)g(cursor)g(p)q(osition)h(sa)o(v)o +(ed)f(b)o(y)h(the)f Fl(set-mark)g Fm(command.)32 b(The)20 +b(text)f(b)q(et)o(w)o(een)g(the)h(p)q(oin)o(t)g(and)75 +656 y(mark)15 b(is)g(referred)h(to)e(as)h(the)g Fc(region)p +Fm(.)75 767 y Fb(1.4.1)30 b(Commands)21 b(F)-5 b(or)19 +b(Mo)n(ving)75 888 y Fl(beginning-of-line)13 b(\(C-a\))315 +942 y Fm(Mo)o(v)o(e)h(to)h(the)g(start)f(of)h(the)g(curren)o(t)g(line.) +75 1034 y Fl(end-of-line)f(\(C-e\))315 1088 y Fm(Mo)o(v)o(e)g(to)h(the) +g(end)h(of)f(the)g(line.)75 1179 y Fl(forward-char)f(\(C-f\))315 +1234 y Fm(Mo)o(v)o(e)g(forw)o(ard)g(a)h(c)o(haracter.)75 +1325 y Fl(backward-char)e(\(C-b\))315 1380 y Fm(Mo)o(v)o(e)h(bac)o(k)h +(a)g(c)o(haracter.)75 1471 y Fl(forward-word)f(\(M-f\))315 +1526 y Fm(Mo)o(v)o(e)g(forw)o(ard)g(to)g(the)i(end)g(of)e(the)h(next)h +(w)o(ord.)j(W)l(ords)c(are)f(comp)q(osed)i(of)f(letters)g(and)315 +1581 y(digits.)75 1672 y Fl(backward-word)e(\(M-b\))315 +1727 y Fm(Mo)o(v)o(e)j(bac)o(k)g(to)h(the)f(start)g(of)g(the)h(curren)o +(t)g(or)f(previous)i(w)o(ord.)24 b(W)l(ords)16 b(are)h(comp)q(osed)315 +1782 y(of)e(letters)g(and)g(digits.)75 1873 y Fl(clear-screen)f +(\(C-l\))315 1928 y Fm(Clear)f(the)h(screen)g(and)f(redra)o(w)g(the)g +(curren)o(t)g(line,)i(lea)o(ving)g(the)e(curren)o(t)g(line)i(at)e(the)g +(top)315 1982 y(of)i(the)g(screen.)75 2074 y Fl(redraw-current-line)e +(\(\))315 2128 y Fm(Refresh)i(the)g(curren)o(t)g(line.)22 +b(By)15 b(default,)h(this)f(is)h(un)o(b)q(ound.)75 2239 +y Fb(1.4.2)30 b(Commands)21 b(F)-5 b(or)19 b(Manipulating)i(The)f +(History)75 2360 y Fl(accept-line)14 b(\(Newline)g(or)h(Return\))315 +2414 y Fm(Accept)j(the)g(line)h(regardless)f(of)f(where)h(the)g(cursor) +f(is.)27 b(If)18 b(this)g(line)h(is)g(non-empt)o(y)l(,)f(it)315 +2469 y(ma)o(y)d(b)q(e)i(added)f(to)g(the)g(history)g(list)g(for)g +(future)g(recall)h(with)f Fl(add_history\(\))p Fm(.)k(If)d(this)315 +2524 y(line)g(is)f(a)e(mo)q(di\014ed)j(history)e(line,)i(the)e(history) +g(line)i(is)f(restored)e(to)h(its)g(original)i(state.)75 +2615 y Fl(previous-history)c(\(C-p\))315 2670 y Fm(Mo)o(v)o(e)h(`bac)o +(k')h(through)f(the)i(history)f(list,)g(fetc)o(hing)h(the)f(previous)h +(command.)p eop +%%Page: 13 15 +13 14 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(13)75 149 y Fl(next-history)14 b(\(C-n\))315 204 y +Fm(Mo)o(v)o(e)g(`forw)o(ard')f(through)i(the)h(history)f(list,)g(fetc)o +(hing)h(the)f(next)h(command.)75 307 y Fl(beginning-of-history)c +(\(M-<\))315 362 y Fm(Mo)o(v)o(e)i(to)h(the)g(\014rst)g(line)i(in)f +(the)f(history)l(.)75 465 y Fl(end-of-history)e(\(M->\))315 +520 y Fm(Mo)o(v)o(e)h(to)h(the)g(end)h(of)f(the)g(input)h(history)l(,)f +(i.e.,)g(the)g(line)i(curren)o(tly)f(b)q(eing)g(en)o(tered.)75 +624 y Fl(reverse-search-history)c(\(C-r\))315 678 y Fm(Searc)o(h)k(bac) +o(kw)o(ard)e(starting)h(at)g(the)h(curren)o(t)f(line)j(and)d(mo)o(ving) +h(`up')f(through)g(the)h(his-)315 733 y(tory)e(as)h(necessary)l(.)20 +b(This)c(is)g(an)f(incremen)o(tal)h(searc)o(h.)75 836 +y Fl(forward-search-history)c(\(C-s\))315 891 y Fm(Searc)o(h)j(forw)o +(ard)e(starting)h(at)h(the)f(curren)o(t)h(line)h(and)f(mo)o(ving)g(`do) +o(wn')f(through)g(the)h(the)315 946 y(history)g(as)g(necessary)l(.)20 +b(This)c(is)g(an)f(incremen)o(tal)h(searc)o(h.)75 1049 +y Fl(non-incremental-reverse-se)o(arch-hi)o(story)c(\(M-p\))315 +1104 y Fm(Searc)o(h)k(bac)o(kw)o(ard)e(starting)h(at)g(the)h(curren)o +(t)f(line)j(and)d(mo)o(ving)h(`up')f(through)g(the)h(his-)315 +1159 y(tory)h(as)h(necessary)g(using)h(a)e(non-incremen)o(tal)j(searc)o +(h)e(for)f(a)h(string)g(supplied)i(b)o(y)e(the)315 1214 +y(user.)75 1317 y Fl(non-incremental-forward-se)o(arch-hi)o(story)12 +b(\(M-n\))315 1372 y Fm(Searc)o(h)j(forw)o(ard)e(starting)h(at)h(the)f +(curren)o(t)h(line)h(and)f(mo)o(ving)g(`do)o(wn')f(through)g(the)h(the) +315 1426 y(history)e(as)g(necessary)h(using)g(a)f(non-incremen)o(tal)i +(searc)o(h)e(for)g(a)g(string)g(supplied)j(b)o(y)d(the)315 +1481 y(user.)75 1584 y Fl(history-search-forward)f(\(\))315 +1639 y Fm(Searc)o(h)21 b(forw)o(ard)e(through)i(the)f(history)h(for)f +(the)h(string)g(of)f(c)o(haracters)g(b)q(et)o(w)o(een)h(the)315 +1694 y(start)16 b(of)h(the)h(curren)o(t)g(line)h(and)e(the)h(p)q(oin)o +(t.)28 b(This)18 b(is)g(a)f(non-incremen)o(tal)i(searc)o(h.)27 +b(By)315 1749 y(default,)15 b(this)h(command)f(is)h(un)o(b)q(ound.)75 +1852 y Fl(history-search-backward)c(\(\))315 1907 y Fm(Searc)o(h)18 +b(bac)o(kw)o(ard)e(through)h(the)h(history)f(for)g(the)g(string)h(of)f +(c)o(haracters)f(b)q(et)o(w)o(een)i(the)315 1962 y(start)e(of)h(the)h +(curren)o(t)g(line)h(and)e(the)h(p)q(oin)o(t.)28 b(This)18 +b(is)g(a)f(non-incremen)o(tal)i(searc)o(h.)27 b(By)315 +2016 y(default,)15 b(this)h(command)f(is)h(un)o(b)q(ound.)75 +2120 y Fl(yank-nth-arg)e(\(M-C-y\))315 2174 y Fm(Insert)f(the)g +(\014rst)g(argumen)o(t)f(to)g(the)i(previous)f(command)g(\(usually)h +(the)f(second)h(w)o(ord)e(on)315 2229 y(the)j(previous)h(line\))g(at)e +(p)q(oin)o(t.)21 b(With)15 b(an)g(argumen)o(t)f Fc(n)p +Fm(,)h(insert)g(the)g Fc(n)p Fm(th)g(w)o(ord)g(from)f(the)315 +2284 y(previous)g(command)g(\(the)f(w)o(ords)f(in)j(the)e(previous)i +(command)e(b)q(egin)i(with)e(w)o(ord)g(0\).)19 b(A)315 +2339 y(negativ)o(e)13 b(argumen)o(t)f(inserts)h(the)g +Fc(n)p Fm(th)g(w)o(ord)f(from)g(the)h(end)h(of)e(the)h(previous)g +(command.)75 2442 y Fl(yank-last-arg)g(\(M-.)i(or)g(M-_\))315 +2497 y Fm(Insert)j(last)f(argumen)o(t)g(to)g(the)g(previous)i(command)e +(\(the)g(last)h(w)o(ord)f(of)g(the)g(previous)315 2552 +y(history)e(en)o(try\).)20 b(With)15 b(an)g(argumen)o(t,)g(b)q(eha)o(v) +o(e)g(exactly)h(lik)o(e)g Fl(yank-nth-arg)p Fm(.)j(Succes-)315 +2606 y(siv)o(e)f(calls)g(to)f Fl(yank-last-arg)e Fm(mo)o(v)o(e)i(bac)o +(k)g(through)g(the)g(history)g(list,)i(inserting)f(the)315 +2661 y(last)d(argumen)o(t)g(of)f(eac)o(h)i(line)g(in)g(turn.)p +eop +%%Page: 14 16 +14 15 bop 75 -58 a Fm(14)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fb(1.4.3)30 b(Commands)21 b(F)-5 b(or)19 b(Changing)i(T)-5 +b(ext)75 286 y Fl(delete-char)14 b(\(C-d\))315 341 y +Fm(Delete)20 b(the)g(c)o(haracter)e(at)h(p)q(oin)o(t.)33 +b(If)20 b(p)q(oin)o(t)g(is)g(at)e(the)i(b)q(eginning)i(of)d(the)g +(line,)j(there)315 396 y(are)c(no)h(c)o(haracters)e(in)j(the)e(line,)j +(and)e(the)f(last)h(c)o(haracter)e(t)o(yp)q(ed)i(w)o(as)f(not)g(b)q +(ound)i(to)315 450 y Fl(delete-char)p Fm(,)13 b(then)j(return)f +Fh(eof)p Fm(.)75 552 y Fl(backward-delete-char)d(\(Rubout\))315 +607 y Fm(Delete)k(the)f(c)o(haracter)f(b)q(ehind)j(the)f(cursor.)j(A)c +(n)o(umeric)h(argumen)o(t)e(means)i(to)e(kill)j(the)315 +661 y(c)o(haracters)d(instead)i(of)f(deleting)i(them.)75 +763 y Fl(forward-backward-delete-ch)o(ar)12 b(\(\))315 +818 y Fm(Delete)20 b(the)f(c)o(haracter)f(under)i(the)f(cursor,)h +(unless)g(the)f(cursor)g(is)h(at)e(the)h(end)h(of)f(the)315 +872 y(line,)e(in)g(whic)o(h)g(case)e(the)h(c)o(haracter)g(b)q(ehind)h +(the)f(cursor)g(is)g(deleted.)23 b(By)16 b(default,)h(this)315 +927 y(is)f(not)f(b)q(ound)h(to)e(a)h(k)o(ey)l(.)75 1029 +y Fl(quoted-insert)e(\(C-q)i(or)g(C-v\))315 1083 y Fm(Add)j(the)f(next) +g(c)o(haracter)g(t)o(yp)q(ed)g(to)f(the)i(line)g(v)o(erbatim.)26 +b(This)18 b(is)f(ho)o(w)g(to)g(insert)g(k)o(ey)315 1138 +y(sequences)f(lik)o(e)h Fg(C-q)p Fm(,)d(for)h(example.)75 +1240 y Fl(tab-insert)f(\(M-)401 1238 y Ff(h)p 412 1212 +74 2 v 412 1240 a Fe(T)m(AB)p 412 1247 V 484 1238 a Ff(i)499 +1240 y Fl(\))315 1294 y Fm(Insert)h(a)g(tab)g(c)o(haracter.)75 +1396 y Fl(self-insert)f(\(a,)g(b,)h(A,)g(1,)g(!,)g(...)o(\))315 +1451 y Fm(Insert)g(y)o(ourself.)75 1552 y Fl(transpose-chars)e(\(C-t\)) +315 1607 y Fm(Drag)i(the)h(c)o(haracter)f(b)q(efore)h(the)h(cursor)e +(forw)o(ard)g(o)o(v)o(er)g(the)h(c)o(haracter)f(at)h(the)g(cursor,)315 +1662 y(mo)o(ving)i(the)f(cursor)h(forw)o(ard)e(as)i(w)o(ell.)28 +b(If)18 b(the)g(insertion)h(p)q(oin)o(t)f(is)g(at)f(the)h(end)h(of)e +(the)315 1716 y(line,)c(then)e(this)h(transp)q(oses)e(the)h(last)g(t)o +(w)o(o)f(c)o(haracters)g(of)h(the)g(line.)20 b(Negativ)o(e)11 +b(argumen)o(ts)315 1771 y(ha)o(v)o(e)k(no)g(e\013ect.)75 +1873 y Fl(transpose-words)e(\(M-t\))315 1927 y Fm(Drag)i(the)h(w)o(ord) +g(b)q(efore)g(p)q(oin)o(t)h(past)f(the)g(w)o(ord)f(after)h(p)q(oin)o +(t,)g(mo)o(ving)g(p)q(oin)o(t)h(past)f(that)315 1982 +y(w)o(ord)d(as)h(w)o(ell.)21 b(If)14 b(the)g(insertion)i(p)q(oin)o(t)e +(is)h(at)f(the)g(end)h(of)e(the)i(line,)g(this)g(transp)q(oses)f(the) +315 2037 y(last)h(t)o(w)o(o)f(w)o(ords)g(on)i(the)f(line.)75 +2138 y Fl(upcase-word)f(\(M-u\))315 2193 y Fm(Upp)q(ercase)j(the)f +(curren)o(t)g(\(or)f(follo)o(wing\))h(w)o(ord.)22 b(With)16 +b(a)g(negativ)o(e)g(argumen)o(t,)f(upp)q(er-)315 2248 +y(case)g(the)g(previous)h(w)o(ord,)f(but)g(do)g(not)g(mo)o(v)o(e)f(the) +i(cursor.)75 2349 y Fl(downcase-word)d(\(M-l\))315 2404 +y Fm(Lo)o(w)o(ercase)d(the)h(curren)o(t)g(\(or)f(follo)o(wing\))h(w)o +(ord.)17 b(With)11 b(a)g(negativ)o(e)g(argumen)o(t,)f(lo)o(w)o(ercase) +315 2459 y(the)15 b(previous)h(w)o(ord,)e(but)i(do)f(not)g(mo)o(v)o(e)f +(the)h(cursor.)75 2560 y Fl(capitalize-word)e(\(M-c\))315 +2615 y Fm(Capitalize)f(the)f(curren)o(t)f(\(or)g(follo)o(wing\))h(w)o +(ord.)18 b(With)11 b(a)f(negativ)o(e)h(argumen)o(t,)f(capitalize)315 +2670 y(the)15 b(previous)h(w)o(ord,)e(but)i(do)f(not)g(mo)o(v)o(e)f +(the)h(cursor.)p eop +%%Page: 15 17 +15 16 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(15)75 149 y Fl(overwrite-mode)13 b(\(\))315 204 y Fm(T)l(oggle)j(o)o +(v)o(erwrite)g(mo)q(de.)24 b(With)17 b(an)f(explicit)j(p)q(ositiv)o(e)f +(n)o(umeric)f(argumen)o(t,)f(switc)o(hes)315 259 y(to)10 +b(o)o(v)o(erwrite)g(mo)q(de.)19 b(With)11 b(an)g(explicit)i(non-p)q +(ositiv)o(e)f(n)o(umeric)g(argumen)o(t,)e(switc)o(hes)i(to)315 +314 y(insert)k(mo)q(de.)k(This)c(command)f(a\013ects)g(only)h +Fl(emacs)e Fm(mo)q(de;)h Fl(vi)g Fm(mo)q(de)h(do)q(es)g(o)o(v)o +(erwrite)315 369 y(di\013eren)o(tly)l(.)21 b(Eac)o(h)15 +b(call)h(to)f Fl(readline\(\))f Fm(starts)f(in)k(insert)e(mo)q(de.)315 +436 y(In)g(o)o(v)o(erwrite)f(mo)q(de,)h(c)o(haracters)f(b)q(ound)h(to)f +Fl(self-insert)f Fm(replace)j(the)e(text)h(at)e(p)q(oin)o(t)315 +491 y(rather)20 b(than)h(pushing)h(the)f(text)f(to)g(the)h(righ)o(t.)36 +b(Characters)20 b(b)q(ound)i(to)e Fl(backward-)315 546 +y(delete-char)14 b Fm(replace)i(the)f(c)o(haracter)g(b)q(efore)g(p)q +(oin)o(t)h(with)f(a)g(space.)315 614 y(By)g(default,)h(this)f(command)g +(is)h(un)o(b)q(ound.)75 729 y Fb(1.4.4)30 b(Killing)20 +b(And)h(Y)-5 b(anking)75 853 y Fl(kill-line)14 b(\(C-k\))315 +908 y Fm(Kill)j(the)f(text)e(from)h(p)q(oin)o(t)h(to)e(the)h(end)h(of)f +(the)g(line.)75 1002 y Fl(backward-kill-line)e(\(C-x)h(Rubout\))315 +1057 y Fm(Kill)j(bac)o(kw)o(ard)e(to)f(the)i(b)q(eginning)h(of)e(the)g +(line.)75 1151 y Fl(unix-line-discard)e(\(C-u\))315 1205 +y Fm(Kill)k(bac)o(kw)o(ard)e(from)f(the)i(cursor)e(to)h(the)g(b)q +(eginning)j(of)c(the)i(curren)o(t)f(line.)75 1299 y Fl(kill-whole-line) +e(\(\))315 1354 y Fm(Kill)20 b(all)g(c)o(haracters)d(on)h(the)h(curren) +o(t)f(line,)i(no)e(matter)g(where)g(p)q(oin)o(t)h(is.)29 +b(By)19 b(default,)315 1409 y(this)d(is)f(un)o(b)q(ound.)75 +1503 y Fl(kill-word)f(\(M-d\))315 1558 y Fm(Kill)j(from)d(p)q(oin)o(t)h +(to)f(the)h(end)g(of)f(the)h(curren)o(t)g(w)o(ord,)e(or)i(if)g(b)q(et)o +(w)o(een)g(w)o(ords,)e(to)i(the)f(end)315 1613 y(of)h(the)g(next)g(w)o +(ord.)20 b(W)l(ord)14 b(b)q(oundaries)j(are)e(the)g(same)g(as)g +Fl(forward-word)p Fm(.)75 1707 y Fl(backward-kill-word)e(\(M-)592 +1705 y Ff(h)p 603 1679 73 2 v 603 1707 a Fe(DEL)p 603 +1714 V 674 1705 a Ff(i)689 1707 y Fl(\))315 1761 y Fm(Kill)k(the)d(w)o +(ord)g(b)q(ehind)i(p)q(oin)o(t.)21 b(W)l(ord)14 b(b)q(oundaries)h(are)f +(the)h(same)f(as)g Fl(backward-word)p Fm(.)75 1855 y +Fl(unix-word-rubout)f(\(C-w\))315 1910 y Fm(Kill)18 b(the)e(w)o(ord)f +(b)q(ehind)j(p)q(oin)o(t,)e(using)h(white)f(space)g(as)g(a)f(w)o(ord)g +(b)q(oundary)l(.)23 b(The)16 b(killed)315 1965 y(text)f(is)g(sa)o(v)o +(ed)g(on)g(the)h(kill-ring.)75 2059 y Fl(delete-horizontal-space)c +(\(\))315 2114 y Fm(Delete)k(all)g(spaces)f(and)h(tabs)e(around)i(p)q +(oin)o(t.)k(By)15 b(default,)h(this)f(is)h(un)o(b)q(ound.)75 +2208 y Fl(kill-region)e(\(\))315 2263 y Fm(Kill)j(the)f(text)e(in)i +(the)g(curren)o(t)f(region.)20 b(By)15 b(default,)h(this)f(command)g +(is)h(un)o(b)q(ound.)75 2357 y Fl(copy-region-as-kill)d(\(\))315 +2412 y Fm(Cop)o(y)j(the)i(text)e(in)i(the)f(region)g(to)g(the)g(kill)h +(bu\013er,)f(so)g(it)g(can)g(b)q(e)h(y)o(ank)o(ed)f(righ)o(t)g(a)o(w)o +(a)o(y)l(.)315 2466 y(By)e(default,)h(this)f(command)g(is)h(un)o(b)q +(ound.)75 2560 y Fl(copy-backward-word)d(\(\))315 2615 +y Fm(Cop)o(y)19 b(the)g(w)o(ord)g(b)q(efore)g(p)q(oin)o(t)h(to)e(the)i +(kill)h(bu\013er.)32 b(The)19 b(w)o(ord)g(b)q(oundaries)h(are)f(the)315 +2670 y(same)c(as)g Fl(backward-word)p Fm(.)j(By)d(default,)g(this)h +(command)f(is)h(un)o(b)q(ound.)p eop +%%Page: 16 18 +16 17 bop 75 -58 a Fm(16)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fl(copy-forward-word)d(\(\))315 204 y Fm(Cop)o(y)i(the)h(w)o(ord) +e(follo)o(wing)j(p)q(oin)o(t)f(to)f(the)g(kill)j(bu\013er.)i(The)c(w)o +(ord)f(b)q(oundaries)i(are)e(the)315 259 y(same)g(as)g +Fl(forward-word)p Fm(.)j(By)d(default,)h(this)f(command)g(is)h(un)o(b)q +(ound.)75 342 y Fl(yank)f(\(C-y\))315 397 y Fm(Y)l(ank)g(the)h(top)f +(of)f(the)i(kill)h(ring)e(in)o(to)g(the)h(bu\013er)f(at)f(p)q(oin)o(t.) +75 481 y Fl(yank-pop)g(\(M-y\))315 535 y Fm(Rotate)i(the)h(kill-ring,)j +(and)d(y)o(ank)g(the)h(new)f(top.)26 b(Y)l(ou)17 b(can)h(only)g(do)f +(this)h(if)f(the)h(prior)315 590 y(command)d(is)h Fl(yank)e +Fm(or)h Fl(yank-pop)p Fm(.)75 693 y Fb(1.4.5)30 b(Sp)r(ecifying)20 +b(Numeric)h(Argumen)n(ts)75 806 y Fl(digit-argument)13 +b(\()p Fg(M-0)p Fl(,)i Fg(M-1)p Fl(,)f(...)h Fg(M--)p +Fl(\))315 861 y Fm(Add)f(this)g(digit)g(to)f(the)h(argumen)o(t)e +(already)i(accum)o(ulating,)g(or)f(start)f(a)h(new)h(argumen)o(t.)315 +915 y Fg(M--)h Fm(starts)f(a)h(negativ)o(e)g(argumen)o(t.)75 +999 y Fl(universal-argument)e(\(\))315 1054 y Fm(This)g(is)h(another)e +(w)o(a)o(y)g(to)g(sp)q(ecify)i(an)f(argumen)o(t.)18 b(If)13 +b(this)g(command)g(is)g(follo)o(w)o(ed)g(b)o(y)g(one)315 +1108 y(or)h(more)h(digits,)g(optionally)h(with)f(a)g(leading)h(min)o +(us)f(sign,)g(those)g(digits)g(de\014ne)h(the)f(ar-)315 +1163 y(gumen)o(t.)k(If)c(the)g(command)f(is)h(follo)o(w)o(ed)g(b)o(y)g +(digits,)g(executing)g Fl(universal-argument)315 1218 +y Fm(again)h(ends)g(the)g(n)o(umeric)h(argumen)o(t,)e(but)h(is)h +(otherwise)f(ignored.)22 b(As)16 b(a)g(sp)q(ecial)h(case,)315 +1273 y(if)g(this)g(command)f(is)h(immediately)h(follo)o(w)o(ed)f(b)o(y) +f(a)g(c)o(haracter)g(that)g(is)h(neither)g(a)f(digit)315 +1328 y(or)d(min)o(us)i(sign,)f(the)g(argumen)o(t)g(coun)o(t)f(for)h +(the)g(next)g(command)g(is)g(m)o(ultiplied)j(b)o(y)d(four.)315 +1382 y(The)19 b(argumen)o(t)f(coun)o(t)g(is)h(initially)j(one,)d(so)f +(executing)i(this)f(function)h(the)e(\014rst)h(time)315 +1437 y(mak)o(es)c(the)h(argumen)o(t)f(coun)o(t)h(four,)f(a)h(second)g +(time)g(mak)o(es)g(the)g(argumen)o(t)f(coun)o(t)g(six-)315 +1492 y(teen,)g(and)g(so)g(on.)20 b(By)15 b(default,)h(this)f(is)h(not)f +(b)q(ound)h(to)f(a)g(k)o(ey)l(.)75 1595 y Fb(1.4.6)30 +b(Letting)20 b(Readline)g(T)n(yp)r(e)h(F)-5 b(or)19 b(Y)-5 +b(ou)75 1708 y Fl(complete)14 b(\()305 1706 y Ff(h)p +317 1680 74 2 v 317 1708 a Fe(T)m(AB)p 317 1715 V 389 +1706 a Ff(i)404 1708 y Fl(\))315 1762 y Fm(A)o(ttempt)c(to)h(p)q +(erform)g(completion)i(on)e(the)g(text)g(b)q(efore)h(p)q(oin)o(t.)19 +b(The)11 b(actual)h(completion)315 1817 y(p)q(erformed)j(is)h +(application-sp)q(eci\014)q(c.)23 b(The)15 b(default)h(is)g(\014lename) +g(completion.)75 1901 y Fl(possible-completions)c(\(M-?\))315 +1955 y Fm(List)k(the)f(p)q(ossible)i(completions)f(of)f(the)g(text)g(b) +q(efore)h(p)q(oin)o(t.)75 2039 y Fl(insert-completions)d(\(M-*\))315 +2093 y Fm(Insert)j(all)g(completions)g(of)f(the)g(text)g(b)q(efore)h(p) +q(oin)o(t)f(that)g(w)o(ould)h(ha)o(v)o(e)f(b)q(een)h(generated)315 +2148 y(b)o(y)f Fl(possible-completions)p Fm(.)75 2232 +y Fl(menu-complete)e(\(\))315 2286 y Fm(Similar)g(to)f +Fl(complete)p Fm(,)f(but)h(replaces)h(the)f(w)o(ord)f(to)g(b)q(e)i +(completed)f(with)h(a)e(single)j(matc)o(h)315 2341 y(from)k(the)h(list) +h(of)e(p)q(ossible)j(completions.)32 b(Rep)q(eated)19 +b(execution)h(of)f Fl(menu-complete)315 2396 y Fm(steps)h(through)g +(the)g(list)h(of)f(p)q(ossible)i(completions,)g(inserting)f(eac)o(h)f +(matc)o(h)f(in)i(turn.)315 2451 y(A)o(t)d(the)g(end)h(of)f(the)h(list)g +(of)f(completions,)i(the)e(b)q(ell)j(is)d(rung)h(\(sub)s(ject)f(to)f +(the)i(setting)315 2506 y(of)f Fl(bell-style)p Fm(\))e(and)i(the)g +(original)h(text)f(is)g(restored.)28 b(An)19 b(argumen)o(t)e(of)g +Fc(n)i Fm(mo)o(v)o(es)e Fc(n)315 2560 y Fm(p)q(ositions)h(forw)o(ard)e +(in)j(the)e(list)h(of)f(matc)o(hes;)h(a)f(negativ)o(e)g(argumen)o(t)g +(ma)o(y)g(b)q(e)h(used)g(to)315 2615 y(mo)o(v)o(e)g(bac)o(kw)o(ard)h +(through)g(the)g(list.)32 b(This)20 b(command)f(is)h(in)o(tended)g(to)f +(b)q(e)h(b)q(ound)g(to)315 2668 y Ff(h)p 327 2642 V 327 +2670 a Fe(T)m(AB)p 327 2678 V 399 2668 a Ff(i)414 2670 +y Fm(,)15 b(but)g(is)h(un)o(b)q(ound)g(b)o(y)f(default.)p +eop +%%Page: 17 19 +17 18 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(17)75 149 y Fl(delete-char-or-list)13 b(\(\))315 204 +y Fm(Deletes)h(the)f(c)o(haracter)g(under)h(the)g(cursor)f(if)h(not)f +(at)g(the)g(b)q(eginning)j(or)d(end)h(of)f(the)g(line)315 +259 y(\(lik)o(e)i Fl(delete-char)p Fm(\).)j(If)d(at)f(the)h(end)g(of)f +(the)g(line,)i(b)q(eha)o(v)o(es)f(iden)o(tically)i(to)d +Fl(possible-)315 314 y(completions)p Fm(.)k(This)e(command)f(is)h(un)o +(b)q(ound)g(b)o(y)f(default.)75 428 y Fb(1.4.7)30 b(Keyb)r(oard)20 +b(Macros)75 551 y Fl(start-kbd-macro)13 b(\(C-x)i(\(\))315 +606 y Fm(Begin)h(sa)o(ving)f(the)h(c)o(haracters)e(t)o(yp)q(ed)i(in)o +(to)f(the)g(curren)o(t)g(k)o(eyb)q(oard)g(macro.)75 699 +y Fl(end-kbd-macro)e(\(C-x)i(\)\))315 754 y Fm(Stop)f(sa)o(ving)f(the)h +(c)o(haracters)f(t)o(yp)q(ed)h(in)o(to)f(the)h(curren)o(t)g(k)o(eyb)q +(oard)f(macro)g(and)h(sa)o(v)o(e)f(the)315 809 y(de\014nition.)75 +902 y Fl(call-last-kbd-macro)g(\(C-x)h(e\))315 957 y +Fm(Re-execute)k(the)g(last)f(k)o(eyb)q(oard)h(macro)f(de\014ned,)i(b)o +(y)e(making)h(the)g(c)o(haracters)e(in)j(the)315 1012 +y(macro)14 b(app)q(ear)i(as)f(if)g(t)o(yp)q(ed)h(at)e(the)i(k)o(eyb)q +(oard.)75 1126 y Fb(1.4.8)30 b(Some)20 b(Miscellaneous)h(Commands)75 +1249 y Fl(re-read-init-file)13 b(\(C-x)h(C-r\))315 1304 +y Fm(Read)d(in)g(the)g(con)o(ten)o(ts)g(of)f(the)h Fc(inputrc)k +Fm(\014le,)d(and)g(incorp)q(orate)f(an)o(y)f(bindings)j(or)e(v)m +(ariable)315 1358 y(assignmen)o(ts)k(found)h(there.)75 +1452 y Fl(abort)e(\(C-g\))315 1507 y Fm(Ab)q(ort)f(the)g(curren)o(t)h +(editing)g(command)f(and)h(ring)f(the)h(terminal's)f(b)q(ell)i(\(sub)s +(ject)e(to)g(the)315 1561 y(setting)i(of)g Fl(bell-style)p +Fm(\).)75 1655 y Fl(do-uppercase-version)d(\(M-a,)j(M-b,)f(M-)p +Fc(x)p Fl(,)h(...\))315 1710 y Fm(If)f(the)g(meta\014ed)g(c)o(haracter) +f Fc(x)k Fm(is)d(lo)o(w)o(ercase,)g(run)g(the)g(command)f(that)h(is)g +(b)q(ound)h(to)e(the)315 1764 y(corresp)q(onding)j(upp)q(ercase)g(c)o +(haracter.)75 1858 y Fl(prefix-meta)e(\()377 1856 y Ff(h)p +389 1830 70 2 v 389 1858 a Fe(ESC)p 389 1866 V 456 1856 +a Ff(i)471 1858 y Fl(\))315 1913 y Fm(Metafy)k(the)h(next)g(c)o +(haracter)f(t)o(yp)q(ed.)30 b(This)20 b(is)f(for)f(k)o(eyb)q(oards)h +(without)g(a)f(meta)g(k)o(ey)l(.)315 1968 y(T)o(yping)e(`)485 +1966 y Ff(h)p 496 1939 V 496 1968 a Fe(ESC)p 496 1975 +V 563 1966 a Ff(i)593 1968 y Fl(f)p Fm(')f(is)h(equiv)m(alen)o(t)h(to)d +(t)o(yping)i Fg(M-f)p Fm(.)75 2061 y Fl(undo)f(\(C-_)f(or)h(C-x)g +(C-u\))315 2116 y Fm(Incremen)o(tal)h(undo,)f(separately)h(remem)o(b)q +(ered)g(for)e(eac)o(h)h(line.)75 2209 y Fl(revert-line)f(\(M-r\))315 +2264 y Fm(Undo)j(all)g(c)o(hanges)g(made)f(to)g(this)h(line.)26 +b(This)17 b(is)g(lik)o(e)h(executing)f(the)g Fl(undo)f +Fm(command)315 2319 y(enough)g(times)f(to)g(get)f(bac)o(k)h(to)g(the)g +(b)q(eginning.)75 2412 y Fl(tilde-expand)f(\(M-~\))315 +2467 y Fm(P)o(erform)g(tilde)j(expansion)f(on)f(the)g(curren)o(t)g(w)o +(ord.)75 2560 y Fl(set-mark)f(\(C-@\))315 2615 y Fm(Set)i(the)h(mark)f +(to)f(the)i(p)q(oin)o(t.)24 b(If)17 b(a)f(n)o(umeric)h(argumen)o(t)f +(is)g(supplied,)j(the)e(mark)e(is)i(set)315 2670 y(to)e(that)f(p)q +(osition.)p eop +%%Page: 18 20 +18 19 bop 75 -58 a Fm(18)1299 b(GNU)15 b(Readline)h(Library)75 +149 y Fl(exchange-point-and-mark)c(\(C-x)j(C-x\))315 +204 y Fm(Sw)o(ap)g(the)h(p)q(oin)o(t)g(with)g(the)g(mark.)k(The)c +(curren)o(t)f(cursor)h(p)q(osition)g(is)g(set)g(to)f(the)g(sa)o(v)o(ed) +315 259 y(p)q(osition,)h(and)f(the)h(old)f(cursor)g(p)q(osition)h(is)g +(sa)o(v)o(ed)f(as)g(the)g(mark.)75 347 y Fl(character-search)e(\(C-]\)) +315 402 y Fm(A)f(c)o(haracter)g(is)h(read)g(and)f(p)q(oin)o(t)h(is)g +(mo)o(v)o(ed)f(to)g(the)g(next)h(o)q(ccurrence)g(of)f(that)g(c)o +(haracter.)315 456 y(A)j(negativ)o(e)h(coun)o(t)f(searc)o(hes)g(for)f +(previous)i(o)q(ccurrences.)75 544 y Fl(character-search-backward)c +(\(M-C-]\))315 599 y Fm(A)22 b(c)o(haracter)g(is)h(read)f(and)h(p)q +(oin)o(t)g(is)g(mo)o(v)o(ed)f(to)g(the)g(previous)h(o)q(ccurrence)h(of) +e(that)315 654 y(c)o(haracter.)d(A)c(negativ)o(e)h(coun)o(t)f(searc)o +(hes)g(for)f(subsequen)o(t)i(o)q(ccurrences.)75 741 y +Fl(insert-comment)d(\(M-#\))315 796 y Fm(Without)18 b(a)f(n)o(umeric)i +(argumen)o(t,)e(the)h(v)m(alue)h(of)f(the)f Fl(comment-begin)f +Fm(v)m(ariable)k(is)e(in-)315 851 y(serted)e(at)f(the)h(b)q(eginning)i +(of)d(the)h(curren)o(t)g(line.)23 b(If)16 b(a)g(n)o(umeric)h(argumen)o +(t)e(is)h(supplied,)315 906 y(this)j(command)f(acts)g(as)f(a)h(toggle:) +26 b(if)19 b(the)f(c)o(haracters)g(at)f(the)i(b)q(eginning)h(of)e(the)g +(line)315 960 y(do)d(not)g(matc)o(h)g(the)g(v)m(alue)i(of)e +Fl(comment-begin)p Fm(,)e(the)i(v)m(alue)i(is)f(inserted,)f(otherwise)h +(the)315 1015 y(c)o(haracters)j(in)i Fl(comment-begin)d +Fm(are)i(deleted)i(from)d(the)h(b)q(eginning)i(of)e(the)g(line.)36 +b(In)315 1070 y(either)16 b(case,)f(the)g(line)i(is)f(accepted)f(as)g +(if)h(a)f(newline)i(had)e(b)q(een)i(t)o(yp)q(ed.)75 1158 +y Fl(dump-functions)c(\(\))315 1213 y Fm(Prin)o(t)g(all)h(of)f(the)g +(functions)h(and)g(their)g(k)o(ey)f(bindings)i(to)d(the)i(Readline)g +(output)f(stream.)315 1267 y(If)j(a)g(n)o(umeric)g(argumen)o(t)f(is)i +(supplied,)h(the)e(output)f(is)i(formatted)d(in)j(suc)o(h)f(a)g(w)o(a)o +(y)f(that)315 1322 y(it)g(can)h(b)q(e)g(made)f(part)f(of)h(an)g +Fc(inputrc)k Fm(\014le.)i(This)16 b(command)f(is)h(un)o(b)q(ound)g(b)o +(y)f(default.)75 1410 y Fl(dump-variables)e(\(\))315 +1465 y Fm(Prin)o(t)e(all)g(of)f(the)h(settable)g(v)m(ariables)h(and)f +(their)g(v)m(alues)h(to)e(the)h(Readline)h(output)e(stream.)315 +1519 y(If)16 b(a)g(n)o(umeric)g(argumen)o(t)f(is)i(supplied,)h(the)e +(output)f(is)i(formatted)d(in)j(suc)o(h)f(a)g(w)o(a)o(y)f(that)315 +1574 y(it)g(can)h(b)q(e)g(made)f(part)f(of)h(an)g Fc(inputrc)k +Fm(\014le.)i(This)16 b(command)f(is)h(un)o(b)q(ound)g(b)o(y)f(default.) +75 1662 y Fl(dump-macros)f(\(\))315 1717 y Fm(Prin)o(t)j(all)h(of)e +(the)h(Readline)h(k)o(ey)f(sequences)h(b)q(ound)g(to)e(macros)g(and)h +(the)g(strings)g(they)315 1771 y(output.)26 b(If)18 b(a)f(n)o(umeric)h +(argumen)o(t)f(is)h(supplied,)i(the)d(output)g(is)h(formatted)e(in)j +(suc)o(h)e(a)315 1826 y(w)o(a)o(y)d(that)g(it)i(can)f(b)q(e)g(made)g +(part)g(of)f(an)h Fc(inputrc)k Fm(\014le.)i(This)15 b(command)g(is)h +(un)o(b)q(ound)g(b)o(y)315 1881 y(default.)75 1969 y +Fl(emacs-editing-mode)d(\(C-e\))315 2024 y Fm(When)j(in)g +Fl(vi)e Fm(command)i(mo)q(de,)f(this)g(causes)h(a)f(switc)o(h)g(to)g +Fl(emacs)f Fm(editing)j(mo)q(de.)75 2111 y Fl(vi-editing-mode)c +(\(M-C-j\))315 2166 y Fm(When)j(in)g Fl(emacs)e Fm(editing)j(mo)q(de,)e +(this)g(causes)h(a)f(switc)o(h)g(to)g Fl(vi)f Fm(editing)j(mo)q(de.)75 +2290 y Fk(1.5)33 b(Readline)23 b(vi)h(Mo)r(de)137 2385 +y Fm(While)13 b(the)f(Readline)i(library)e(do)q(es)g(not)g(ha)o(v)o(e)f +(a)h(full)h(set)f(of)f Fl(vi)g Fm(editing)j(functions,)f(it)f(do)q(es)g +(con)o(tain)75 2440 y(enough)17 b(to)g(allo)o(w)g(simple)h(editing)h +(of)d(the)i(line.)27 b(The)17 b(Readline)h Fl(vi)f Fm(mo)q(de)g(b)q +(eha)o(v)o(es)g(as)g(sp)q(eci\014ed)i(in)75 2495 y(the)c +Fh(posix)g Fm(1003.2)f(standard.)137 2560 y(In)h(order)g(to)f(switc)o +(h)g(in)o(teractiv)o(ely)i(b)q(et)o(w)o(een)f Fl(emacs)e +Fm(and)i Fl(vi)f Fm(editing)i(mo)q(des,)f(use)f(the)h(command)75 +2615 y Fg(M-C-j)j Fm(\(b)q(ound)i(to)e(emacs-editing-mo)q(de)j(when)e +(in)h Fl(vi)f Fm(mo)q(de)g(and)g(to)f(vi-editing-mo)q(de)k(in)e +Fl(emacs)75 2670 y Fm(mo)q(de\).)g(The)15 b(Readline)i(default)f(is)f +Fl(emacs)g Fm(mo)q(de.)p eop +%%Page: 19 21 +19 20 bop 75 -58 a Fm(Chapter)15 b(1:)k(Command)c(Line)i(Editing)1055 +b(19)137 149 y(When)16 b(y)o(ou)e(en)o(ter)h(a)g(line)i(in)e +Fl(vi)g Fm(mo)q(de,)g(y)o(ou)g(are)f(already)i(placed)g(in)g +(`insertion')f(mo)q(de,)g(as)g(if)g(y)o(ou)75 204 y(had)e(t)o(yp)q(ed)h +(an)f(`)p Fl(i)p Fm('.)18 b(Pressing)608 202 y Ff(h)p +620 176 70 2 v 620 204 a Fe(ESC)p 620 212 V 687 202 a +Ff(i)715 204 y Fm(switc)o(hes)13 b(y)o(ou)g(in)o(to)g(`command')f(mo)q +(de,)i(where)f(y)o(ou)g(can)g(edit)h(the)75 259 y(text)i(of)h(the)g +(line)h(with)g(the)f(standard)f Fl(vi)h Fm(mo)o(v)o(emen)o(t)f(k)o +(eys,)g(mo)o(v)o(e)g(to)h(previous)g(history)g(lines)i(with)75 +314 y(`)p Fl(k)p Fm(')14 b(and)i(subsequen)o(t)f(lines)i(with)f(`)p +Fl(j)p Fm(',)e(and)h(so)g(forth.)p eop +%%Page: 20 22 +20 21 bop 75 -58 a Fm(20)1299 b(GNU)15 b(Readline)h(Library)p +eop +%%Page: -1 23 +-1 22 bop 1862 -58 a Fm(i)75 149 y Fi(T)-7 b(able)27 +b(of)f(Con)n(ten)n(ts)75 320 y Fk(1)67 b(Command)22 b(Line)i(Editing)d +Fa(.)10 b(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)g(.)42 b Fk(1)224 389 y Fm(1.1)j(In)o(tro)q(duction)16 +b(to)f(Line)h(Editing)e Fd(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)27 b Fm(1)224 444 y(1.2)45 b(Readline)16 b(In)o(teraction)8 +b Fd(.)g(.)g(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)23 b Fm(1)374 499 y(1.2.1)44 b(Readline)16 +b(Bare)f(Essen)o(tials)f Fd(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)27 +b Fm(1)374 553 y(1.2.2)44 b(Readline)16 b(Mo)o(v)o(emen)o(t)e(Commands) +7 b Fd(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)21 b Fm(2)374 608 y(1.2.3)44 b(Readline)16 b(Killing)i(Commands) +11 b Fd(.)c(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)25 b Fm(2)374 663 y(1.2.4)44 b(Readline)16 +b(Argumen)o(ts)c Fd(.)c(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)27 +b Fm(3)374 718 y(1.2.5)44 b(Searc)o(hing)16 b(for)e(Commands)h(in)h +(the)f(History)e Fd(.)8 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)27 +b Fm(3)224 773 y(1.3)45 b(Readline)16 b(Init)h(File)e +Fd(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)29 b Fm(4)374 827 y(1.3.1)44 b(Readline)16 +b(Init)g(File)h(Syn)o(tax)7 b Fd(.)g(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)21 +b Fm(4)374 882 y(1.3.2)44 b(Conditional)16 b(Init)g(Constructs)5 +b Fd(.)i(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)g(.)f(.)19 b Fm(9)374 937 y(1.3.3)44 b(Sample)16 +b(Init)g(File)11 b Fd(.)e(.)e(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)26 b Fm(9)224 992 y(1.4)45 b(Bindable)17 b(Readline)g(Commands) +6 b Fd(.)h(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)21 b Fm(12)374 +1046 y(1.4.1)44 b(Commands)14 b(F)l(or)h(Mo)o(ving)e +Fd(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)28 b Fm(12)374 1101 y(1.4.2)44 +b(Commands)14 b(F)l(or)h(Manipulating)i(The)e(History)9 +b Fd(.)e(.)h(.)f(.)h(.)f(.)h(.)24 b Fm(12)374 1156 y(1.4.3)44 +b(Commands)14 b(F)l(or)h(Changing)h(T)l(ext)e Fd(.)8 +b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)30 +b Fm(14)374 1211 y(1.4.4)44 b(Killing)18 b(And)e(Y)l(anking)9 +b Fd(.)e(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)24 b Fm(15)374 +1266 y(1.4.5)44 b(Sp)q(ecifying)17 b(Numeric)f(Argumen)o(ts)c +Fd(.)c(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)27 +b Fm(16)374 1320 y(1.4.6)44 b(Letting)15 b(Readline)i(T)o(yp)q(e)e(F)l +(or)g(Y)l(ou)10 b Fd(.)d(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)25 b Fm(16)374 1375 y(1.4.7)44 b(Keyb)q(oard)15 +b(Macros)6 b Fd(.)h(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)21 +b Fm(17)374 1430 y(1.4.8)44 b(Some)15 b(Miscellaneous)i(Commands)7 +b Fd(.)g(.)g(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +22 b Fm(17)224 1485 y(1.5)45 b(Readline)16 b(vi)g(Mo)q(de)e +Fd(.)7 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)28 b Fm(18)p eop +%%Page: -2 24 +-2 23 bop 75 -58 a Fm(ii)1321 b(GNU)15 b(Readline)h(Library)p +eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/rtemsNfs/ChangeLog b/rtemsNfs/ChangeLog new file mode 100644 index 0000000..ab2a1f1 --- /dev/null +++ b/rtemsNfs/ChangeLog @@ -0,0 +1,37 @@ +Changes since RTEMS-NFS 1.1: + NFS: + - unlink() didnt work. The underlying RTEMS filesystem code evaluates + a '..' path on a non-directory node to find out the file's parent + directory. Workaround to this semantically inelegant RTEMS feature + was implemented. + +Changes since RTEMS-NFS 1.0.beta3: + NFS: + - fixed possible string overrun in nfsMount + - nfs_read_dir() must reset the 'eofreached' flag if it skipped + dirents present in the xdr but not fitting into the user buffer. + - nfsMountsShow() released the wrong lock! + RPCIO: + - cannot delete locked binary semaphore (authlock) -- must unlock + first (authlock was never deleted and hence effectively leaked) + - added ASSERT paranoia around mutex primitives + - Relaxed paranoia check / ASSERTion failure: + paranoia_free() is called more than once on an ext_buf - it must + undo calls to paranoia_refcnt() - hence the 0 == --refcnt check + is too strict. + - Added a DEBUG flag to introduce random packet losses for testing + retransmission. + xdr_mbuf: + - make sure we do a signed comparison + +Changes since rtemsNFS-1.0.beta2: + - moved 'tar' command to the 'config' area; use + predefined 'make-tar' in individual Makefiles + - use INSTALL_CHANGE for headers, not INSTALL_VARIANT (probably doesn't + matter, though) + - use LD not LD_FOR_TARGET (to get absolute path) + - fixed assertion failure print format + - print requestor id if send_event fails - had just experienced this :-( + - hint about fprintf using FP registers is probably PPC specific + - provided implementation for xdrmbuf_getlong_aligned(). i386-rtems + seems to use it. diff --git a/rtemsNfs/LICENSE b/rtemsNfs/LICENSE new file mode 100644 index 0000000..ba677ea --- /dev/null +++ b/rtemsNfs/LICENSE @@ -0,0 +1,115 @@ + + EPICS Open License Terms + + The following is the text of the EPICS Open software license agreement + which applies to many of the unbundled EPICS extensions and support + modules. + + -------------------------------------------------------------- + + Copyright © 2002, Stanford University and + Till Straumann + + RTEMS-NFS is distributed subject to the following license conditions: + + SOFTWARE LICENSE AGREEMENT + Software: RTEMS-NFS + + 1. The "Software", below, refers to RTEMS-NFS (in either source + code, or binary form and accompanying documentation). Each + licensee is addressed as "you" or "Licensee." + + RTEMS-NFS comprises all files under this directory with + the EXCEPTION OF + src/sock_mbuf.c + src/xdr_mbuf.c + proto/mount_prot.x + proto/nfs_prot.x + which are covered by the licenses described in the + LICENSE.NET and LICENSE.RPCXDR files (RTEMS source topdir) + and header comments in the mentioned files, respectively. + + 2. The copyright holders shown above and their third-party + licensors hereby grant Licensee a royalty-free nonexclusive + license, subject to the limitations stated herein and U.S. + Government license rights. + 3. You may modify and make a copy or copies of the Software for use + within your organization, if you meet the following conditions: + a. Copies in source code must include the copyright notice + and this Software License Agreement. + b. Copies in binary form must include the copyright notice + and this Software License Agreement in the documentation + and/or other materials provided with the copy. + + 4. You may modify a copy or copies of the Software or any portion + of it, thus forming a work based on the Software, and distribute + copies of such work outside your organization, if you meet all + of the following conditions: + a. Copies in source code must include the copyright notice + and this Software License Agreement; + b. Copies in binary form must include the copyright notice + and this Software License Agreement in the documentation + and/or other materials provided with the copy; + c. Modified copies and works based on the Software must carry + prominent notices stating that you changed specified + portions of the Software. + + 5. Portions of the Software resulted from work developed under a + U.S. Government contract and are subject to the following + license: the Government is granted for itself and others acting + on its behalf a paid-up, nonexclusive, irrevocable worldwide + license in this computer software to reproduce, prepare + derivative works, and perform publicly and display publicly. + 6. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, AND THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY + OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS + OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE + WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT + THAT THE SOFTWARE WILL FUNCTION UNINTERRUPTED, THAT IT IS + ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + 7. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, + THEIR THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED + STATES DEPARTMENT OF ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR + ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE + DAMAGES OF ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS + OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER + SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT + (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN + IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE POSSIBILITY OF + SUCH LOSS OR DAMAGES. + + Stanford Notice + *************** + + Acknowledgement of sponsorship + - - - - - - - - - - - - - - - - + This software was produced by the Stanford Linear Accelerator Center, + Stanford University, under Contract DE-AC03-76SFO0515 with the Department + of Energy. + + Government disclaimer of liability + - - - - - - - - - - - - - - - - - + Neither the United States nor the United States Department of Energy, + nor any of their employees, makes any warranty, express or implied, + or assumes any legal liability or responsibility for the accuracy, + completeness, or usefulness of any data, apparatus, product, or process + disclosed, or represents that its use would not infringe privately + owned rights. + + Stanford disclaimer of liability + - - - - - - - - - - - - - - - - - + Stanford University makes no representations or warranties, express or + implied, nor assumes any liability for the use of this software. + + Maintenance of notice + - - - - - - - - - - - + In the interest of clarity regarding the origin and status of this + software, Stanford University requests that any recipient of it maintain + this notice affixed to any distribution by the recipient that contains a + copy or derivative of this software. + diff --git a/rtemsNfs/Makefile b/rtemsNfs/Makefile new file mode 100644 index 0000000..a77b0f8 --- /dev/null +++ b/rtemsNfs/Makefile @@ -0,0 +1,16 @@ +# +# $Id$ +# + + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc + +include $(RTEMS_CUSTOM) +include $(RTEMS_ROOT)/make/directory.cfg + +SUBDIRS=proto src + +REVISION=$(filter-out $$%,$$Name$$) + +tar: tar-recursive + @$(make-tar) diff --git a/rtemsNfs/README b/rtemsNfs/README new file mode 100644 index 0000000..3291329 --- /dev/null +++ b/rtemsNfs/README @@ -0,0 +1,491 @@ +RTEMS-NFS +========= + +A NFS-V2 client implementation for the RTEMS real-time +executive. + +Author: Till Straumann , 2002 + +Copyright 2002, Stanford University and + Till Straumann + +Stanford Notice +*************** + +Acknowledgement of sponsorship +* * * * * * * * * * * * * * * * +This software was produced by the Stanford Linear Accelerator Center, +Stanford University, under Contract DE-AC03-76SFO0515 with the Department +of Energy. + + +Contents +-------- +I Overview + 1) Performance + 2) Reference Platform / Test Environment + +II Usage + 1) Initialization + 2) Mounting Remote Server Filesystems + 3) Unmounting + 4) Unloading + 5) Dumping Information / Statistics + +III Implementation Details + 1) RPCIOD + 2) NFS + 3) RTEMS Resources Used By NFS/RPCIOD + 4) Caveats & Bugs + +IV Licensing & Disclaimers + +I Overview +----------- + +This package implements a simple non-caching NFS client +for RTEMS. Most of the system calls are supported +with the exception of 'mount', i.e. it is not possible +to mount another FS on top of NFS (mostly because +of the difficulty that arises when mount points are +deleted on the server). It shouldn't be hard to do, +though. + +Note: this client supports NFS vers. 2 / MOUNT vers. 1; + NFS Version 3 or higher are NOT supported. + +The package consists of two modules: RPCIOD and NFS itself. + + - RPCIOD is a UDP/RPC multiplexor daemon. It takes + RPC requests from multiple local client threads, + funnels them through a single socket to multiple + servers and dispatches the replies back to the + (blocked) requestor threads. + RPCIOD does packet retransmission and handles + timeouts etc. + Note however, that it does NOT do any XDR + marshalling - it is up to the requestor threads + to do the XDR encoding/decoding. RPCIOD _is_ RPC + specific, though, because its message dispatching + is based on the RPC transaction ID. + + - The NFS package maps RTEMS filesystem calls + to proper RPCs, it does the XDR work and + hands marshalled RPC requests to RPCIOD. + All of the calls are synchronous, i.e. they + block until they get a reply. + +1) Performance +- - - - - - - - +Performance sucks (due to the lack of readahead/delayed +write and caching). On a fast (100Mb/s) ethernet, it +takes about 20s to copy a 10MB file from NFS to NFS. +I found, however, that vxWorks' NFS client doesn't seem +to be any faster... + +2) Reference Platform +- - - - - - - - - - - +RTEMS-NFS was developed and tested on + + o RTEMS-ss20020301 (local patches applied) + o PowerPC G3, G4 on Synergy SVGM series board + (custom 'SVGM' BSP, to be released soon) + o PowerPC 604 on MVME23xx + (powerpc/shared/motorola-powerpc BSP) + o Test Environment: + - RTEMS executable running CEXP + - rpciod/nfs dynamically loaded from TFTPfs + - EPICS application dynamically loaded from NFS; + the executing IOC accesses all of its files + on NFS. + +II Usage +--------- + +After linking into the system and proper initialization +(rtems-NFS supports 'magic' module initialization when +loaded into a running system with the CEXP loader), +you are ready for mounting NFSes from a server +(I avoid the term NFS filesystem because NFS already +stands for 'Network File System'). + +You should also read the + + - "RTEMS Resources Used By NFS/RPCIOD" + - "CAVEATS & BUGS" + +below. + +1) Initialization +- - - - - - - - - +NFS consists of two modules who must be initialized: + + a) the RPCIO daemon package; by calling + + rpcUdpInit(); + + note that this step must be performed prior to + initializing NFS: + + b) NFS is initialized by calling + + nfsInit( smallPoolDepth, bigPoolDepth ); + + if you supply 0 (zero) values for the pool + depths, the compile-time default configuration + is used which should work fine. + +NOTE: when using CEXP to load these modules into a +running system, initialization will be performed +automagically. + +2) Mounting Remote Server Filesystems +- - - - - - - - - - - - - - - - - - - + +There are two interfaces for mounting an NFS: + + - The (non-POSIX) RTEMS 'mount()' call: + + mount( &mount_table_entry_pointer, + &filesystem_operations_table_pointer, + options, + device, + mount_point ) + + Note that you must specify a 'mount_table_entry_pointer' + (use a dummy) - RTEMS' mount() doesn't grok a NULL for + the first argument. + + o for the 'filesystem_operations_table_pointer', supply + + &nfs_fs_ops + + o options are constants (see RTEMS headers) for specifying + read-only / read-write mounts. + + o the 'device' string specifies the remote filesystem + who is to be mounted. NFS expects a string conforming + to the following format (EBNF syntax): + + [ '.' '@' ] ':' + + The first optional part of the string allows you + to specify the credentials to be used for all + subsequent transactions with this server. If the + string is omitted, the EUID/EGID of the executing + thread (i.e. the thread performing the 'mount' - + NFS will still 'remember' these values and use them + for all future communication with this server). + + The part denotes the server IP address + in standard 'dot' notation. It is followed by + a colon and the (absolute) path on the server. + Note that no extra characters or whitespace must + be present in the string. Example 'device' strings + are: + + "300.99@192.168.44.3:/remote/rtems/root" + + "192.168.44.3:/remote/rtems/root" + + o the 'mount_point' string identifies the local + directory (most probably on IMFS) where the NFS + is to be mounted. Note that the mount point must + already exist with proper permissions. + + - Alternate 'mount' interface. NFS offers a more + convenient wrapper taking three string arguments: + + nfsMount(uidgid_at_host, server_path, mount_point) + + This interface does DNS lookup (see reentrancy note + below) and creates the mount point if necessary. + + o the first argument specifies the server and + optionally the uid/gid to be used for authentication. + The semantics are exactly as described above: + + [ '.' '@' ] + + The part may be either a host _name_ or + an IP address in 'dot' notation. In the former + case, nfsMount() uses 'gethostbyname()' to do + a DNS lookup. + + IMPORTANT NOTE: gethostbyname() is NOT reentrant/ + thread-safe and 'nfsMount()' (if not provided with an + IP/dot address string) is hence subject to race conditions. + + o the 'server_path' and 'mount_point' arguments + are described above. + NOTE: If the mount point does not exist yet, + nfsMount() tries to create it. + + o if nfsMount() is called with a NULL 'uidgid_at_host' + argument, it lists all currently mounted NFS + +3) Unmounting +- - - - - - - +An NFS can be unmounted using RTEMS 'unmount()' +call (yep, it is unmount() - not umount()): + + unmount(mount_point) + +Note that you _must_ supply the mount point (string +argument). It is _not_ possible to specify the +'mountee' when unmounting. NFS implements no +convenience wrapper for this (yet), essentially because +(although this sounds unbelievable) it is non-trivial +to lookup the path leading to an RTEMS filesystem +directory node. + +4) Unloading +- - - - - - - +After unmounting all NFS from the system, the NFS +and RPCIOD modules may be stopped and unloaded. +Just call 'nfsCleanup()' and 'rpcUdpCleanup()' +in this order. You should evaluate the return value +of these routines which is non-zero if either +of them refuses to yield (e.g. because there are +still mounted filesystems). +Again, when unloading is done by CEXP this is +transparently handled. + +5) Dumping Information / Statistics +- - - - - - - - - - - - - - - - - - + +Rudimentary RPCIOD statistics are printed +to a file (stdout when NULL) by + + int rpcUdpStats(FILE *f) + +A list of all currently mounted NFS can be +printed to a file (stdout if NULL) using + + int nfsMountsShow(FILE *f) + +For convenience, this routine is also called +by nfsMount() when supplying NULL arguments. + +III Implementation Details +-------------------------- + +1) RPCIOD +- - - - - + +RPCIOD was created to + +a) avoid non-reentrant librpc calls. +b) support 'asynchronous' operation over a single + socket. + +RPCIOD is a daemon thread handling 'transaction objects' +(XACTs) through an UDP socket. XACTs are marshalled RPC +calls/replies associated with RPC servers and requestor +threads. + +requestor thread: network: + + XACT packet + | | + V V + | message queue | ( socket ) + | | ^ + ----------> <----- | | + RPCIOD | + / -------------- + timeout/ (re) transmission + + +A requestor thread drops a transaction into +the message queue and goes to sleep. The XACT is +picked up by rpciod who is listening for events from +three sources: + + o the request queue + o packet arrival at the socket + o timeouts + +RPCIOD sends the XACT to its destination server and +enqueues the pending XACT into an ordered list of +outstanding transactions. + +When a packet arrives, RPCIOD (based on the RPC transaction +ID) looks up the matching XACT and wakes up the requestor +who can then XDR-decode the RPC results found in the XACT +object's buffer. + +When a timeout expires, RPCIOD examines the outstanding +XACT that is responsible for the timeout. If its lifetime +has not expired yet, RPCIOD resends the request. Otherwise, +the XACT's error status is set and the requestor is woken up. + +RPCIOD dynamically adjusts the retransmission intervals +based on the average round-trip time measured (on a per-server +basis). + +Having the requestors event driven (rather than blocking +e.g. on a semaphore) is geared to having many different +requestors (one synchronization object per requestor would +be needed otherwise). + +Requestors who want to do asynchronous IO need a different +interface which will be added in the future. + +1.a) Reentrancy +- - - - - - - - +RPCIOD does no non-reentrant librpc calls. + +1.b) Efficiency +- - - - - - - - +We shouldn't bother about efficiency until pipelining (read-ahead/ +delayed write) and caching are implemented. The round-trip delay +associated with every single RPC transaction clearly is a big +performance killer. + +Nevertheless, I could not withstand the temptation to eliminate +the extra copy step involved with socket IO: + +A user data object has to be XDR encoded into a buffer. The +buffer given to the socket where it is copied into MBUFs. +(The network chip driver might even do more copying). + +Likewise, on reception 'recvfrom' copies MBUFS into a user +buffer which is XDR decoded into the final user data object. + +Eliminating the copying into (possibly multiple) MBUFS by +'sendto()' is actually a piece of cake. RPCIOD uses the +'sosend()' routine [properly wrapped] supplying a single +MBUF header who directly points to the marshalled buffer +:-) + +Getting rid of the extra copy on reception was (only a little) +harder: I derived a 'XDR-mbuf' stream from SUN's xdr_mem which +allows for XDR-decoding out of a MBUF chain who is obtained by +soreceive(). + +2) NFS +- - - - +The actual NFS implementation is straightforward and essentially +'passive' (no threads created). Any RTEMS task executing a +filesystem call dispatched to NFS (such as 'opendir()', 'lseek()' +or 'unlink()') ends up XDR encoding arguments, dropping a +XACT into RPCIOD's message queue and going to sleep. +When woken up by RPCIOD, the XACT is decoded (using the XDR-mbuf +stream mentioned above) and the properly cooked-up results are +returned. + +3) RTEMS Resources Used By NFS/RPCIOD +- - - - - - - - - - - - - - - - - - - + +The RPCIOD/NFS package uses the following resources. Some +parameters are compile-time configurable - consult the +source files for details. + +RPCIOD: + o 1 task + o 1 message queue + o 1 socket/filedescriptor + o 2 semaphores (a third one is temporarily created during + rpcUdpCleanup()). + o 1 RTEMS EVENT (by default RTEMS_EVENT_30). + IMPORTANT: this event is used by _every_ thread executing + NFS system calls and hence is RESERVED. + o 3 events only used by RPCIOD itself, i.e. these must not + be sent to RPCIOD by no other thread (except for the intended + use, of course). The events involved are 1,2,3. + o preemption disabled sections: NONE + o sections with interrupts disabled: NONE + o NO 'timers' are used (timer code would run in IRQ context) + o memory usage: n.a + +NFS: + o 2 message queues + o 2 semaphores + o 1 semaphore per mounted NFS + o 1 slot in driver entry table (for major number) + o preemption disabled sections: NONE + o sections with interrupts disabled: NONE + o 1 task + 1 semaphore temporarily created when + listing mounted filesystems (rtems_filesystem_resolve_location()) + +4) CAVEATS & BUGS +- - - - - - - - - +Unfortunately, some bugs crawl around in the filesystem generics. +(Some of them might already be fixed in versions later than +rtems-ss-20020301). +I recommend to use the patch distributed with RTEMS-NFS. + + o RTEMS uses/used (Joel said it has been fixed already) a 'short' + ino_t which is not enough for NFS. + The driver detects this problem and enables a workaround. In rare + situations (mainly involving 'getcwd()' improper inode comparison + may result (due to the restricted size, stat() returns st_ino modulo + 2^16). In most cases, however, st_dev is compared along with st_ino + which will give correct results (different files may yield identical + st_ino but they will have different st_dev). However, there is + code (in getcwd(), for example) who assumes that files residing + in one directory must be hosted by the same device and hence omits + the st_dev comparison. In such a case, the workaround will fail. + + NOTE: changing the size (sys/types.h) of ino_t from 'short' to 'long' + is strongly recommended. It is NOT included in the patch, however + as this is a major change requiring ALL of your sources to + be recompiled. + + THE ino_t SIZE IS FIXED IN GCC-3.2/NEWLIB-1.10.0-2 DISTRIBUTED BY + OAR. + + o You may work around most filesystem bugs by observing the following + rules: + + * never use chroot() (fixed by the patch) + * never use getpwent(), getgrent() & friends - they are NOT THREAD + safe (fixed by the patch) + * NEVER use rtems_libio_share_private_env() - not even with the + patch applied. Just DONT - it is broken by design. + * All threads who have their own userenv (who have called + rtems_libio_set_private_env()) SHOULD 'chdir("/")' before + terminating. Otherwise, (i.e. if their cwd is on NFS), it will + be impossible to unmount the NFS involved. + + o The patch slightly changes the semantics of 'getpwent()' and + 'getgrent()' & friends (to what is IMHO correct anyways - the patch is + also needed to fix another problem, however): with the patch applied, + the passwd and group files are always accessed from the 'current' user + environment, i.e. a thread who has changed its 'root' or 'uid' might + not be able to access these files anymore. + + o NOTE: RTEMS 'mount()' / 'unmount()' are NOT THREAD SAFE. + +IV Licensing & Disclaimers +-------------------------- + +NFS is distributed under the EPICS Open License - consult the +separate 'LICENSE' file. + +Government disclaimer of liability +- - - - - - - - - - - - - - - - - +Neither the United States nor the United States Department of Energy, +nor any of their employees, makes any warranty, express or implied, +or assumes any legal liability or responsibility for the accuracy, +completeness, or usefulness of any data, apparatus, product, or process +disclosed, or represents that its use would not infringe privately +owned rights. + +Stanford disclaimer of liability +- - - - - - - - - - - - - - - - - +Stanford University makes no representations or warranties, express or +implied, nor assumes any liability for the use of this software. + +This product is subject to the EPICS open license +- - - - - - - - - - - - - - - - - - - - - - - - - +Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php +for more information. + +Maintenance of notice +- - - - - - - - - - - +In the interest of clarity regarding the origin and status of this +software, Stanford University requests that any recipient of it maintain +this notice affixed to any distribution by the recipient that contains a +copy or derivative of this software. diff --git a/rtemsNfs/proto/Makefile b/rtemsNfs/proto/Makefile new file mode 100644 index 0000000..57a9830 --- /dev/null +++ b/rtemsNfs/proto/Makefile @@ -0,0 +1,75 @@ +# +# $Id$ +# +# Templates/Makefile.lib +# Template library Makefile +# + + +LIBNAME=libnfsprot.a # xxx- your library names goes here +LIB=${ARCH}/${LIBNAME} + +# C and C++ source names, if any, go here -- minus the .c or .cc +C_PIECES=nfs_prot_xdr mount_prot_xdr +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +CC_PIECES= +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +H_FILES= + +XFILES = $(wildcard *.x) + +# Assembly source names, if any, go here -- minus the .S +S_PIECES= +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc + +include $(RTEMS_CUSTOM) +include $(RTEMS_ROOT)/make/lib.cfg + +# +# Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +# inline declarations require -O +CFLAGS += -O2 -Winline + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += $(XFILES:%.x=%*.c) $(XFILES:%.x=%*.h) + +all: ${ARCH} $(SRCS) $(LIB) + +$(LIB): ${OBJS} + $(make-library) + +%_xdr.c: %.x %.h + rpcgen -c $< > $@ + +%.h: %.x + rpcgen -h $< > $@ + +.PRECIOUS: $(XFILES:%.x=%.h) $(XFILES:%.x=%_xdr.c) + +tar: $(XFILES:%.x=%.h) $(XFILES:%.x=%_xdr.c) + +distclean: clean + +# DONT install this library. +install: all diff --git a/rtemsNfs/proto/mount_prot.h b/rtemsNfs/proto/mount_prot.h new file mode 100644 index 0000000..1cde517 --- /dev/null +++ b/rtemsNfs/proto/mount_prot.h @@ -0,0 +1,144 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _MOUNT_PROT_H_RPCGEN +#define _MOUNT_PROT_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define MNTPATHLEN 1024 +#define MNTNAMLEN 255 +#define FHSIZE 32 + +typedef char fhandle[FHSIZE]; + +struct fhstatus { + u_int fhs_status; + union { + fhandle fhs_fhandle; + } fhstatus_u; +}; +typedef struct fhstatus fhstatus; + +typedef char *dirpath; + +typedef char *name; + +typedef struct mountbody *mountlist; + +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; +typedef struct mountbody mountbody; + +typedef struct groupnode *groups; + +struct groupnode { + name gr_name; + groups gr_next; +}; +typedef struct groupnode groupnode; + +typedef struct exportnode *exports; + +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; +typedef struct exportnode exportnode; + +#define MOUNTPROG 100005 +#define MOUNTVERS 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define MOUNTPROC_NULL 0 +extern void * mountproc_null_1(void *, CLIENT *); +extern void * mountproc_null_1_svc(void *, struct svc_req *); +#define MOUNTPROC_MNT 1 +extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *); +extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_DUMP 2 +extern mountlist * mountproc_dump_1(void *, CLIENT *); +extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *); +#define MOUNTPROC_UMNT 3 +extern void * mountproc_umnt_1(dirpath *, CLIENT *); +extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_UMNTALL 4 +extern void * mountproc_umntall_1(void *, CLIENT *); +extern void * mountproc_umntall_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORT 5 +extern exports * mountproc_export_1(void *, CLIENT *); +extern exports * mountproc_export_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORTALL 6 +extern exports * mountproc_exportall_1(void *, CLIENT *); +extern exports * mountproc_exportall_1_svc(void *, struct svc_req *); +extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define MOUNTPROC_NULL 0 +extern void * mountproc_null_1(); +extern void * mountproc_null_1_svc(); +#define MOUNTPROC_MNT 1 +extern fhstatus * mountproc_mnt_1(); +extern fhstatus * mountproc_mnt_1_svc(); +#define MOUNTPROC_DUMP 2 +extern mountlist * mountproc_dump_1(); +extern mountlist * mountproc_dump_1_svc(); +#define MOUNTPROC_UMNT 3 +extern void * mountproc_umnt_1(); +extern void * mountproc_umnt_1_svc(); +#define MOUNTPROC_UMNTALL 4 +extern void * mountproc_umntall_1(); +extern void * mountproc_umntall_1_svc(); +#define MOUNTPROC_EXPORT 5 +extern exports * mountproc_export_1(); +extern exports * mountproc_export_1_svc(); +#define MOUNTPROC_EXPORTALL 6 +extern exports * mountproc_exportall_1(); +extern exports * mountproc_exportall_1_svc(); +extern int mountprog_1_freeresult (); +#endif /* K&R C */ + +/* the xdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_fhandle (XDR *, fhandle); +extern bool_t xdr_fhstatus (XDR *, fhstatus*); +extern bool_t xdr_dirpath (XDR *, dirpath*); +extern bool_t xdr_name (XDR *, name*); +extern bool_t xdr_mountlist (XDR *, mountlist*); +extern bool_t xdr_mountbody (XDR *, mountbody*); +extern bool_t xdr_groups (XDR *, groups*); +extern bool_t xdr_groupnode (XDR *, groupnode*); +extern bool_t xdr_exports (XDR *, exports*); +extern bool_t xdr_exportnode (XDR *, exportnode*); + +#else /* K&R C */ +extern bool_t xdr_fhandle (); +extern bool_t xdr_fhstatus (); +extern bool_t xdr_dirpath (); +extern bool_t xdr_name (); +extern bool_t xdr_mountlist (); +extern bool_t xdr_mountbody (); +extern bool_t xdr_groups (); +extern bool_t xdr_groupnode (); +extern bool_t xdr_exports (); +extern bool_t xdr_exportnode (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_MOUNT_PROT_H_RPCGEN */ diff --git a/rtemsNfs/proto/mount_prot.x b/rtemsNfs/proto/mount_prot.x new file mode 100644 index 0000000..444e998 --- /dev/null +++ b/rtemsNfs/proto/mount_prot.x @@ -0,0 +1,161 @@ +/* @(#)mount.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Protocol description for the mount program + */ + + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; + +/* + * If a status of zero is returned, the call completed successfully, and + * a file handle for the directory follows. A non-zero status indicates + * some sort of error. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. The only connecting point is the fhandle + * structure, which is the same for both protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; +} = 100005; diff --git a/rtemsNfs/proto/mount_prot_xdr.c b/rtemsNfs/proto/mount_prot_xdr.c new file mode 100644 index 0000000..b83350b --- /dev/null +++ b/rtemsNfs/proto/mount_prot_xdr.c @@ -0,0 +1,124 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "mount_prot.h" + +bool_t +xdr_fhandle (XDR *xdrs, fhandle objp) +{ + register int32_t *buf; + + if (!xdr_opaque (xdrs, objp, FHSIZE)) + return FALSE; + return TRUE; +} + +bool_t +xdr_fhstatus (XDR *xdrs, fhstatus *objp) +{ + register int32_t *buf; + + if (!xdr_u_int (xdrs, &objp->fhs_status)) + return FALSE; + switch (objp->fhs_status) { + case 0: + if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_dirpath (XDR *xdrs, dirpath *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, objp, MNTPATHLEN)) + return FALSE; + return TRUE; +} + +bool_t +xdr_name (XDR *xdrs, name *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, objp, MNTNAMLEN)) + return FALSE; + return TRUE; +} + +bool_t +xdr_mountlist (XDR *xdrs, mountlist *objp) +{ + register int32_t *buf; + + if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody)) + return FALSE; + return TRUE; +} + +bool_t +xdr_mountbody (XDR *xdrs, mountbody *objp) +{ + register int32_t *buf; + + if (!xdr_name (xdrs, &objp->ml_hostname)) + return FALSE; + if (!xdr_dirpath (xdrs, &objp->ml_directory)) + return FALSE; + if (!xdr_mountlist (xdrs, &objp->ml_next)) + return FALSE; + return TRUE; +} + +bool_t +xdr_groups (XDR *xdrs, groups *objp) +{ + register int32_t *buf; + + if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode)) + return FALSE; + return TRUE; +} + +bool_t +xdr_groupnode (XDR *xdrs, groupnode *objp) +{ + register int32_t *buf; + + if (!xdr_name (xdrs, &objp->gr_name)) + return FALSE; + if (!xdr_groups (xdrs, &objp->gr_next)) + return FALSE; + return TRUE; +} + +bool_t +xdr_exports (XDR *xdrs, exports *objp) +{ + register int32_t *buf; + + if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode)) + return FALSE; + return TRUE; +} + +bool_t +xdr_exportnode (XDR *xdrs, exportnode *objp) +{ + register int32_t *buf; + + if (!xdr_dirpath (xdrs, &objp->ex_dir)) + return FALSE; + if (!xdr_groups (xdrs, &objp->ex_groups)) + return FALSE; + if (!xdr_exports (xdrs, &objp->ex_next)) + return FALSE; + return TRUE; +} diff --git a/rtemsNfs/proto/nfs_prot.h b/rtemsNfs/proto/nfs_prot.h new file mode 100644 index 0000000..de812db --- /dev/null +++ b/rtemsNfs/proto/nfs_prot.h @@ -0,0 +1,453 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NFS_PROT_H_RPCGEN +#define _NFS_PROT_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFS_PORT 2049 +#define NFS_MAXDATA 8192 +#define NFS_MAXPATHLEN 1024 +#define NFS_MAXNAMLEN 255 +#define NFS_FHSIZE 32 +#define NFS_COOKIESIZE 4 +#define NFS_FIFO_DEV -1 +#define NFSMODE_FMT 0170000 +#define NFSMODE_DIR 0040000 +#define NFSMODE_CHR 0020000 +#define NFSMODE_BLK 0060000 +#define NFSMODE_REG 0100000 +#define NFSMODE_LNK 0120000 +#define NFSMODE_SOCK 0140000 +#define NFSMODE_FIFO 0010000 + +enum nfsstat { + NFS_OK = 0, + NFSERR_PERM = 1, + NFSERR_NOENT = 2, + NFSERR_IO = 5, + NFSERR_NXIO = 6, + NFSERR_ACCES = 13, + NFSERR_EXIST = 17, + NFSERR_NODEV = 19, + NFSERR_NOTDIR = 20, + NFSERR_ISDIR = 21, + NFSERR_FBIG = 27, + NFSERR_NOSPC = 28, + NFSERR_ROFS = 30, + NFSERR_NAMETOOLONG = 63, + NFSERR_NOTEMPTY = 66, + NFSERR_DQUOT = 69, + NFSERR_STALE = 70, + NFSERR_WFLUSH = 99, +}; +typedef enum nfsstat nfsstat; + +enum ftype { + NFNON = 0, + NFREG = 1, + NFDIR = 2, + NFBLK = 3, + NFCHR = 4, + NFLNK = 5, + NFSOCK = 6, + NFBAD = 7, + NFFIFO = 8, +}; +typedef enum ftype ftype; + +struct nfs_fh { + char data[NFS_FHSIZE]; +}; +typedef struct nfs_fh nfs_fh; + +struct nfstime { + u_int seconds; + u_int useconds; +}; +typedef struct nfstime nfstime; + +struct fattr { + ftype type; + u_int mode; + u_int nlink; + u_int uid; + u_int gid; + u_int size; + u_int blocksize; + u_int rdev; + u_int blocks; + u_int fsid; + u_int fileid; + nfstime atime; + nfstime mtime; + nfstime ctime; +}; +typedef struct fattr fattr; + +struct sattr { + u_int mode; + u_int uid; + u_int gid; + u_int size; + nfstime atime; + nfstime mtime; +}; +typedef struct sattr sattr; + +typedef char *filename; + +typedef char *nfspath; + +struct attrstat { + nfsstat status; + union { + fattr attributes; + } attrstat_u; +}; +typedef struct attrstat attrstat; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; +typedef struct sattrargs sattrargs; + +struct diropargs { + nfs_fh dir; + filename name; +}; +typedef struct diropargs diropargs; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; +typedef struct diropokres diropokres; + +struct diropres { + nfsstat status; + union { + diropokres diropres; + } diropres_u; +}; +typedef struct diropres diropres; + +struct readlinkres { + nfsstat status; + union { + nfspath data; + } readlinkres_u; +}; +typedef struct readlinkres readlinkres; + +struct readargs { + nfs_fh file; + u_int offset; + u_int count; + u_int totalcount; +}; +typedef struct readargs readargs; + +struct readokres { + fattr attributes; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct readokres readokres; + +struct readres { + nfsstat status; + union { + readokres reply; + } readres_u; +}; +typedef struct readres readres; + +struct writeargs { + nfs_fh file; + u_int beginoffset; + u_int offset; + u_int totalcount; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct writeargs writeargs; + +struct createargs { + diropargs where; + sattr attributes; +}; +typedef struct createargs createargs; + +struct renameargs { + diropargs from; + diropargs to; +}; +typedef struct renameargs renameargs; + +struct linkargs { + nfs_fh from; + diropargs to; +}; +typedef struct linkargs linkargs; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; +typedef struct symlinkargs symlinkargs; + +struct nfscookie { + char data[NFS_COOKIESIZE]; +}; +typedef struct nfscookie nfscookie; + +struct readdirargs { + nfs_fh dir; + nfscookie cookie; + u_int count; +}; +typedef struct readdirargs readdirargs; + +struct entry { + u_int fileid; + filename name; + nfscookie cookie; + struct entry *nextentry; +}; +typedef struct entry entry; + +struct dirlist { + entry *entries; + bool_t eof; +}; +typedef struct dirlist dirlist; + +struct readdirres { + nfsstat status; + union { + dirlist reply; + } readdirres_u; +}; +typedef struct readdirres readdirres; + +struct statfsokres { + u_int tsize; + u_int bsize; + u_int blocks; + u_int bfree; + u_int bavail; +}; +typedef struct statfsokres statfsokres; + +struct statfsres { + nfsstat status; + union { + statfsokres reply; + } statfsres_u; +}; +typedef struct statfsres statfsres; + +#define NFS_PROGRAM 100003 +#define NFS_VERSION 2 + +#if defined(__STDC__) || defined(__cplusplus) +#define NFSPROC_NULL 0 +extern void * nfsproc_null_2(void *, CLIENT *); +extern void * nfsproc_null_2_svc(void *, struct svc_req *); +#define NFSPROC_GETATTR 1 +extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *); +extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_SETATTR 2 +extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *); +extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *); +#define NFSPROC_ROOT 3 +extern void * nfsproc_root_2(void *, CLIENT *); +extern void * nfsproc_root_2_svc(void *, struct svc_req *); +#define NFSPROC_LOOKUP 4 +extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *); +extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READLINK 5 +extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *); +extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_READ 6 +extern readres * nfsproc_read_2(readargs *, CLIENT *); +extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *); +#define NFSPROC_WRITECACHE 7 +extern void * nfsproc_writecache_2(void *, CLIENT *); +extern void * nfsproc_writecache_2_svc(void *, struct svc_req *); +#define NFSPROC_WRITE 8 +extern attrstat * nfsproc_write_2(writeargs *, CLIENT *); +extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *); +#define NFSPROC_CREATE 9 +extern diropres * nfsproc_create_2(createargs *, CLIENT *); +extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *); +#define NFSPROC_REMOVE 10 +extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *); +extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_RENAME 11 +extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *); +extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *); +#define NFSPROC_LINK 12 +extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *); +extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *); +#define NFSPROC_SYMLINK 13 +extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *); +extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *); +#define NFSPROC_MKDIR 14 +extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *); +extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *); +#define NFSPROC_RMDIR 15 +extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *); +extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READDIR 16 +extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *); +extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *); +#define NFSPROC_STATFS 17 +extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *); +extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *); +extern int nfs_program_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define NFSPROC_NULL 0 +extern void * nfsproc_null_2(); +extern void * nfsproc_null_2_svc(); +#define NFSPROC_GETATTR 1 +extern attrstat * nfsproc_getattr_2(); +extern attrstat * nfsproc_getattr_2_svc(); +#define NFSPROC_SETATTR 2 +extern attrstat * nfsproc_setattr_2(); +extern attrstat * nfsproc_setattr_2_svc(); +#define NFSPROC_ROOT 3 +extern void * nfsproc_root_2(); +extern void * nfsproc_root_2_svc(); +#define NFSPROC_LOOKUP 4 +extern diropres * nfsproc_lookup_2(); +extern diropres * nfsproc_lookup_2_svc(); +#define NFSPROC_READLINK 5 +extern readlinkres * nfsproc_readlink_2(); +extern readlinkres * nfsproc_readlink_2_svc(); +#define NFSPROC_READ 6 +extern readres * nfsproc_read_2(); +extern readres * nfsproc_read_2_svc(); +#define NFSPROC_WRITECACHE 7 +extern void * nfsproc_writecache_2(); +extern void * nfsproc_writecache_2_svc(); +#define NFSPROC_WRITE 8 +extern attrstat * nfsproc_write_2(); +extern attrstat * nfsproc_write_2_svc(); +#define NFSPROC_CREATE 9 +extern diropres * nfsproc_create_2(); +extern diropres * nfsproc_create_2_svc(); +#define NFSPROC_REMOVE 10 +extern nfsstat * nfsproc_remove_2(); +extern nfsstat * nfsproc_remove_2_svc(); +#define NFSPROC_RENAME 11 +extern nfsstat * nfsproc_rename_2(); +extern nfsstat * nfsproc_rename_2_svc(); +#define NFSPROC_LINK 12 +extern nfsstat * nfsproc_link_2(); +extern nfsstat * nfsproc_link_2_svc(); +#define NFSPROC_SYMLINK 13 +extern nfsstat * nfsproc_symlink_2(); +extern nfsstat * nfsproc_symlink_2_svc(); +#define NFSPROC_MKDIR 14 +extern diropres * nfsproc_mkdir_2(); +extern diropres * nfsproc_mkdir_2_svc(); +#define NFSPROC_RMDIR 15 +extern nfsstat * nfsproc_rmdir_2(); +extern nfsstat * nfsproc_rmdir_2_svc(); +#define NFSPROC_READDIR 16 +extern readdirres * nfsproc_readdir_2(); +extern readdirres * nfsproc_readdir_2_svc(); +#define NFSPROC_STATFS 17 +extern statfsres * nfsproc_statfs_2(); +extern statfsres * nfsproc_statfs_2_svc(); +extern int nfs_program_2_freeresult (); +#endif /* K&R C */ + +/* the xdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_nfsstat (XDR *, nfsstat*); +extern bool_t xdr_ftype (XDR *, ftype*); +extern bool_t xdr_nfs_fh (XDR *, nfs_fh*); +extern bool_t xdr_nfstime (XDR *, nfstime*); +extern bool_t xdr_fattr (XDR *, fattr*); +extern bool_t xdr_sattr (XDR *, sattr*); +extern bool_t xdr_filename (XDR *, filename*); +extern bool_t xdr_nfspath (XDR *, nfspath*); +extern bool_t xdr_attrstat (XDR *, attrstat*); +extern bool_t xdr_sattrargs (XDR *, sattrargs*); +extern bool_t xdr_diropargs (XDR *, diropargs*); +extern bool_t xdr_diropokres (XDR *, diropokres*); +extern bool_t xdr_diropres (XDR *, diropres*); +extern bool_t xdr_readlinkres (XDR *, readlinkres*); +extern bool_t xdr_readargs (XDR *, readargs*); +extern bool_t xdr_readokres (XDR *, readokres*); +extern bool_t xdr_readres (XDR *, readres*); +extern bool_t xdr_writeargs (XDR *, writeargs*); +extern bool_t xdr_createargs (XDR *, createargs*); +extern bool_t xdr_renameargs (XDR *, renameargs*); +extern bool_t xdr_linkargs (XDR *, linkargs*); +extern bool_t xdr_symlinkargs (XDR *, symlinkargs*); +extern bool_t xdr_nfscookie (XDR *, nfscookie*); +extern bool_t xdr_readdirargs (XDR *, readdirargs*); +extern bool_t xdr_entry (XDR *, entry*); +extern bool_t xdr_dirlist (XDR *, dirlist*); +extern bool_t xdr_readdirres (XDR *, readdirres*); +extern bool_t xdr_statfsokres (XDR *, statfsokres*); +extern bool_t xdr_statfsres (XDR *, statfsres*); + +#else /* K&R C */ +extern bool_t xdr_nfsstat (); +extern bool_t xdr_ftype (); +extern bool_t xdr_nfs_fh (); +extern bool_t xdr_nfstime (); +extern bool_t xdr_fattr (); +extern bool_t xdr_sattr (); +extern bool_t xdr_filename (); +extern bool_t xdr_nfspath (); +extern bool_t xdr_attrstat (); +extern bool_t xdr_sattrargs (); +extern bool_t xdr_diropargs (); +extern bool_t xdr_diropokres (); +extern bool_t xdr_diropres (); +extern bool_t xdr_readlinkres (); +extern bool_t xdr_readargs (); +extern bool_t xdr_readokres (); +extern bool_t xdr_readres (); +extern bool_t xdr_writeargs (); +extern bool_t xdr_createargs (); +extern bool_t xdr_renameargs (); +extern bool_t xdr_linkargs (); +extern bool_t xdr_symlinkargs (); +extern bool_t xdr_nfscookie (); +extern bool_t xdr_readdirargs (); +extern bool_t xdr_entry (); +extern bool_t xdr_dirlist (); +extern bool_t xdr_readdirres (); +extern bool_t xdr_statfsokres (); +extern bool_t xdr_statfsres (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_NFS_PROT_H_RPCGEN */ diff --git a/rtemsNfs/proto/nfs_prot.x b/rtemsNfs/proto/nfs_prot.x new file mode 100644 index 0000000..a40d9a5 --- /dev/null +++ b/rtemsNfs/proto/nfs_prot.x @@ -0,0 +1,1268 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static char rcsid[] = "$Id$"; +%#endif /* not lint */ +#endif + +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* prefered block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename; +typedef string nfspath; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +/* TS, 10/21/2002; converted cookie to struct */ +struct nfscookie { + opaque data[NFS_COOKIESIZE]; +}; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +#ifdef WANT_NFS3 + +/* + * NFSv3 constants and types + */ +const NFS3_FHSIZE = 64; /* maximum size in bytes of a file handle */ +const NFS3_COOKIEVERFSIZE = 8; /* size of a cookie verifier for READDIR */ +const NFS3_CREATEVERFSIZE = 8; /* size of the verifier used for CREATE */ +const NFS3_WRITEVERFSIZE = 8; /* size of the verifier used for WRITE */ + +typedef unsigned hyper uint64; +typedef hyper int64; +typedef unsigned long uint32; +typedef long int32; +typedef string filename3<>; +typedef string nfspath3<>; +typedef uint64 fileid3; +typedef uint64 cookie3; +typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; +typedef opaque createverf3[NFS3_CREATEVERFSIZE]; +typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; +typedef uint32 uid3; +typedef uint32 gid3; +typedef uint64 size3; +typedef uint64 offset3; +typedef uint32 mode3; +typedef uint32 count3; + +/* + * Error status (v3) + */ +enum nfsstat3 { + NFS3_OK = 0, + NFS3ERR_PERM = 1, + NFS3ERR_NOENT = 2, + NFS3ERR_IO = 5, + NFS3ERR_NXIO = 6, + NFS3ERR_ACCES = 13, + NFS3ERR_EXIST = 17, + NFS3ERR_XDEV = 18, + NFS3ERR_NODEV = 19, + NFS3ERR_NOTDIR = 20, + NFS3ERR_ISDIR = 21, + NFS3ERR_INVAL = 22, + NFS3ERR_FBIG = 27, + NFS3ERR_NOSPC = 28, + NFS3ERR_ROFS = 30, + NFS3ERR_MLINK = 31, + NFS3ERR_NAMETOOLONG = 63, + NFS3ERR_NOTEMPTY = 66, + NFS3ERR_DQUOT = 69, + NFS3ERR_STALE = 70, + NFS3ERR_REMOTE = 71, + NFS3ERR_BADHANDLE = 10001, + NFS3ERR_NOT_SYNC = 10002, + NFS3ERR_BAD_COOKIE = 10003, + NFS3ERR_NOTSUPP = 10004, + NFS3ERR_TOOSMALL = 10005, + NFS3ERR_SERVERFAULT = 10006, + NFS3ERR_BADTYPE = 10007, + NFS3ERR_JUKEBOX = 10008 +}; + +/* + * File types (v3) + */ +enum ftype3 { + NF3REG = 1, /* regular file */ + NF3DIR = 2, /* directory */ + NF3BLK = 3, /* block special */ + NF3CHR = 4, /* character special */ + NF3LNK = 5, /* symbolic link */ + NF3SOCK = 6, /* unix domain sockets */ + NF3FIFO = 7 /* named pipe */ +}; + +struct specdata3 { + uint32 specdata1; + uint32 specdata2; +}; + +/* + * File access handle (v3) + */ +struct nfs_fh3 { + opaque data; +}; + +/* + * Timeval (v3) + */ +struct nfstime3 { + uint32 seconds; + uint32 nseconds; +}; + + +/* + * File attributes (v3) + */ +struct fattr3 { + ftype3 type; /* file type */ + mode3 mode; /* protection mode bits */ + uint32 nlink; /* # hard links */ + uid3 uid; /* owner user id */ + gid3 gid; /* owner group id */ + size3 size; /* file size in bytes */ + size3 used; /* prefered block size */ + specdata3 rdev; /* special device # */ + uint64 fsid; /* device # */ + fileid3 fileid; /* inode # */ + nfstime3 atime; /* time of last access */ + nfstime3 mtime; /* time of last modification */ + nfstime3 ctime; /* time of last change */ +}; + +union post_op_attr switch (bool attributes_follow) { +case TRUE: + fattr3 attributes; +case FALSE: + void; +}; + +struct wcc_attr { + size3 size; + nfstime3 mtime; + nfstime3 ctime; +}; + +union pre_op_attr switch (bool attributes_follow) { +case TRUE: + wcc_attr attributes; +case FALSE: + void; +}; + +struct wcc_data { + pre_op_attr before; + post_op_attr after; +}; + +union post_op_fh3 switch (bool handle_follows) { +case TRUE: + nfs_fh3 handle; +case FALSE: + void; +}; + +/* + * File attributes which can be set (v3) + */ +enum time_how { + DONT_CHANGE = 0, + SET_TO_SERVER_TIME = 1, + SET_TO_CLIENT_TIME = 2 +}; + +union set_mode3 switch (bool set_it) { +case TRUE: + mode3 mode; +default: + void; +}; + +union set_uid3 switch (bool set_it) { +case TRUE: + uid3 uid; +default: + void; +}; + +union set_gid3 switch (bool set_it) { +case TRUE: + gid3 gid; +default: + void; +}; + +union set_size3 switch (bool set_it) { +case TRUE: + size3 size; +default: + void; +}; + +union set_atime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 atime; +default: + void; +}; + +union set_mtime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 mtime; +default: + void; +}; + +struct sattr3 { + set_mode3 mode; + set_uid3 uid; + set_gid3 gid; + set_size3 size; + set_atime atime; + set_mtime mtime; +}; + +/* + * Arguments for directory operations (v3) + */ +struct diropargs3 { + nfs_fh3 dir; /* directory file handle */ + filename3 name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +/* + * Arguments to getattr (v3). + */ +struct GETATTR3args { + nfs_fh3 object; +}; + +struct GETATTR3resok { + fattr3 obj_attributes; +}; + +union GETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + GETATTR3resok resok; +default: + void; +}; + +/* + * Arguments to setattr (v3). + */ +union sattrguard3 switch (bool check) { +case TRUE: + nfstime3 obj_ctime; +case FALSE: + void; +}; + +struct SETATTR3args { + nfs_fh3 object; + sattr3 new_attributes; + sattrguard3 guard; +}; + +struct SETATTR3resok { + wcc_data obj_wcc; +}; + +struct SETATTR3resfail { + wcc_data obj_wcc; +}; + +union SETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + SETATTR3resok resok; +default: + SETATTR3resfail resfail; +}; + +/* + * Arguments to lookup (v3). + */ +struct LOOKUP3args { + diropargs3 what; +}; + +struct LOOKUP3resok { + nfs_fh3 object; + post_op_attr obj_attributes; + post_op_attr dir_attributes; +}; + +struct LOOKUP3resfail { + post_op_attr dir_attributes; +}; + +union LOOKUP3res switch (nfsstat3 status) { +case NFS3_OK: + LOOKUP3resok resok; +default: + LOOKUP3resfail resfail; +}; + +/* + * Arguments to access (v3). + */ +const ACCESS3_READ = 0x0001; +const ACCESS3_LOOKUP = 0x0002; +const ACCESS3_MODIFY = 0x0004; +const ACCESS3_EXTEND = 0x0008; +const ACCESS3_DELETE = 0x0010; +const ACCESS3_EXECUTE = 0x0020; + +struct ACCESS3args { + nfs_fh3 object; + uint32 access; +}; + +struct ACCESS3resok { + post_op_attr obj_attributes; + uint32 access; +}; + +struct ACCESS3resfail { + post_op_attr obj_attributes; +}; + +union ACCESS3res switch (nfsstat3 status) { +case NFS3_OK: + ACCESS3resok resok; +default: + ACCESS3resfail resfail; +}; + +/* + * Arguments to readlink (v3). + */ +struct READLINK3args { + nfs_fh3 symlink; +}; + +struct READLINK3resok { + post_op_attr symlink_attributes; + nfspath3 data; +}; + +struct READLINK3resfail { + post_op_attr symlink_attributes; +}; + +union READLINK3res switch (nfsstat3 status) { +case NFS3_OK: + READLINK3resok resok; +default: + READLINK3resfail resfail; +}; + +/* + * Arguments to read (v3). + */ +struct READ3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct READ3resok { + post_op_attr file_attributes; + count3 count; + bool eof; + opaque data<>; +}; + +struct READ3resfail { + post_op_attr file_attributes; +}; + +/* XXX: solaris 2.6 uses ``nfsstat'' here */ +union READ3res switch (nfsstat3 status) { +case NFS3_OK: + READ3resok resok; +default: + READ3resfail resfail; +}; + +/* + * Arguments to write (v3). + */ +enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2 +}; + +struct WRITE3args { + nfs_fh3 file; + offset3 offset; + count3 count; + stable_how stable; + opaque data<>; +}; + +struct WRITE3resok { + wcc_data file_wcc; + count3 count; + stable_how committed; + writeverf3 verf; +}; + +struct WRITE3resfail { + wcc_data file_wcc; +}; + +union WRITE3res switch (nfsstat3 status) { +case NFS3_OK: + WRITE3resok resok; +default: + WRITE3resfail resfail; +}; + +/* + * Arguments to create (v3). + */ +enum createmode3 { + UNCHECKED = 0, + GUARDED = 1, + EXCLUSIVE = 2 +}; + +union createhow3 switch (createmode3 mode) { +case UNCHECKED: +case GUARDED: + sattr3 obj_attributes; +case EXCLUSIVE: + createverf3 verf; +}; + +struct CREATE3args { + diropargs3 where; + createhow3 how; +}; + +struct CREATE3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct CREATE3resfail { + wcc_data dir_wcc; +}; + +union CREATE3res switch (nfsstat3 status) { +case NFS3_OK: + CREATE3resok resok; +default: + CREATE3resfail resfail; +}; + +/* + * Arguments to mkdir (v3). + */ +struct MKDIR3args { + diropargs3 where; + sattr3 attributes; +}; + +struct MKDIR3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKDIR3resfail { + wcc_data dir_wcc; +}; + +union MKDIR3res switch (nfsstat3 status) { +case NFS3_OK: + MKDIR3resok resok; +default: + MKDIR3resfail resfail; +}; + +/* + * Arguments to symlink (v3). + */ +struct symlinkdata3 { + sattr3 symlink_attributes; + nfspath3 symlink_data; +}; + +struct SYMLINK3args { + diropargs3 where; + symlinkdata3 symlink; +}; + +struct SYMLINK3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct SYMLINK3resfail { + wcc_data dir_wcc; +}; + +union SYMLINK3res switch (nfsstat3 status) { +case NFS3_OK: + SYMLINK3resok resok; +default: + SYMLINK3resfail resfail; +}; + +/* + * Arguments to mknod (v3). + */ +struct devicedata3 { + sattr3 dev_attributes; + specdata3 spec; +}; + +union mknoddata3 switch (ftype3 type) { +case NF3CHR: +case NF3BLK: + devicedata3 device; +case NF3SOCK: +case NF3FIFO: + sattr3 pipe_attributes; +default: + void; +}; + +struct MKNOD3args { + diropargs3 where; + mknoddata3 what; +}; + +struct MKNOD3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKNOD3resfail { + wcc_data dir_wcc; +}; + +union MKNOD3res switch (nfsstat3 status) { +case NFS3_OK: + MKNOD3resok resok; +default: + MKNOD3resfail resfail; +}; + +/* + * Arguments to remove (v3). + */ +struct REMOVE3args { + diropargs3 object; +}; + +struct REMOVE3resok { + wcc_data dir_wcc; +}; + +struct REMOVE3resfail { + wcc_data dir_wcc; +}; + +union REMOVE3res switch (nfsstat3 status) { +case NFS3_OK: + REMOVE3resok resok; +default: + REMOVE3resfail resfail; +}; + +/* + * Arguments to rmdir (v3). + */ +struct RMDIR3args { + diropargs3 object; +}; + +struct RMDIR3resok { + wcc_data dir_wcc; +}; + +struct RMDIR3resfail { + wcc_data dir_wcc; +}; + +union RMDIR3res switch (nfsstat3 status) { +case NFS3_OK: + RMDIR3resok resok; +default: + RMDIR3resfail resfail; +}; + +/* + * Arguments to rename (v3). + */ +struct RENAME3args { + diropargs3 from; + diropargs3 to; +}; + +struct RENAME3resok { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +struct RENAME3resfail { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +union RENAME3res switch (nfsstat3 status) { +case NFS3_OK: + RENAME3resok resok; +default: + RENAME3resfail resfail; +}; + +/* + * Arguments to link (v3). + */ +struct LINK3args { + nfs_fh3 file; + diropargs3 link; +}; + +struct LINK3resok { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +struct LINK3resfail { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +union LINK3res switch (nfsstat3 status) { +case NFS3_OK: + LINK3resok resok; +default: + LINK3resfail resfail; +}; + +/* + * Arguments to readdir (v3). + */ +struct READDIR3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 count; +}; + +struct entry3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + entry3 *nextentry; +}; + +struct dirlist3 { + entry3 *entries; + bool eof; +}; + +struct READDIR3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlist3 reply; +}; + +struct READDIR3resfail { + post_op_attr dir_attributes; +}; + +union READDIR3res switch (nfsstat3 status) { +case NFS3_OK: + READDIR3resok resok; +default: + READDIR3resfail resfail; +}; + +/* + * Arguments to readdirplus (v3). + */ +struct READDIRPLUS3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 dircount; + count3 maxcount; +}; + +struct entryplus3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + post_op_attr name_attributes; + post_op_fh3 name_handle; + entryplus3 *nextentry; +}; + +struct dirlistplus3 { + entryplus3 *entries; + bool eof; +}; + +struct READDIRPLUS3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlistplus3 reply; +}; + +struct READDIRPLUS3resfail { + post_op_attr dir_attributes; +}; + +union READDIRPLUS3res switch (nfsstat3 status) { +case NFS3_OK: + READDIRPLUS3resok resok; +default: + READDIRPLUS3resfail resfail; +}; + +/* + * Arguments to fsstat (v3). + */ +struct FSSTAT3args { + nfs_fh3 fsroot; +}; + +struct FSSTAT3resok { + post_op_attr obj_attributes; + size3 tbytes; + size3 fbytes; + size3 abytes; + size3 tfiles; + size3 ffiles; + size3 afiles; + uint32 invarsec; +}; + +struct FSSTAT3resfail { + post_op_attr obj_attributes; +}; + +union FSSTAT3res switch (nfsstat3 status) { +case NFS3_OK: + FSSTAT3resok resok; +default: + FSSTAT3resfail resfail; +}; + +/* + * Arguments to fsinfo (v3). + */ +const FSF3_LINK = 0x0001; +const FSF3_SYMLINK = 0x0002; +const FSF3_HOMOGENEOUS = 0x0008; +const FSF3_CANSETTIME = 0x0010; + +struct FSINFO3args { + nfs_fh3 fsroot; +}; + +struct FSINFO3resok { + post_op_attr obj_attributes; + uint32 rtmax; + uint32 rtpref; + uint32 rtmult; + uint32 wtmax; + uint32 wtpref; + uint32 wtmult; + uint32 dtpref; + size3 maxfilesize; + nfstime3 time_delta; + uint32 properties; +}; + +struct FSINFO3resfail { + post_op_attr obj_attributes; +}; + +union FSINFO3res switch (nfsstat3 status) { +case NFS3_OK: + FSINFO3resok resok; +default: + FSINFO3resfail resfail; +}; + +/* + * Arguments to pathconf (v3). + */ +struct PATHCONF3args { + nfs_fh3 object; +}; + +struct PATHCONF3resok { + post_op_attr obj_attributes; + uint32 linkmax; + uint32 name_max; + bool no_trunc; + bool chown_restricted; + bool case_insensitive; + bool case_preserving; +}; + +struct PATHCONF3resfail { + post_op_attr obj_attributes; +}; + +union PATHCONF3res switch (nfsstat3 status) { +case NFS3_OK: + PATHCONF3resok resok; +default: + PATHCONF3resfail resfail; +}; + +/* + * Arguments to commit (v3). + */ +struct COMMIT3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct COMMIT3resok { + wcc_data file_wcc; + writeverf3 verf; +}; + +struct COMMIT3resfail { + wcc_data file_wcc; +}; + +union COMMIT3res switch (nfsstat3 status) { +case NFS3_OK: + COMMIT3resok resok; +default: + COMMIT3resfail resfail; +}; + +#endif /* WANT_NFS3 */ + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; +#ifdef WANT_NFS3 +program NFS3_PROGRAM { + version NFS_V3 { + void + NFSPROC3_NULL(void) = 0; + + GETATTR3res + NFSPROC3_GETATTR(GETATTR3args) = 1; + + SETATTR3res + NFSPROC3_SETATTR(SETATTR3args) = 2; + + LOOKUP3res + NFSPROC3_LOOKUP(LOOKUP3args) = 3; + + ACCESS3res + NFSPROC3_ACCESS(ACCESS3args) = 4; + + READLINK3res + NFSPROC3_READLINK(READLINK3args) = 5; + + READ3res + NFSPROC3_READ(READ3args) = 6; + + WRITE3res + NFSPROC3_WRITE(WRITE3args) = 7; + + CREATE3res + NFSPROC3_CREATE(CREATE3args) = 8; + + MKDIR3res + NFSPROC3_MKDIR(MKDIR3args) = 9; + + SYMLINK3res + NFSPROC3_SYMLINK(SYMLINK3args) = 10; + + MKNOD3res + NFSPROC3_MKNOD(MKNOD3args) = 11; + + REMOVE3res + NFSPROC3_REMOVE(REMOVE3args) = 12; + + RMDIR3res + NFSPROC3_RMDIR(RMDIR3args) = 13; + + RENAME3res + NFSPROC3_RENAME(RENAME3args) = 14; + + LINK3res + NFSPROC3_LINK(LINK3args) = 15; + + READDIR3res + NFSPROC3_READDIR(READDIR3args) = 16; + + READDIRPLUS3res + NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17; + + FSSTAT3res + NFSPROC3_FSSTAT(FSSTAT3args) = 18; + + FSINFO3res + NFSPROC3_FSINFO(FSINFO3args) = 19; + + PATHCONF3res + NFSPROC3_PATHCONF(PATHCONF3args) = 20; + + COMMIT3res + NFSPROC3_COMMIT(COMMIT3args) = 21; + } = 3; +} = 100003; +#endif + diff --git a/rtemsNfs/proto/nfs_prot_xdr.c b/rtemsNfs/proto/nfs_prot_xdr.c new file mode 100644 index 0000000..7e222ec --- /dev/null +++ b/rtemsNfs/proto/nfs_prot_xdr.c @@ -0,0 +1,671 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "nfs_prot.h" +#ifndef lint +/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/ +/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +static char rcsid[] = "$Id$"; +#endif /* not lint */ + +bool_t +xdr_nfsstat (XDR *xdrs, nfsstat *objp) +{ + register int32_t *buf; + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_ftype (XDR *xdrs, ftype *objp) +{ + register int32_t *buf; + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_nfs_fh (XDR *xdrs, nfs_fh *objp) +{ + register int32_t *buf; + + int i; + if (!xdr_opaque (xdrs, objp->data, NFS_FHSIZE)) + return FALSE; + return TRUE; +} + +bool_t +xdr_nfstime (XDR *xdrs, nfstime *objp) +{ + register int32_t *buf; + + if (!xdr_u_int (xdrs, &objp->seconds)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->useconds)) + return FALSE; + return TRUE; +} + +bool_t +xdr_fattr (XDR *xdrs, fattr *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_ftype (xdrs, &objp->type)) + return FALSE; + buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->nlink)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocksize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->rdev)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fsid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fileid)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->mode); + IXDR_PUT_U_LONG(buf, objp->nlink); + IXDR_PUT_U_LONG(buf, objp->uid); + IXDR_PUT_U_LONG(buf, objp->gid); + IXDR_PUT_U_LONG(buf, objp->size); + IXDR_PUT_U_LONG(buf, objp->blocksize); + IXDR_PUT_U_LONG(buf, objp->rdev); + IXDR_PUT_U_LONG(buf, objp->blocks); + IXDR_PUT_U_LONG(buf, objp->fsid); + IXDR_PUT_U_LONG(buf, objp->fileid); + } + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->ctime)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_ftype (xdrs, &objp->type)) + return FALSE; + buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->nlink)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocksize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->rdev)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fsid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fileid)) + return FALSE; + + } else { + objp->mode = IXDR_GET_U_LONG(buf); + objp->nlink = IXDR_GET_U_LONG(buf); + objp->uid = IXDR_GET_U_LONG(buf); + objp->gid = IXDR_GET_U_LONG(buf); + objp->size = IXDR_GET_U_LONG(buf); + objp->blocksize = IXDR_GET_U_LONG(buf); + objp->rdev = IXDR_GET_U_LONG(buf); + objp->blocks = IXDR_GET_U_LONG(buf); + objp->fsid = IXDR_GET_U_LONG(buf); + objp->fileid = IXDR_GET_U_LONG(buf); + } + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->ctime)) + return FALSE; + return TRUE; + } + + if (!xdr_ftype (xdrs, &objp->type)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->nlink)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocksize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->rdev)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fsid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->fileid)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->ctime)) + return FALSE; + return TRUE; +} + +bool_t +xdr_sattr (XDR *xdrs, sattr *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->mode); + IXDR_PUT_U_LONG(buf, objp->uid); + IXDR_PUT_U_LONG(buf, objp->gid); + IXDR_PUT_U_LONG(buf, objp->size); + } + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + + } else { + objp->mode = IXDR_GET_U_LONG(buf); + objp->uid = IXDR_GET_U_LONG(buf); + objp->gid = IXDR_GET_U_LONG(buf); + objp->size = IXDR_GET_U_LONG(buf); + } + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + return TRUE; + } + + if (!xdr_u_int (xdrs, &objp->mode)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->uid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->gid)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->size)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->atime)) + return FALSE; + if (!xdr_nfstime (xdrs, &objp->mtime)) + return FALSE; + return TRUE; +} + +bool_t +xdr_filename (XDR *xdrs, filename *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, objp, NFS_MAXNAMLEN)) + return FALSE; + return TRUE; +} + +bool_t +xdr_nfspath (XDR *xdrs, nfspath *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, objp, NFS_MAXPATHLEN)) + return FALSE; + return TRUE; +} + +bool_t +xdr_attrstat (XDR *xdrs, attrstat *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_fattr (xdrs, &objp->attrstat_u.attributes)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_sattrargs (XDR *xdrs, sattrargs *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + if (!xdr_sattr (xdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +xdr_diropargs (XDR *xdrs, diropargs *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->dir)) + return FALSE; + if (!xdr_filename (xdrs, &objp->name)) + return FALSE; + return TRUE; +} + +bool_t +xdr_diropokres (XDR *xdrs, diropokres *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + if (!xdr_fattr (xdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +xdr_diropres (XDR *xdrs, diropres *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_diropokres (xdrs, &objp->diropres_u.diropres)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_readlinkres (XDR *xdrs, readlinkres *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_nfspath (xdrs, &objp->readlinkres_u.data)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_readargs (XDR *xdrs, readargs *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->offset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->count)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->totalcount)) + return FALSE; + return TRUE; +} + +bool_t +xdr_readokres (XDR *xdrs, readokres *objp) +{ + register int32_t *buf; + + if (!xdr_fattr (xdrs, &objp->attributes)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA)) + return FALSE; + return TRUE; +} + +bool_t +xdr_readres (XDR *xdrs, readres *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_readokres (xdrs, &objp->readres_u.reply)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_writeargs (XDR *xdrs, writeargs *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->beginoffset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->offset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->totalcount)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->beginoffset); + IXDR_PUT_U_LONG(buf, objp->offset); + IXDR_PUT_U_LONG(buf, objp->totalcount); + } + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->beginoffset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->offset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->totalcount)) + return FALSE; + + } else { + objp->beginoffset = IXDR_GET_U_LONG(buf); + objp->offset = IXDR_GET_U_LONG(buf); + objp->totalcount = IXDR_GET_U_LONG(buf); + } + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA)) + return FALSE; + return TRUE; + } + + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->beginoffset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->offset)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->totalcount)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA)) + return FALSE; + return TRUE; +} + +bool_t +xdr_createargs (XDR *xdrs, createargs *objp) +{ + register int32_t *buf; + + if (!xdr_diropargs (xdrs, &objp->where)) + return FALSE; + if (!xdr_sattr (xdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +xdr_renameargs (XDR *xdrs, renameargs *objp) +{ + register int32_t *buf; + + if (!xdr_diropargs (xdrs, &objp->from)) + return FALSE; + if (!xdr_diropargs (xdrs, &objp->to)) + return FALSE; + return TRUE; +} + +bool_t +xdr_linkargs (XDR *xdrs, linkargs *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->from)) + return FALSE; + if (!xdr_diropargs (xdrs, &objp->to)) + return FALSE; + return TRUE; +} + +bool_t +xdr_symlinkargs (XDR *xdrs, symlinkargs *objp) +{ + register int32_t *buf; + + if (!xdr_diropargs (xdrs, &objp->from)) + return FALSE; + if (!xdr_nfspath (xdrs, &objp->to)) + return FALSE; + if (!xdr_sattr (xdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +xdr_nfscookie (XDR *xdrs, nfscookie *objp) +{ + register int32_t *buf; + + int i; + if (!xdr_opaque (xdrs, objp->data, NFS_COOKIESIZE)) + return FALSE; + return TRUE; +} + +bool_t +xdr_readdirargs (XDR *xdrs, readdirargs *objp) +{ + register int32_t *buf; + + if (!xdr_nfs_fh (xdrs, &objp->dir)) + return FALSE; + if (!xdr_nfscookie (xdrs, &objp->cookie)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->count)) + return FALSE; + return TRUE; +} + +bool_t +xdr_entry (XDR *xdrs, entry *objp) +{ + register int32_t *buf; + + if (!xdr_u_int (xdrs, &objp->fileid)) + return FALSE; + if (!xdr_filename (xdrs, &objp->name)) + return FALSE; + if (!xdr_nfscookie (xdrs, &objp->cookie)) + return FALSE; + if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entry), (xdrproc_t) xdr_entry)) + return FALSE; + return TRUE; +} + +bool_t +xdr_dirlist (XDR *xdrs, dirlist *objp) +{ + register int32_t *buf; + + if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entry), (xdrproc_t) xdr_entry)) + return FALSE; + if (!xdr_bool (xdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +bool_t +xdr_readdirres (XDR *xdrs, readdirres *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_dirlist (xdrs, &objp->readdirres_u.reply)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +bool_t +xdr_statfsokres (XDR *xdrs, statfsokres *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->tsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bfree)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bavail)) + return FALSE; + } else { + IXDR_PUT_U_LONG(buf, objp->tsize); + IXDR_PUT_U_LONG(buf, objp->bsize); + IXDR_PUT_U_LONG(buf, objp->blocks); + IXDR_PUT_U_LONG(buf, objp->bfree); + IXDR_PUT_U_LONG(buf, objp->bavail); + } + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int (xdrs, &objp->tsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bfree)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bavail)) + return FALSE; + } else { + objp->tsize = IXDR_GET_U_LONG(buf); + objp->bsize = IXDR_GET_U_LONG(buf); + objp->blocks = IXDR_GET_U_LONG(buf); + objp->bfree = IXDR_GET_U_LONG(buf); + objp->bavail = IXDR_GET_U_LONG(buf); + } + return TRUE; + } + + if (!xdr_u_int (xdrs, &objp->tsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bsize)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bfree)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->bavail)) + return FALSE; + return TRUE; +} + +bool_t +xdr_statfsres (XDR *xdrs, statfsres *objp) +{ + register int32_t *buf; + + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_statfsokres (xdrs, &objp->statfsres_u.reply)) + return FALSE; + break; + default: + break; + } + return TRUE; +} diff --git a/rtemsNfs/rtems-filesystem-patch b/rtemsNfs/rtems-filesystem-patch new file mode 100644 index 0000000..c2d7861 --- /dev/null +++ b/rtemsNfs/rtems-filesystem-patch @@ -0,0 +1,860 @@ +# Diffed against OAR_orig (ss-20020301) on Sun Nov 3 00:24:13 PST 2002 +# T.S. + +For more information about this patch consult README (CAVEATS section). + +To apply this patch, + +chdir to c/src/lib/libc + +and issue + + patch -p0 < this_file + +It is always a good idea to try a "dry-run" before applying a patch: + + patch --dry-run -p0 < this_file + +Index: Makefile.am +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/Makefile.am,v +retrieving revision 1.1.1.2 +retrieving revision 1.2 +diff -c -r1.1.1.2 -r1.2 +*** Makefile.am 7 Mar 2002 01:53:46 -0000 1.1.1.2 +--- Makefile.am 28 Mar 2002 20:59:16 -0000 1.2 +*************** +*** 1,5 **** + ## +! ## $Id$ + ## + + AUTOMAKE_OPTIONS = foreign 1.4 +--- 1,5 ---- + ## +! ## $Id$ + ## + + AUTOMAKE_OPTIONS = foreign 1.4 +*************** +*** 32,37 **** +--- 32,39 ---- + + MALLOC_C_FILES = malloc.c mallocfreespace.c __brk.c __sbrk.c + ++ ENVIRON_C_FILES = envlock.c ++ + PASSWORD_GROUP_C_FILES = getpwent.c getgrent.c + + TERMINAL_IDENTIFICATION_C_FILES = ctermid.c isatty.c ttyname.c ttyname_r.c +*************** +*** 42,48 **** + UNIX_LIBC_C_FILES = unixlibc.c hosterr.c + + COMMON_C_FILES = gxx_wrappers.c printk.c $(BASE_FS_C_FILES) \ +! $(MALLOC_C_FILES) $(TERMIOS_C_FILES) $(ERROR_C_FILES) \ + $(ASSOCIATION_C_FILES) + + UNIX_C_FILES = $(UNIX_LIBC_C_FILES) +--- 44,50 ---- + UNIX_LIBC_C_FILES = unixlibc.c hosterr.c + + COMMON_C_FILES = gxx_wrappers.c printk.c $(BASE_FS_C_FILES) \ +! $(MALLOC_C_FILES) $(ENVIRON_C_FILES) $(TERMIOS_C_FILES) $(ERROR_C_FILES) \ + $(ASSOCIATION_C_FILES) + + UNIX_C_FILES = $(UNIX_LIBC_C_FILES) +Index: base_fs.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/base_fs.c,v +retrieving revision 1.1.1.1 +diff -c -r1.1.1.1 base_fs.c +*** base_fs.c 14 Dec 2001 22:52:31 -0000 1.1.1.1 +--- base_fs.c 26 Oct 2002 02:45:15 -0000 +*************** +*** 49,54 **** +--- 49,55 ---- + int status; + rtems_filesystem_mount_table_entry_t *entry; + rtems_filesystem_mount_table_t *mt; ++ rtems_filesystem_location_info_t loc; + + /* + * Set the default umask to "022". +*************** +*** 75,82 **** + rtems_fatal_error_occurred( 0xABCD0002 ); + + rtems_filesystem_link_counts = 0; + rtems_filesystem_root = entry->mt_fs_root; +! rtems_filesystem_current = rtems_filesystem_root; + + + /* +--- 76,113 ---- + rtems_fatal_error_occurred( 0xABCD0002 ); + + rtems_filesystem_link_counts = 0; ++ ++ /* setup the 'current' and 'root' directories ++ * ++ * NOTE: cloning the pathlocs is not strictly ++ * necessary. Since we implicitely let ++ * all threads that don't call ++ * libio_set_private_env() share the same ++ * (initial) 'root' and 'current' locs, ++ * we (also implicitely) assume that the ++ * root filesystem doesn't care about ++ * reference counts. ++ * I just inserted the code snippet below ++ * to remind everybody of the fact by ++ * making it more explicit... ++ * Ideally, every thread would have to ++ * call either share_private_env() or ++ * set_private_env() - but then: that's ++ * gonna hit performance. ++ * ++ * Till Straumann, 10/25/2002 ++ */ + rtems_filesystem_root = entry->mt_fs_root; +! /* Clone the root pathloc */ +! rtems_filesystem_evaluate_path("/", 0, &loc, 0); +! rtems_filesystem_root = loc; +! /* One more clone for the current node */ +! rtems_filesystem_evaluate_path("/", 0, &loc, 0); +! rtems_filesystem_current = loc; +! +! /* Note: the global_env's refcnt doesn't matter +! * as the global env is never released +! */ + + + /* +Index: chroot.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/chroot.c,v +retrieving revision 1.1.1.2 +diff -c -r1.1.1.2 chroot.c +*** chroot.c 7 Mar 2002 01:53:47 -0000 1.1.1.2 +--- chroot.c 29 Oct 2002 03:01:47 -0000 +*************** +*** 38,51 **** + rtems_set_errno_and_return_minus_one( ENOTSUP ); + }; + +- loc = rtems_filesystem_root; /* save the value */ +- + result = chdir(pathname); + if (result) { +- rtems_filesystem_root = loc; /* restore the value */ + rtems_set_errno_and_return_minus_one( errno ); + }; +! rtems_filesystem_root = rtems_filesystem_current; + + return 0; + } +--- 38,53 ---- + rtems_set_errno_and_return_minus_one( ENOTSUP ); + }; + + result = chdir(pathname); + if (result) { + rtems_set_errno_and_return_minus_one( errno ); + }; +! /* clone the new root location */ +! if (rtems_filesystem_evaluate_path(".", 0, &loc, 0)) { +! rtems_set_errno_and_return_minus_one( errno ); +! } +! rtems_filesystem_freenode(&rtems_filesystem_root); +! rtems_filesystem_root = loc; + + return 0; + } +Index: eval.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/eval.c,v +retrieving revision 1.1.1.2 +retrieving revision 1.2 +diff -c -r1.1.1.2 -r1.2 +*** eval.c 7 Mar 2002 01:53:48 -0000 1.1.1.2 +--- eval.c 29 Oct 2002 21:03:50 -0000 1.2 +*************** +*** 10,16 **** + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +--- 10,16 ---- + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +*************** +*** 60,76 **** + + if ( (result == 0) && follow_link ) { + +! if ( !pathloc->ops->node_type_h ) + rtems_set_errno_and_return_minus_one( ENOTSUP ); + + type = (*pathloc->ops->node_type_h)( pathloc ); + + if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) || + ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) { + +! if ( !pathloc->ops->eval_link_h ) + rtems_set_errno_and_return_minus_one( ENOTSUP ); + + result = (*pathloc->ops->eval_link_h)( pathloc, flags ); + + } +--- 60,93 ---- + + if ( (result == 0) && follow_link ) { + +! if ( !pathloc->ops->node_type_h ) { +! rtems_filesystem_freenode(pathloc); + rtems_set_errno_and_return_minus_one( ENOTSUP ); ++ } + + type = (*pathloc->ops->node_type_h)( pathloc ); + + if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) || + ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) { + +! if ( !pathloc->ops->eval_link_h ) { +! rtems_filesystem_freenode(pathloc); + rtems_set_errno_and_return_minus_one( ENOTSUP ); ++ } + ++ /* what to do with the valid node pathloc points to ++ * if eval_link_h() fails? ++ * Let the FS implementation deal with this case. It ++ * should probably free pathloc in either case: ++ * - if the link evaluation fails, it must free the ++ * original (valid) pathloc because we are going ++ * to return -1 and hence the FS generics won't ++ * cleanup pathloc ++ * - if the link evaluation is successful, the updated ++ * pathloc will be passed up (and eventually released). ++ * Hence, the (valid) original node that we submit to ++ * eval_link_h() should be released by the handler. ++ */ + result = (*pathloc->ops->eval_link_h)( pathloc, flags ); + + } +Index: fchdir.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/fchdir.c,v +retrieving revision 1.1.1.2 +diff -c -r1.1.1.2 fchdir.c +*** fchdir.c 7 Mar 2002 01:53:48 -0000 1.1.1.2 +--- fchdir.c 25 Oct 2002 23:59:03 -0000 +*************** +*** 29,34 **** +--- 29,35 ---- + ) + { + rtems_libio_t *iop; ++ rtems_filesystem_location_info_t loc; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); +*************** +*** 65,74 **** + * this node which we are making here. I can + * see the freenode interface but do not see + * allocnode node interface. It maybe node_type. + */ + + rtems_filesystem_current = iop->pathinfo; + + return 0; + } +- +--- 66,80 ---- + * this node which we are making here. I can + * see the freenode interface but do not see + * allocnode node interface. It maybe node_type. ++ * ++ * FIXEC: T.Straumann: it is evaluate_path() + */ + + rtems_filesystem_current = iop->pathinfo; + ++ /* clone the current node */ ++ rtems_filesystem_evaluate_path(".", 0, &loc, 0); ++ rtems_filesystem_current = loc; ++ + return 0; + } +Index: getgrent.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/getgrent.c,v +retrieving revision 1.1.1.1 +diff -c -r1.1.1.1 getgrent.c +*** getgrent.c 14 Dec 2001 22:52:31 -0000 1.1.1.1 +--- getgrent.c 27 Oct 2002 18:24:20 -0000 +*************** +*** 50,63 **** +--- 50,69 ---- + ) + { + FILE *fp; ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if ((fp = fopen ("/etc/group", "r")) == NULL) { + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 72,84 **** +--- 78,94 ---- + if (!strcmp (groupname, name)) { + fclose (fp); + *result = grp; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return 0; + } + } + fclose (fp); + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 104,118 **** +--- 114,134 ---- + ) + { + FILE *fp; ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + + + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if ((fp = fopen ("/etc/group", "r")) == NULL) { + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 128,140 **** +--- 144,160 ---- + if (gid == gr_group.gr_gid) { + fclose (fp); + *result = grp; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return 0; + } + } + fclose (fp); + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 174,188 **** +--- 194,214 ---- + void + setgrent () + { ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if (group_fp != NULL) + fclose (group_fp); + + group_fp = fopen ("/etc/group", "r"); ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + } + + void +Index: getpwent.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/getpwent.c,v +retrieving revision 1.1.1.1 +diff -c -r1.1.1.1 getpwent.c +*** getpwent.c 14 Dec 2001 22:52:31 -0000 1.1.1.1 +--- getpwent.c 27 Oct 2002 18:18:52 -0000 +*************** +*** 97,110 **** +--- 97,116 ---- + ) + { + FILE *fp; ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if ((fp = fopen ("/etc/passwd", "r")) == NULL) { + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 123,135 **** +--- 129,145 ---- + if (!strcmp (logname, name)) { + fclose (fp); + *result = pwd; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return 0; + } + } + fclose (fp); + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 155,168 **** +--- 165,184 ---- + ) + { + FILE *fp; ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if ((fp = fopen ("/etc/passwd", "r")) == NULL) { + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 181,193 **** +--- 197,213 ---- + if (uid == pwd->pw_uid) { + fclose (fp); + *result = pwd; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return 0; + } + } + fclose (fp); + errno = EINVAL; ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + return -1; + } + +*************** +*** 230,244 **** +--- 250,270 ---- + + void setpwent( void ) + { ++ #if 0 + rtems_user_env_t * aux=rtems_current_user_env; /* save */ ++ #endif + init_etc_passwd_group(); ++ #if 0 + rtems_current_user_env=&rtems_global_user_env; /* set root */ ++ #endif + + if (passwd_fp != NULL) + fclose (passwd_fp); + + passwd_fp = fopen ("/etc/passwd", "r"); ++ #if 0 + rtems_current_user_env=aux; /* restore */ ++ #endif + } + + void endpwent( void ) +Index: mknod.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/mknod.c,v +retrieving revision 1.1.1.2 +retrieving revision 1.2 +diff -c -r1.1.1.2 -r1.2 +*** mknod.c 7 Mar 2002 01:53:51 -0000 1.1.1.2 +--- mknod.c 29 Oct 2002 21:03:50 -0000 1.2 +*************** +*** 12,18 **** + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +--- 12,18 ---- + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +*************** +*** 49,55 **** + rtems_filesystem_get_start_loc( pathname, &i, &temp_loc ); + + if ( !temp_loc.ops->evalformake_h ) { +- rtems_filesystem_freenode( &temp_loc ); + rtems_set_errno_and_return_minus_one( ENOTSUP ); + } + +--- 49,54 ---- +Index: mount.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/mount.c,v +retrieving revision 1.1.1.1 +diff -c -r1.1.1.1 mount.c +*** mount.c 14 Dec 2001 22:52:33 -0000 1.1.1.1 +--- mount.c 30 Oct 2002 06:39:09 -0000 +*************** +*** 14,20 **** + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +--- 14,20 ---- + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + */ + + #if HAVE_CONFIG_H +*************** +*** 101,106 **** +--- 101,113 ---- + return -1; + } + ++ /* Do they support being mounted at all ? */ ++ if ( !fs_ops->fsmount_me_h ) { ++ errno = ENOTSUP; ++ goto cleanup_and_bail; ++ } ++ ++ + /* + * Allocate a mount table entry + */ +*************** +*** 140,145 **** +--- 147,158 ---- + */ + + loc_to_free = &loc; ++ ++ if ( !loc.ops->node_type_h ) { ++ errno = ENOTSUP; ++ goto cleanup_and_bail; ++ } ++ + if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) { + errno = ENOTDIR; + goto cleanup_and_bail; +*************** +*** 198,210 **** + temp_mt_entry->mt_point_node.mt_entry = NULL; + } + +! if ( !fs_ops->fsmount_me_h ) { +! errno = ENOTSUP; + goto cleanup_and_bail; + } +- +- if ( fs_ops->fsmount_me_h( temp_mt_entry ) ) +- goto cleanup_and_bail; + + /* + * Add the mount table entry to the mount table chain +--- 211,223 ---- + temp_mt_entry->mt_point_node.mt_entry = NULL; + } + +! if ( fs_ops->fsmount_me_h( temp_mt_entry ) ) { +! /* try to undo the mount operation */ +! if ( loc.ops->unmount_h ) { +! loc.ops->unmount_h( temp_mt_entry ); +! } + goto cleanup_and_bail; + } + + /* + * Add the mount table entry to the mount table chain +Index: newlibc.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/newlibc.c,v +retrieving revision 1.1.1.1 +retrieving revision 1.3 +diff -c -r1.1.1.1 -r1.3 +*** newlibc.c 14 Dec 2001 22:52:33 -0000 1.1.1.1 +--- newlibc.c 16 Apr 2002 19:41:03 -0000 1.3 +*************** +*** 9,15 **** + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + * + */ + +--- 9,15 ---- + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * +! * $Id$ + * + */ + +Index: privateenv.c +=================================================================== +RCS file: /afs/slac/g/spear/cvsrep/rtems/src/c/src/lib/libc/privateenv.c,v +retrieving revision 1.1.1.2 +diff -c -r1.1.1.2 privateenv.c +*** privateenv.c 7 Mar 2002 01:53:51 -0000 1.1.1.2 +--- privateenv.c 27 Oct 2002 18:35:34 -0000 +*************** +*** 23,47 **** + #include + #include + + rtems_status_code rtems_libio_set_private_env(void) { +! rtems_status_code sc; +! rtems_id task_id; + + sc=rtems_task_ident(RTEMS_SELF,0,&task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* Only for the first time a malloc is necesary */ +! if (rtems_current_user_env==&rtems_global_user_env) { +! sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free); +! if (sc != RTEMS_SUCCESSFUL) return sc; +! rtems_current_user_env = malloc(sizeof(rtems_user_env_t)); +! if (!rtems_current_user_env) + return RTEMS_NO_MEMORY; + }; + +- /* the side effect desired . chroot("/") */ + *rtems_current_user_env = rtems_global_user_env; /* get the global values*/ + rtems_current_user_env->task_id=task_id; /* mark the local values*/ + + return RTEMS_SUCCESSFUL; + } +--- 23,92 ---- + #include + #include + ++ extern Chain_Control rtems_filesystem_mount_table_control; ++ ++ #define THE_ROOT_FS_LOC \ ++ (((rtems_filesystem_mount_table_entry_t*)\ ++ rtems_filesystem_mount_table_control.first)->mt_fs_root) ++ ++ /* cleanup a user environment ++ * NOTE: this must be called with ++ * thread dispatching disabled! ++ */ ++ static void ++ free_user_env(rtems_user_env_t *env) ++ { ++ if (env != &rtems_global_user_env ++ && --env->refcnt <= 0) { ++ rtems_filesystem_freenode( &env->current_directory); ++ rtems_filesystem_freenode( &env->root_directory); ++ free(env); ++ } ++ } ++ + rtems_status_code rtems_libio_set_private_env(void) { +! rtems_status_code sc; +! rtems_id task_id; +! rtems_filesystem_location_info_t loc; + + sc=rtems_task_ident(RTEMS_SELF,0,&task_id); + if (sc != RTEMS_SUCCESSFUL) return sc; + + /* Only for the first time a malloc is necesary */ +! if (rtems_current_user_env==&rtems_global_user_env) { +! rtems_user_env_t *tmp = malloc(sizeof(rtems_user_env_t)); +! if (!tmp) + return RTEMS_NO_MEMORY; ++ ++ tmp->refcnt = 1; ++ ++ sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env); ++ if (sc != RTEMS_SUCCESSFUL) { ++ /* don't use free_user_env because the pathlocs are ++ * not initialized yet ++ */ ++ free(tmp); ++ return sc; ++ } ++ rtems_current_user_env = tmp; + }; + + *rtems_current_user_env = rtems_global_user_env; /* get the global values*/ + rtems_current_user_env->task_id=task_id; /* mark the local values*/ ++ ++ /* get a clean root */ ++ rtems_filesystem_root = THE_ROOT_FS_LOC; ++ ++ /* Clone the pathlocs. In contrast to most other ++ * code we must _not_ free the original locs because ++ * what we are trying to do here is forking off ++ * clones. ++ */ ++ ++ rtems_filesystem_evaluate_path("/", 0, &loc, 0); ++ rtems_filesystem_root = loc; ++ rtems_filesystem_evaluate_path("/", 0, &loc, 0); ++ rtems_filesystem_current = loc; + + return RTEMS_SUCCESSFUL; + } +*************** +*** 51,56 **** +--- 96,115 ---- + * Task_id (remote) and RTEMS_SELF(current). + */ + ++ /* NOTE: ++ * ++ * THIS CODE HAS NO PROTECTION IMPLEMENTED ++ * ++ * Tasks who wish to share their environments must ++ * ++ * a) assert that no participants are concurrently ++ * executing ++ * libio_share_private_env() and/or libio_set_private_env() ++ * ++ * b) mutex access to rtems_filesystem_current, rtems_filesytem_root ++ * while changing any of those (chdir(), chroot()). ++ */ ++ + rtems_status_code rtems_libio_share_private_env(rtems_id task_id) { + rtems_status_code sc; + rtems_user_env_t * shared_user_env; +*************** +*** 61,81 **** + + if (rtems_current_user_env->task_id==current_task_id) { + /* kill the current user env & task_var*/ +! free(rtems_current_user_env); + sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); + if (sc != RTEMS_SUCCESSFUL) return sc; + }; + + sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, + (void*)&shared_user_env ); +! if (sc != RTEMS_SUCCESSFUL) return sc; + +! /* don't free(NULL'ed) at the task_delete. It is a shared var... */ +! sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,NULL); +! if (sc != RTEMS_SUCCESSFUL) return sc; + + /* the current_user_env is the same pointer that remote env */ + rtems_current_user_env = shared_user_env; + + return RTEMS_SUCCESSFUL; + } +--- 120,152 ---- + + if (rtems_current_user_env->task_id==current_task_id) { + /* kill the current user env & task_var*/ +! rtems_user_env_t *tmp = rtems_current_user_env; + sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); + if (sc != RTEMS_SUCCESSFUL) return sc; ++ free_user_env(tmp); + }; + ++ /* AT THIS POINT, rtems_current_user_env is DANGLING */ ++ + sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, + (void*)&shared_user_env ); +! if (sc != RTEMS_SUCCESSFUL) +! goto bailout; + +! sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env); +! if (sc != RTEMS_SUCCESSFUL) +! goto bailout; + + /* the current_user_env is the same pointer that remote env */ + rtems_current_user_env = shared_user_env; + ++ /* increase the reference count */ ++ rtems_current_user_env->refcnt++; ++ + return RTEMS_SUCCESSFUL; ++ ++ bailout: ++ /* fallback to the global env */ ++ rtems_current_user_env = &rtems_global_user_env; ++ return sc; + } diff --git a/rtemsNfs/src/Makefile b/rtemsNfs/src/Makefile new file mode 100644 index 0000000..431b5ad --- /dev/null +++ b/rtemsNfs/src/Makefile @@ -0,0 +1,104 @@ +# +# $Id$ +# +# Templates/Makefile.leaf +# Template leaf node Makefile +# + +# if you have CEXP set this variable to 'YES' +# and some "help" info will be compiled in. +HAVE_CEXP=YES + +# C source names, if any, go here -- minus the .c +C_PIECES_YES=rpcio nfs sock_mbuf xdr_mbuf dirutils rpcio.modini nfs.modini cexphelp +C_PIECES_NO=rpcio nfs sock_mbuf xdr_mbuf + +C_PIECES=$(C_PIECES_$(HAVE_CEXP)) + +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +# C++ source names, if any, go here -- minus the .cc +CC_PIECES= +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +H_FILES=librtemsNfs.h rpcio.h +INST_HEADERS=librtemsNfs.h + +# Assembly source names, if any, go here -- minus the .S +S_PIECES= +S_FILES=$(S_PIECES:%=%.S) +S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o) + +SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES) $(wildcard ../proto/$(ARCH)/*.o) + +PGMS=${ARCH}/nfs.obj ${ARCH}/rpcio.obj ${ARCH}/dirutils.obj + +LIBNAME=librtemsNfs.a + +LIB=$(ARCH)/$(LIBNAME) + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(RTEMS_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFS_CEXP_YES=-DHAVE_CEXP + +DEFINES += $(DEFS_CEXP_$(HAVE_CEXP)) + +CPPFLAGS += -I. -I../proto + +CFLAGS += + +# +# CFLAGS_DEBUG_V are used when the `make debug' target is built. +# To link your application with the non-optimized RTEMS routines, +# uncomment the following line: +# CFLAGS_DEBUG_V += -qrtems_debug +# + +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +#CLEAN_ADDITIONS += xxx-your-debris-goes-here +CLOBBER_ADDITIONS += + +ifndef RTEMS_SITE_INSTALLDIR +RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE) +endif + +%nfs.obj: %nfs.o %nfs.modini.o + $(LD) -r -o $@ $^ -L../proto/$(ARCH) -lnfsprot + +%rpcio.obj: %rpcio.o %sock_mbuf.o %xdr_mbuf.o %rpcio.modini.o + $(LD) -r -o $@ $^ + +%dirutils.obj: %dirutils.o + $(LD) -r -o $@ $^ + +$(LIB): $(OBJS) + $(make-library) + +all: ${ARCH} $(SRCS) $(PGMS) $(LIB) + +tar: + echo not implemented + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL_CHANGE) +install: all + $(INSTALL_VARIANT) -m 555 ${PGMS} ${RTEMS_SITE_INSTALLDIR}/bin + $(INSTALL_VARIANT) -m 555 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib + $(INSTALL_CHANGE) -m 444 ${INST_HEADERS} ${RTEMS_SITE_INSTALLDIR}/include diff --git a/rtemsNfs/src/cexphelp.c b/rtemsNfs/src/cexphelp.c new file mode 100644 index 0000000..d062ed1 --- /dev/null +++ b/rtemsNfs/src/cexphelp.c @@ -0,0 +1,16 @@ +#include +#include +CEXP_HELP_TAB_BEGIN(rtemsNfs) + HELP( +"Mount a remote filesystem (NFS). The mount point (must not be a NFS dir)\n" +"is created on the fly if not existing already.\n" +"uid/gid to use may be specified:\n" +" hostspec: [uid.gid@]hostname_or_ipaddr\n" + , int, nfsMount, (char *hostspec, char *exportdir, char *mntpoint) + ), + HELP( +"Print all currently mounted NFS directories to open file handle.\n" +"Pass f = 0 to print to stdout\n" + , int, nfsMountsShow, (FILE *f) + ), +CEXP_HELP_TAB_END diff --git a/rtemsNfs/src/dirutils.c b/rtemsNfs/src/dirutils.c new file mode 100644 index 0000000..91b1858 --- /dev/null +++ b/rtemsNfs/src/dirutils.c @@ -0,0 +1,323 @@ +/* $Id$ */ + +/* very crude and basic fs utilities for testing the NFS */ + +/* Till Straumann, , 10/2002 */ + +/* + * Copyright 2002, Stanford University and + * Till Straumann + * + * Stanford Notice + * *************** + * + * Acknowledgement of sponsorship + * * * * * * * * * * * * * * * * * + * This software was produced by the Stanford Linear Accelerator Center, + * Stanford University, under Contract DE-AC03-76SFO0515 with the Department + * of Energy. + * + * Government disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, + * or assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately + * owned rights. + * + * Stanford disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * This product is subject to the EPICS open license + * - - - - - - - - - - - - - - - - - - - - - - - - - + * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php + * for more information. + * + * Maintenance of notice + * - - - - - - - - - - - + * In the interest of clarity regarding the origin and status of this + * software, Stanford University requests that any recipient of it maintain + * this notice affixed to any distribution by the recipient that contains a + * copy or derivative of this software. + */ + +#ifdef __vxworks +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CEXP +#include +#endif + +#define BUFFERSZ 10000 + +#ifndef __vxworks +int +pwd(void) +{ +char buf[MAXPATHLEN]; + + if ( !getcwd(buf,MAXPATHLEN)) { + perror("getcwd"); + return -1; + } else { + printf("%s\n",buf); + } + return 0; +} + +static int +ls_r(char *path, char *chpt, char *name, struct stat *buf) +{ +char *t; + sprintf(chpt, "/%s", name); + if (lstat(path,buf)) { + fprintf(stderr,"stat(%s): %s\n", path, strerror(errno)); + return -1; + } + switch ( buf->st_mode & S_IFMT ) { + case S_IFSOCK: + case S_IFIFO: t = "|"; break; + + default: + case S_IFREG: + case S_IFBLK: + case S_IFCHR: + t = ""; break; + case S_IFDIR: + t = "/"; break; + case S_IFLNK: + t = "@"; break; + } + + printf("%10li, %10lib, %5i.%-5i 0%04o %s%s\n", + buf->st_ino, + buf->st_size, + buf->st_uid, + buf->st_gid, + buf->st_mode & ~S_IFMT, + name, + t); + *chpt = 0; + return 0; +} + +int +ls(char *dir, char *opts) +{ +struct dirent *de; +char path[MAXPATHLEN+1]; +char *chpt; +DIR *dp = 0; +int rval = -1; +struct stat buf; + + if ( !dir ) + dir = "."; + + strncpy(path, dir, MAXPATHLEN); + path[MAXPATHLEN] = 0; + chpt = path+strlen(path); + + if ( !(dp=opendir(dir)) ) { + perror("opendir"); + goto cleanup; + } + + while ( (de = readdir(dp)) ) { + ls_r(path, chpt, de->d_name, &buf); + } + + rval = 0; + +cleanup: + if (dp) + closedir(dp); + return rval; +} +#endif + +#if 0 + fprintf(stderr, "usage: cp(""from"",[""to""[,""-f""]]\n"); + fprintf(stderr, " ""to""==NULL -> stdout\n"); + fprintf(stderr, " ""-f"" -> overwrite existing file\n"); +#endif + +int +cp(char *from, char *to, char *opts) +{ +struct stat st; +int got,put,tot; +char *buf = 0; +int rval = -1; +int ffd = -1; +int tfd = -1; +int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL; + + if (from) { + + if ((ffd=open(from,O_RDONLY,0)) < 0) { + fprintf(stderr, + "Opening %s for reading: %s\n", + from, + strerror(errno)); + goto cleanup; + } + + if (fstat(ffd, &st)) { + fprintf(stderr, + "rstat(%s): %s\n", + from, + strerror(errno)); + goto cleanup; + } + + + if (!S_ISREG(st.st_mode)) { + fprintf(stderr,"Refuse to copy a non-regular file\n"); + errno = EINVAL; + goto cleanup; + } + + } else { + ffd = fileno(stdin); + st.st_mode = 0644; + } + + if (opts && strchr(opts,'f')) + flags &= ~ O_EXCL; + + if (to) { + if ((tfd=open(to,flags,st.st_mode)) < 0) { + fprintf(stderr, + "Opening %s for writing: %s\n", + to, + strerror(errno)); + goto cleanup; + } + } else { + tfd = fileno(stdout); + } + + if ( !(buf = malloc(BUFFERSZ)) ) { + fprintf(stderr,"cp: unable to allocate buffer - out of memory\n"); + errno = ENOMEM; + goto cleanup; + } + + tot = 0; + while ( (got=read(ffd,buf,BUFFERSZ)) > 0 ) { + if (got !=(put=write(tfd,buf,got))) { + if (put<0) { + fprintf(stderr,"Write error: %s\n",strerror(errno)); + } else { + fprintf(stderr,"Write error: unable to write whole block\n"); + } + goto cleanup; + } + tot += got; + } + if (got < 0) { + fprintf(stderr,"Read error: %s\n",strerror(errno)); + goto cleanup; + } + rval = 0; + +cleanup: + free(buf); + + if (from && ffd>=0) + close(ffd); + if (to && tfd>=0) + close(tfd); + + return rval; +} + +int +ln(char *to, char *name, char *opts) +{ + if (!to) { + fprintf(stderr,"ln: need 'to' argument\n"); + return -1; + } + if (!name) { + if ( !(name = strrchr(to,'/')) ) { + fprintf(stderr, + "ln: 'unable to link %s to %s\n", + to,to); + return -1; + } + name++; + } + if (opts || strchr(opts,'s')) { + if (symlink(name,to)) { + fprintf(stderr,"symlink: %s\n",strerror(errno)); + return -1; + } + } else { + if (link(name,to)) { + fprintf(stderr,"hardlink: %s\n",strerror(errno)); + return -1; + } + } + return 0; +} + +int +rm(char *path) +{ + return unlink(path); +} + +int +cd(char *path) +{ + return chdir(path); +} + +#ifdef HAVE_CEXP +static CexpHelpTabRec _cexpHelpTabDirutils[]={ + HELP( +"copy a file: cp(""from"",[""to""[,""-f""]])\n\ + from = NULL <-- stdin\n\ + to = NULL --> stdout\n\ + option -f: overwrite existing file\n", + int, + cp, (char *from, char *to, char *options) + ), + HELP( +"list a directory: ls([""dir""])\n", + int, + ls, (char *dir) + ), + HELP( +"remove a file\n", + int, + rm, (char *path) + ), + HELP( +"change the working directory\n", + int, + cd, (char *path) + ), + HELP( +"create a link: ln(""to"",""name"",""[-s]""\n\ + -s creates a symlink\n", + int, + ln, (char *to, char *name, char *options) + ), + HELP("",,0,) +}; +#endif diff --git a/rtemsNfs/src/librtemsNfs.h b/rtemsNfs/src/librtemsNfs.h new file mode 100644 index 0000000..880842c --- /dev/null +++ b/rtemsNfs/src/librtemsNfs.h @@ -0,0 +1,158 @@ +#ifndef LIB_RTEMS_NFS_CLIENT_H +#define LIB_RTEMS_NFS_CLIENT_H +/* $Id$ */ + +/* public interface to the NFS client library for RTEMS */ + +/* Author: Till Straumann 2002-2003 */ + +/* + * Copyright 2002-2003, Stanford University and + * Till Straumann + * + * Stanford Notice + * *************** + * + * Acknowledgement of sponsorship + * * * * * * * * * * * * * * * * * + * This software was produced by the Stanford Linear Accelerator Center, + * Stanford University, under Contract DE-AC03-76SFO0515 with the Department + * of Energy. + * + * Government disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, + * or assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately + * owned rights. + * + * Stanford disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * This product is subject to the EPICS open license + * - - - - - - - - - - - - - - - - - - - - - - - - - + * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php + * for more information. + * + * Maintenance of notice + * - - - - - - - - - - - + * In the interest of clarity regarding the origin and status of this + * software, Stanford University requests that any recipient of it maintain + * this notice affixed to any distribution by the recipient that contains a + * copy or derivative of this software. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef HAVE_CEXP_H +#include +#endif + +/* RPCIO driver interface. + * If you need RPCIO for other purposes than NFS + * you may want to include +#include "rpcio.h" + */ + +/* Initialize the driver + * + * RETURNS: 0 on success, -1 on failure + */ +int +rpcUdpInit(void); + +/* Cleanup/Stop + * + * RETURNS: 0 on success, nonzero if still in use + */ +int +rpcUdpCleanup(void); + +/* NFS driver interface */ + +/* Initialize the NFS driver. + * + * NOTE: The RPCIO driver must have been initialized prior to + * calling this. + * + * ARGS: depth of the small and big + * transaction pools, i.e. how + * many transactions (buffers) + * should always be kept around. + * + * (If more transactions are needed, + * they are created and destroyed + * on the fly). + * + * Supply zero values to have the + * driver chose reasonable defaults. + */ +int +nfsInit(int smallPoolDepth, int bigPoolDepth); + +/* Driver cleanup code + * + * RETURNS: 0 on success, nonzero if still in use + */ +int +nfsCleanup(void); + +/* Dump a list of the currently mounted NFS to a file + * (stdout is used in case f==NULL) + */ +int +nfsMountsShow(FILE *f); + +/* convenience wrapper + * + * NOTE: this routine calls NON-REENTRANT + * gethostbyname() if the host is + * not in 'dot' notation. + */ +int +nfsMount(char *uidhost, char *path, char *mntpoint); + +/* Alternatively, a pointer to the filesystem operations + * table can be supplied to the native RTEMS (NON-POSIX!) + * 'mount()' call. + * Supply a ":" string + * for 'device' argument to 'mount()'. + */ +extern struct _rtems_filesystem_operations_table nfs_fs_ops; + +/* A utility routine to find the path leading to a + * rtems_filesystem_location_info_t node. + * + * This should really be present in libcsupport... + * + * INPUT: 'loc' and a buffer 'buf' (length 'len') to hold the + * path. + * OUTPUT: path copied into 'buf' + * + * RETURNS: 0 on success, RTEMS error code on error. + */ +rtems_status_code +rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc); +#endif diff --git a/rtemsNfs/src/nfs.c b/rtemsNfs/src/nfs.c new file mode 100644 index 0000000..73f4354 --- /dev/null +++ b/rtemsNfs/src/nfs.c @@ -0,0 +1,3317 @@ +/* nfs.c,v 1.33 2004/09/22 22:10:41 till Exp */ + +/* NFS client implementation for RTEMS; hooks into the RTEMS filesystem */ + +/* Author: Till Straumann 2002 */ + +/* + * Copyright 2002, Stanford University and + * Till Straumann + * + * Stanford Notice + * *************** + * + * Acknowledgement of sponsorship + * * * * * * * * * * * * * * * * * + * This software was produced by the Stanford Linear Accelerator Center, + * Stanford University, under Contract DE-AC03-76SFO0515 with the Department + * of Energy. + * + * Government disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, + * or assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately + * owned rights. + * + * Stanford disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * This product is subject to the EPICS open license + * - - - - - - - - - - - - - - - - - - - - - - - - - + * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php + * for more information. + * + * Maintenance of notice + * - - - - - - - - - - - + * In the interest of clarity regarding the origin and status of this + * software, Stanford University requests that any recipient of it maintain + * this notice affixed to any distribution by the recipient that contains a + * copy or derivative of this software. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +#include "rpcio.h" + +#ifdef HAVE_CEXP_H +#include +#endif + + +/* Configurable parameters */ + +/* Estimated average length of a filename (including terminating 0). + * This was calculated by doing + * + * find -print -exec basename '{}' \; > feil + * wc feil + * + * AVG_NAMLEN = (num_chars + num_lines)/num_lines + */ +#define CONFIG_AVG_NAMLEN 10 + +#define CONFIG_NFS_SMALL_XACT_SIZE 800 /* size of RPC arguments for non-write ops */ +/* lifetime of NFS attributes in a NfsNode; + * the time is in seconds and the lifetime is + * infinite if the symbol is #undef + */ +#define CONFIG_ATTR_LIFETIME 10/*secs*/ + +/* dont change this without changing the maximal write size */ +#define CONFIG_NFS_BIG_XACT_SIZE UDPMSGSIZE /* dont change this */ + +/* The real values for these are specified further down */ +#define NFSCALL_TIMEOUT (&_nfscalltimeout) +#define MNTCALL_TIMEOUT (&_nfscalltimeout) +static struct timeval _nfscalltimeout = { 10, 0 }; /* {secs, us } */ + +/* More or less fixed constants; in particular, NFS3 is not supported */ +#define DELIM '/' +#define HOSTDELIM ':' +#define UPDIR ".." +#define UIDSEP '@' +#define NFS_VERSION_2 NFS_VERSION + +/* we use a dynamically assigned major number */ +#define NFS_MAJOR (nfsGlob.nfs_major) + + +/* NOTE: RTEMS (ss-20020301) uses a 'short st_ino' type :-( but the + * NFS fileid is 32 bit. + * As a workarount, we merge the upper 16bits of the fileid into the + * minor device no. Hence, it is still possible to uniquely identify + * a file by looking at its device number (major = nfs, minor = part + * of the fileid + our 'nfs-id' identifier). + * + * This has an impact on performance, as e.g. getcwd() stats() all + * directory entries when it believes it has crossed a mount point + * (a.st_dev != b.st_dev). + * + * OTOH, it also might cause node comparison failure! E.g. 'getcwd()' + * assumes that two nodes residing in the same directory must be located + * on the same device and hence compares 'st_ino' only. + * If two files in the same directory have the same inode number + * modulo 2^16, they will be considered equal (although their device + * number doesn't match - getcwd doesn't look at it). + * + * Other software might or might not be affected. + * + * The only clean solution to this problem is bumping up the size of + * 'ino_t' at least to 'long'. + * Note that this requires _all_ software (libraries etc.) to be + * recompiled. + */ + +#define NFS_MAKE_DEV_T_INO_HACK(node) \ + rtems_filesystem_make_dev_t( NFS_MAJOR, \ + (((node)->nfs->id)<<16) | (SERP_ATTR((node)).fileid >> 16) ) + +/* use our 'nfs id' and the server's fsid for the minor device number + * this should be fairly unique + */ +#define NFS_MAKE_DEV_T(node) \ + rtems_filesystem_make_dev_t( NFS_MAJOR, \ + (((node)->nfs->id)<<16) | (SERP_ATTR((node)).fsid & ((1<<16)-1)) ) + +#define DIRENT_HEADER_SIZE ( sizeof(struct dirent) - \ + sizeof( ((struct dirent *)0)->d_name ) ) + + +/* debugging flags */ +#define DEBUG_COUNT_NODES (1<<0) +#define DEBUG_TRACK_NODES (1<<1) +#define DEBUG_EVALPATH (1<<2) +#define DEBUG_READDIR (1<<3) +#define DEBUG_SYSCALLS (1<<4) + +/* #define DEBUG ( DEBUG_SYSCALLS | DEBUG_COUNT_NODES ) */ + +#ifdef DEBUG +#define STATIC +#else +#define STATIC static +#endif + +#define MUTEX_ATTRIBUTES (RTEMS_LOCAL | \ + RTEMS_PRIORITY | \ + RTEMS_INHERIT_PRIORITY | \ + RTEMS_BINARY_SEMAPHORE) + +#define LOCK(s) do { rtems_semaphore_obtain((s), \ + RTEMS_WAIT, \ + RTEMS_NO_TIMEOUT); \ + } while (0) + +#define UNLOCK(s) do { rtems_semaphore_release((s)); \ + } while (0) + +/***************************************** + Types with Associated XDR Routines + *****************************************/ + +/* a string buffer with a maximal length. + * If the buffer pointer is NULL, it is updated + * with an appropriately allocated area. + */ +typedef struct strbuf { + char *buf; + u_int max; +} strbuf; + +static bool_t +xdr_strbuf(XDR *xdrs, strbuf *obj) +{ + return xdr_string(xdrs, &obj->buf, obj->max); +} + +/* Read 'readlink' results into a 'strbuf'. + * This is convenient as it avoids + * one extra step of copying / lenght + * checking. + */ +typedef struct readlinkres_strbuf { + nfsstat status; + strbuf strbuf; +} readlinkres_strbuf; + +static bool_t +xdr_readlinkres_strbuf(XDR *xdrs, readlinkres_strbuf *objp) +{ + if ( !xdr_nfsstat(xdrs, &objp->status) ) + return FALSE; + + if ( NFS_OK == objp->status ) { + if ( !xdr_string(xdrs, &objp->strbuf.buf, objp->strbuf.max) ) + return FALSE; + } + return TRUE; +} + + +/* DirInfoRec is used instead of dirresargs + * to convert recursion into iteration. The + * 'rpcgen'erated xdr_dirresargs ends up + * doing nested calls when unpacking the + * 'next' pointers. + */ + +typedef struct DirInfoRec_ { + readdirargs readdirargs; + /* clone of the 'readdirres' fields; + * the cookie is put into the readdirargs above + */ + nfsstat status; + char *buf, *ptr; + int len; + bool_t eofreached; +} DirInfoRec, *DirInfo; + +/* this deals with one entry / record */ +static bool_t +xdr_dir_info_entry(XDR *xdrs, DirInfo di) +{ +union { + char nambuf[NFS_MAXNAMLEN+1]; + nfscookie cookie; +} dummy; +struct dirent *pde = (struct dirent *)di->ptr; +u_int fileid; +char *name; +register int nlen = 0,len,naligned = 0; +nfscookie *pcookie; + + len = di->len; + + if ( !xdr_u_int(xdrs, &fileid) ) + return FALSE; + + /* we must pass the address of a char* */ + name = (len > NFS_MAXNAMLEN) ? pde->d_name : dummy.nambuf; + + if ( !xdr_filename(xdrs, &name) ) { + return FALSE; + } + + if (len >= 0) { + nlen = strlen(name); + naligned = nlen + 1 /* string delimiter */ + 3 /* alignment */; + naligned &= ~3; + len -= naligned; + } + + /* if the cookie goes into the DirInfo, we hope this doesn't fail + * - the caller ends up with an invalid readdirargs cookie otherwise... + */ + pcookie = (len >= 0) ? &di->readdirargs.cookie : &dummy.cookie; + if ( !xdr_nfscookie(xdrs, pcookie) ) { + return FALSE; + } + + di->len = len; + /* adjust the buffer pointer */ + if (len >= 0) { + pde->d_ino = fileid; + pde->d_namlen = nlen; + pde->d_off = di->ptr - di->buf; + if (name == dummy.nambuf) { + memcpy(pde->d_name, dummy.nambuf, nlen + 1); + } + pde->d_reclen = DIRENT_HEADER_SIZE + naligned; + di->ptr += pde->d_reclen; + } + + return TRUE; +} + +/* this routine loops over all entries */ +static bool_t +xdr_dir_info(XDR *xdrs, DirInfo di) +{ +DirInfo dip; + + if ( !xdr_nfsstat(xdrs, &di->status) ) + return FALSE; + + if ( NFS_OK != di->status ) + return TRUE; + + dip = di; + + while (dip) { + /* reserve space for the dirent 'header' - we assume it's word aligned! */ +#ifdef DEBUG + assert( DIRENT_HEADER_SIZE % 4 == 0 ); +#endif + dip->len -= DIRENT_HEADER_SIZE; + + /* we pass a 0 size - size is unused since + * we always pass a non-NULL pointer + */ + if ( !xdr_pointer(xdrs, (caddr_t*)&dip, 0 /* size */, xdr_dir_info_entry) ) + return FALSE; + } + + if ( ! xdr_bool(xdrs, &di->eofreached) ) + return FALSE; + + /* if everything fits into the XDR buffer but not the user's buffer, + * they must resume reading from where xdr_dir_info_entry() started + * skipping and 'eofreached' needs to be adjusted + */ + if ( di->len < 0 && di->eofreached ) + di->eofreached = FALSE; + + return TRUE; +} + + +/* a type better suited for node operations + * than diropres. + * fattr and fhs are swapped so parts of this + * structure may be used as a diroparg which + * is practical when looking up paths. + */ + +/* Macro for accessing serporid fields + */ +#define SERP_ARGS(node) ((node)->serporid.serporid_u.serporid.arg_u) +#define SERP_ATTR(node) ((node)->serporid.serporid_u.serporid.attributes) +#define SERP_FILE(node) ((node)->serporid.serporid_u.serporid.file) + + +typedef struct serporidok { + fattr attributes; + nfs_fh file; + union { + struct { + filename name; + } diroparg; + struct { + sattr attributes; + } sattrarg; + struct { + u_int offset; + u_int count; + u_int totalcount; + } readarg; + struct { + u_int beginoffset; + u_int offset; + u_int totalcount; + struct { + u_int data_len; + char* data_val; + } data; + } writearg; + struct { + filename name; + sattr attributes; + } createarg; + struct { + filename name; + diropargs to; + } renamearg; + struct { + diropargs to; + } linkarg; + struct { + filename name; + nfspath to; + sattr attributes; + } symlinkarg; + struct { + nfscookie cookie; + u_int count; + } readdirarg; + } arg_u; +} serporidok; + +typedef struct serporid { + nfsstat status; + union { + serporidok serporid; + } serporid_u; +} serporid; + +/* an XDR routine to encode/decode the inverted diropres + * into an nfsnodestat; + * + * NOTE: this routine only acts on + * - 'serporid.status' + * - 'serporid.file' + * - 'serporid.attributes' + * and leaves the 'arg_u' alone. + * + * The idea is that a 'diropres' is read into 'serporid' + * which can then be used as an argument to subsequent + * NFS-RPCs (after filling in the node's arg_u). + */ +static bool_t +xdr_serporidok(XDR *xdrs, serporidok *objp) +{ + if (!xdr_nfs_fh (xdrs, &objp->file)) + return FALSE; + if (!xdr_fattr (xdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +static bool_t +xdr_serporid(XDR *xdrs, serporid *objp) +{ + if (!xdr_nfsstat (xdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS_OK: + if (!xdr_serporidok(xdrs, &objp->serporid_u.serporid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +/***************************************** + Data Structures and Types + *****************************************/ + +/* 'time()' hack with less overhead; */ + +/* assume reading a long word is atomic */ +#define READ_LONG_IS_ATOMIC + +typedef rtems_unsigned32 TimeStamp; + +static inline TimeStamp +nowSeconds(void) +{ +register rtems_unsigned32 rval; +#ifndef READ_LONG_IS_ATOMIC +rtems_interrupt_level l; + + rtems_interrupt_disable(level); +#endif + + rval = _TOD_Seconds_since_epoch; + +#ifndef READ_LONG_IS_ATOMIC + rtems_interrupt_enable(level); +#endif + return rval; +} + + +/* Per mounted FS structure */ +typedef struct NfsRec_ { + /* the NFS server we're talking to. + */ + RpcUdpServer server; + /* statistics; how many NfsNodes are + * currently alive. + */ + int nodesInUse; +#if DEBUG & DEBUG_COUNT_NODES + /* statistics; how many 'NfsNode.str' + * strings are currently allocated. + */ + int stringsInUse; +#endif + /* A small number who uniquely + * identifies a mounted NFS within + * this driver (i.e. this NfsRec). + * Each time a NFS is mounted, the + * global ID counter is incremented + * and its value is assigned to the + * newly created NfsRec. + */ + u_short id; + /* Our RTEMS filesystem mt_entry + */ + rtems_filesystem_mount_table_entry_t *mt_entry; + /* Next NfsRec on a linked list who + * is anchored at nfsGlob + */ + struct NfsRec_ *next; + /* Who we pretend we are + */ + u_long uid,gid; +} NfsRec, *Nfs; + +typedef struct NfsNodeRec_ { + /* This holds this node's attributes + * (stats) and its nfs filehandle. + * It also contains room for nfs rpc + * arguments. + */ + serporid serporid; + /* The arguments we used when doing + * the 'lookup' call for this node. + * We need this information (especially + * the directory FH) for performing + * certain operations on this + * node (in particular: for unlinking + * it from a parent directory) + */ + diropargs args; + /* FS this node belongs to + */ + Nfs nfs; + /* A buffer for the string the + * args.name points to. + * We need this because args.name might + * temporarily point to strings on the + * stack. Duplicates are allocated from + * the heap and attached to 'str' so + * they can be released as appropriate. + */ + char *str; + /* A timestamp for the stats + */ + TimeStamp age; +} NfsNodeRec, *NfsNode; + +/***************************************** + Forward Declarations + *****************************************/ + +static int nfs_readlink( + rtems_filesystem_location_info_t *loc, /* IN */ + char *buf, /* OUT */ + size_t len +); + +static int updateAttr(NfsNode node, int force); + +/* Mask bits when setting attributes. + * Only the 'arg' fields with their + * corresponding bit set in the mask + * will be used. The others are left + * unchanged. + * The 'TOUCH' bits instruct nfs_sattr() + * to update the respective time + * fields to the current time + */ +#define SATTR_MODE (1<<0) +#define SATTR_UID (1<<1) +#define SATTR_GID (1<<2) +#define SATTR_SIZE (1<<3) +#define SATTR_ATIME (1<<4) +#define SATTR_TOUCHA (1<<5) +#define SATTR_MTIME (1<<6) +#define SATTR_TOUCHM (1<<7) +#define SATTR_TOUCH (SATTR_TOUCHM | SATTR_TOUCHA) + +static int +nfs_sattr(NfsNode node, sattr *arg, u_long mask); + +extern struct _rtems_filesystem_operations_table nfs_fs_ops; +extern struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers; +extern struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers; +extern struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers; +extern rtems_driver_address_table drvNfs; + +int +nfsMountsShow(FILE*); + +rtems_status_code +rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc); + + +/***************************************** + Inline Routines + *****************************************/ + + +/* * * * * * * * * * * * * * * * * * + Trivial Operations on a NfsNode + * * * * * * * * * * * * * * * * * */ + +/* determine if a location 'l' is an NFS root node */ +static inline int +locIsRoot(rtems_filesystem_location_info_t *l) +{ +NfsNode me = (NfsNode) l->node_access; +NfsNode r; + r = (NfsNode)l->mt_entry->mt_fs_root.node_access; + return SERP_ATTR(r).fileid == SERP_ATTR(me).fileid && + SERP_ATTR(r).fsid == SERP_ATTR(me).fsid; +} + +/* determine if a location 'l' is an NFS node */ +static inline int +locIsNfs(rtems_filesystem_location_info_t *l) +{ + return l->ops == &nfs_fs_ops; +} + +/* determine if two locations refer to the + * same entity. We know that 'nfsloc' is a + * location inside nfs. However, we needn't + * know anything about 'anyloc'. + */ +static inline int +locAreEqual( + rtems_filesystem_location_info_t *nfsloc, + rtems_filesystem_location_info_t *anyloc +) +{ +NfsNode na = (NfsNode) nfsloc->node_access; +NfsNode nb; + + if (!locIsNfs(anyloc)) + return 0; + + nb = (NfsNode) anyloc->node_access; + + if (na->nfs != nb->nfs) + return 0; + + updateAttr(nb, 0); + + return SERP_ATTR(na).fileid == SERP_ATTR(nb).fileid && + SERP_ATTR(na).fsid == SERP_ATTR(nb).fsid; +} + + + +/***************************************** + Global Variables + *****************************************/ + +/* These are (except for MAXNAMLEN/MAXPATHLEN) copied from IMFS */ + +static rtems_filesystem_limits_and_options_t +nfs_limits_and_options = { + 5, /* link_max */ + 6, /* max_canon */ + 7, /* max_input */ + NFS_MAXNAMLEN, /* name_max */ + NFS_MAXPATHLEN, /* path_max */ + 2, /* pipe_buf */ + 1, /* posix_async_io */ + 2, /* posix_chown_restrictions */ + 3, /* posix_no_trunc */ + 4, /* posix_prio_io */ + 5, /* posix_sync_io */ + 6 /* posix_vdisable */ +}; + +/* size of an encoded 'entry' object */ +static int dirres_entry_size; + +/* Global stuff and statistics */ +static struct nfsstats { + /* A lock for protecting the + * linked ist of mounted NFS + * and the num_mounted_fs field + */ + rtems_id llock; + /* A lock for protecting misc + * stuff within the driver. + * The lock must only be held + * for short periods of time. + */ + rtems_id lock; + /* Our major number as assigned + * by RTEMS + */ + rtems_device_major_number nfs_major; + /* The number of currently + * mounted NFS + */ + int num_mounted_fs; + /* A list of the currently + * mounted NFS + */ + struct NfsRec_ *mounted_fs; + /* A counter for allocating + * unique IDs to each mounted + * NFS. + * Assume we are not going to + * do more than 16k mounts + * during the system lifetime + */ + u_short fs_ids; +} nfsGlob = {0/* IMPORTANT */}; + + +/* Two pools of RPC transactions; + * One with small send buffers + * the other with a big one. + * The actual size of the small + * buffer is configurable (see top). + * + * Note: The RX buffers are always + * big + */ +static RpcUdpXactPool smallPool = 0; +static RpcUdpXactPool bigPool = 0; + + +/***************************************** + Implementation + *****************************************/ + +/* Create a Nfs object. This is + * per-mounted NFS information. + * + * ARGS: The Nfs server handle. + * + * RETURNS: Nfs on success, + * NULL on failure with + * errno set + * + * NOTE: The submitted server + * object is 'owned' by + * this Nfs and will be + * destroyed by nfsDestroy() + */ +static Nfs +nfsCreate(RpcUdpServer server) +{ +Nfs rval = calloc(1,sizeof(*rval)); + + if (rval) { + rval->server = server; + LOCK(nfsGlob.llock); + rval->next = nfsGlob.mounted_fs; + nfsGlob.mounted_fs = rval; + UNLOCK(nfsGlob.llock); + } else { + errno = ENOMEM; + } + return rval; +} + +/* Destroy an Nfs object and + * its associated server + */ +static void +nfsDestroy(Nfs nfs) +{ +register Nfs prev; + if (!nfs) + return; + + LOCK(nfsGlob.llock); + if (nfs == nfsGlob.mounted_fs) + nfsGlob.mounted_fs = nfs->next; + else { + for (prev = nfsGlob.mounted_fs; + prev && prev->next != nfs; + prev = prev->next) + /* nothing else to do */; + assert( prev ); + prev->next = nfs->next; + } + UNLOCK(nfsGlob.llock); + + nfs->next = 0; /* paranoia */ + rpcUdpServerDestroy(nfs->server); + free(nfs); +} + +/* + * Create a Node. The node will + * be associated with a particular + * mounted NFS identified by 'nfs' + * Optionally, a NFS file handle + * may be copied into this node. + * + * ARGS: nfs of the NFS this node + * belongs to. + * NFS file handle identifying + * this node. + * RETURNS: node on success, + * NULL on failure with errno + * set. + * + * NOTE: The caller of this routine + * is responsible for copying + * a NFS file handle if she + * choses to pass a NULL fh. + * + * The driver code assumes the + * a node always has a valid + * NFS filehandle and file + * attributes (unless the latter + * are aged). + */ +static NfsNode +nfsNodeCreate(Nfs nfs, nfs_fh *fh) +{ +NfsNode rval = malloc(sizeof(*rval)); + +#if DEBUG & DEBUG_TRACK_NODES + fprintf(stderr,"NFS: creating a node\n"); +#endif + + if (rval) { + if (fh) + memcpy( &SERP_FILE(rval), fh, sizeof(*fh) ); + rval->nfs = nfs; + rval->str = 0; + LOCK(nfsGlob.lock); + nfs->nodesInUse++; + UNLOCK(nfsGlob.lock); + } else { + errno = ENOMEM; + } + + return rval; +} + +/* destroy a node */ +static void +nfsNodeDestroy(NfsNode node) +{ +#if DEBUG & DEBUG_TRACK_NODES + fprintf(stderr,"NFS: destroying a node\n"); +#endif +#if 0 + if (!node) + return; + /* this probably does nothing... */ + xdr_free(xdr_serporid, &node->serporid); +#endif + + LOCK(nfsGlob.lock); + node->nfs->nodesInUse--; +#if DEBUG & DEBUG_COUNT_NODES + if (node->str) + node->nfs->stringsInUse--; +#endif + UNLOCK(nfsGlob.lock); + + if (node->str) + free(node->str); + + free(node); +} + +/* Clone a given node (AKA copy constructor), + * i.e. create an exact copy. + * + * ARGS: node to clone + * RETURNS: new node on success + * NULL on failure with errno set. + * + * NOTE: a string attached to 'str' + * is cloned as well. Outdated + * attributes (of the new copy + * only) will be refreshed + * (if unsuccessful, this could + * be a reason for failure to + * clone a node). + */ +static NfsNode +nfsNodeClone(NfsNode node) +{ +NfsNode rval = nfsNodeCreate(node->nfs, 0); + + if (rval) { + *rval = *node; + + /* must clone the string also */ + if (node->str) { + rval->args.name = rval->str = strdup(node->str); + if (!rval->str) { + nfsNodeDestroy(rval); + return 0; + } +#if DEBUG & DEBUG_COUNT_NODES + LOCK(nfsGlob.lock); + node->nfs->stringsInUse++; + UNLOCK(nfsGlob.lock); +#endif + } + + /* possibly update the stats */ + if (updateAttr(rval, 0 /* only if necessary */)) { + nfsNodeDestroy(rval); + return 0; + } + } + return rval; +} + +/* Initialize the driver. + * + * ARGS: depth of the small and big + * transaction pools, i.e. how + * many transactions (buffers) + * should always be kept around. + * + * (If more transactions are needed, + * they are created and destroyed + * on the fly). + */ +void +nfsInit(int smallPoolDepth, int bigPoolDepth) +{ +entry dummy; + + fprintf(stderr,"This is RTEMS-NFS Release SSRL_RTEMS_20041202\n"); + fprintf(stderr,"(nfs.c,v 1.33 2004/09/22 22:10:41 till Exp)\n\n"); + fprintf(stderr,"Till Straumann, Stanford/SLAC/SSRL 2002\n"); + fprintf(stderr,"See LICENSE file for licensing info\n"); + + /* Get a major number */ + + if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, &nfsGlob.nfs_major)) { + fprintf(stderr,"Registering NFS driver failed - %s\n", strerror(errno)); + return; + } + + if (0==smallPoolDepth) + smallPoolDepth = 20; + if (0==bigPoolDepth) + bigPoolDepth = 10; + + /* it's crucial to zero out the 'next' pointer + * because it terminates the xdr_entry recursion + * + * we also must make the filename some non-zero + * char pointer! + */ + + memset(&dummy, 0, sizeof(dummy)); + + dummy.nextentry = 0; + dummy.name = "somename"; /* guess average length of a filename */ + dirres_entry_size = xdr_sizeof(xdr_entry, &dummy); + + assert( smallPool = rpcUdpXactPoolCreate( + NFS_PROGRAM, + NFS_VERSION_2, + CONFIG_NFS_SMALL_XACT_SIZE, + smallPoolDepth) ); + + assert( bigPool = rpcUdpXactPoolCreate( + NFS_PROGRAM, + NFS_VERSION_2, + CONFIG_NFS_BIG_XACT_SIZE, + bigPoolDepth) ); + + assert( RTEMS_SUCCESSFUL == rtems_semaphore_create( + rtems_build_name('N','F','S','l'), + 1, + MUTEX_ATTRIBUTES, + 0, + &nfsGlob.llock) ); + + assert( RTEMS_SUCCESSFUL == rtems_semaphore_create( + rtems_build_name('N','F','S','m'), + 1, + MUTEX_ATTRIBUTES, + 0, + &nfsGlob.lock) ); + + if (sizeof(ino_t) < sizeof(u_int)) { + fprintf(stderr, + "WARNING: Using 'short st_ino' hits performance and may fail to access/find correct files\n"); + fprintf(stderr, + "you should fix newlib's sys/stat.h - for now I'll enable a hack...\n"); + + } +} + +/* Driver cleanup code + */ +int +nfsCleanup(void) +{ +rtems_id l; +int refuse; + + if (!nfsGlob.llock) { + /* registering the driver failed - let them still cleanup */ + return 0; + } + + LOCK(nfsGlob.llock); + if ( (refuse = nfsGlob.num_mounted_fs) ) { + fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n", + refuse); + nfsMountsShow(stderr); + /* yes, printing is slow - but since you try to unload the driver, + * you assume nobody is using NFS, so what if they have to wait? + */ + UNLOCK(nfsGlob.llock); + return -1; + } + + rtems_semaphore_delete(nfsGlob.lock); + nfsGlob.lock = 0; + + /* hold the lock while cleaning up... */ + + rpcUdpXactPoolDestroy(smallPool); + rpcUdpXactPoolDestroy(bigPool); + l = nfsGlob.llock; + rtems_io_unregister_driver(nfsGlob.nfs_major); + + rtems_semaphore_delete(l); + nfsGlob.llock = 0; + return 0; +} + +/* NFS RPC wrapper. + * + * ARGS: srvr the NFS server we want to call + * proc the NFSPROC_xx we want to invoke + * xargs xdr routine to wrap the arguments + * pargs pointer to the argument object + * xres xdr routine to unwrap the results + * pres pointer to the result object + * + * RETURNS: 0 on success, -1 on error with errno set. + * + * NOTE: the caller assumes that errno is set to + * a nonzero value if this routine returns + * an error (nonzero return value). + * + * This routine prints RPC error messages to + * stderr. + */ +STATIC int +nfscall( + RpcUdpServer srvr, + int proc, + xdrproc_t xargs, + void * pargs, + xdrproc_t xres, + void * pres) +{ +RpcUdpXact xact; +enum clnt_stat stat; +RpcUdpXactPool pool; +int rval = -1; + + + switch (proc) { + case NFSPROC_SYMLINK: + case NFSPROC_WRITE: + pool = bigPool; break; + default: pool = smallPool; break; + } + + xact = rpcUdpXactPoolGet(pool, XactGetCreate); + + if ( !xact ) { + errno = ENOMEM; + return -1; + } + + if ( RPC_SUCCESS != (stat=rpcUdpSend( + xact, + srvr, + NFSCALL_TIMEOUT, + proc, + xres, + pres, + xargs, + pargs, + 0)) || + RPC_SUCCESS != (stat=rpcUdpRcv(xact)) ) { + + fprintf(stderr, + "NFS (proc %i) - %s\n", + proc, + clnt_sperrno(stat)); + + switch (stat) { + /* TODO: this is probably not complete and/or fully accurate */ + case RPC_CANTENCODEARGS : errno = EINVAL; break; + case RPC_AUTHERROR : errno = EPERM; break; + + case RPC_CANTSEND : + case RPC_CANTRECV : /* hope they have errno set */ + case RPC_SYSTEMERROR : break; + + default : errno = EIO; break; + } + } else { + rval = 0; + } + + /* release the transaction back into the pool */ + rpcUdpXactPoolPut(xact); + + if (rval && !errno) + errno = EIO; + + return rval; +} + +/* Check the 'age' of a node's stats + * and read the attributes from the server + * if necessary. + * + * ARGS: node node to update + * force enforce updating ignoring + * the timestamp/age + * + * RETURNS: 0 on success, + * -1 on failure with errno set + */ + +static int +updateAttr(NfsNode node, int force) +{ + + if (force +#ifdef CONFIG_ATTR_LIFETIME + || (nowSeconds() - node->age > CONFIG_ATTR_LIFETIME) +#endif + ) { + if ( nfscall(node->nfs->server, + NFSPROC_GETATTR, + xdr_nfs_fh, &SERP_FILE(node), + xdr_attrstat, &node->serporid) ) + return -1; + + if ( NFS_OK != node->serporid.status ) { + errno = node->serporid.status; + return -1; + } + + node->age = nowSeconds(); + } + + return 0; +} + +/* + * IP address helper. Note that we avoid + * gethostbyname() since it's not reentrant. + * + * initialize a sockaddr_in from a + * ['.''@']':'" string and let + * pPath point to the part; retrieve the optional + * uid/gids + * + * ARGS: see description above + * + * RETURNS: 0 on success, + * -1 on failure with errno set + */ +static int +buildIpAddr(u_long *puid, u_long *pgid, + char **pHost, struct sockaddr_in *psa, + char **pPath) +{ +char host[30]; +char *chpt = *pPath; +char *path; +int len; + + if ( !chpt ) { + errno = EINVAL; + return -1; + } + + /* look for the optional uid/gid */ + if ( (chpt = strchr(chpt, UIDSEP)) ) { + if ( 2 != sscanf(*pPath,"%li.%li",puid,pgid) ) { + errno = EINVAL; + return -1; + } + chpt++; + } else { + *puid = RPCIOD_DEFAULT_ID; + *pgid = RPCIOD_DEFAULT_ID; + chpt = *pPath; + } + if ( pHost ) + *pHost = chpt; + + /* split the device name which is in the form + * + * ':' + * + * into its components using a local buffer + */ + + if ( !(path = strchr(chpt, HOSTDELIM)) || + (len = path - chpt) >= sizeof(host) - 1 ) { + errno = EINVAL; + return -1; + } + /* point to path beyond ':' */ + path++; + + strncpy(host, chpt, len); + host[len]=0; + + if ( ! inet_aton(host, &psa->sin_addr) ) { + errno = ENXIO; + return -1; + } + + psa->sin_family = AF_INET; + psa->sin_port = 0; + *pPath = path; + return 0; +} + +/* wrapper similar to nfscall. + * However, since it is not used + * very often, the simpler and less + * efficient rpcUdpCallRp API is used. + * + * ARGS: see 'nfscall()' above + * + * RETURNS: RPC status + */ +static enum clnt_stat +mntcall( + struct sockaddr_in *psrvr, + int proc, + xdrproc_t xargs, + void * pargs, + xdrproc_t xres, + void * pres, + u_long uid, + u_long gid) +{ +#ifdef MOUNT_V1_PORT +int retry; +#endif +enum clnt_stat stat = RPC_FAILED; + +#ifdef MOUNT_V1_PORT + /* if the portmapper fails, retry a fixed port */ + for (retry = 1, psrvr->sin_port = 0, stat = RPC_FAILED; + retry >= 0 && stat; + stat && (psrvr->sin_port = htons(MOUNT_V1_PORT)), retry-- ) +#endif + stat = rpcUdpCallRp( + psrvr, + MOUNTPROG, + MOUNTVERS, + proc, + xargs, + pargs, + xres, + pres, + uid, + gid, + MNTCALL_TIMEOUT + ); + return stat; +} + +/***************************************** + RTEMS File System Operations for NFS + *****************************************/ + +#if 0 /* for reference */ + +struct rtems_filesystem_location_info_tt +{ + void *node_access; + rtems_filesystem_file_handlers_r *handlers; + rtems_filesystem_operations_table *ops; + rtems_filesystem_mount_table_entry_t *mt_entry; +}; + +#endif + +/* + * Evaluate a path letting 'pathloc' travel along. + * + * The important semantics of this operation are: + * + * If this routine returns -1, the caller assumes + * pathloc to be _invalid_ and hence it will not + * invoke rtems_filesystem_freenode() on it. + * + * OTOH, if evalpath returns 0, + * rtems_filesystem_freenode() will eventually be + * called which results in our freeing the associated + * NfsNode attached to node_access. + * + * Therefore, this routine will _always_ allocate + * a NfsNode and pass it out to *pathloc (provided + * that the evaluation succeeds). + * + * However, if the evaluation finds that it has to + * step across FS boundaries (mount point or a symlink + * pointing outside), the NfsNode is destroyed + * before passing control to the new FS' evalpath_h() + * + */ + +STATIC int nfs_do_evalpath( + const char *pathname, /* IN */ + void *arg, + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + int forMake +) +{ +char *del = 0, *part; +int e = 0; +NfsNode node = pathloc->node_access; +char *p = malloc(MAXPATHLEN+1); +Nfs nfs = (Nfs)pathloc->mt_entry->fs_info; +RpcUdpServer server = nfs->server; + + if ( !p ) { + e = ENOMEM; + goto cleanup; + } + strcpy(p, pathname); + + /* clone the node */ + if ( !(node = nfsNodeClone(node)) ) { + /* nodeClone sets errno */ + goto cleanup; + } + + pathloc->node_access = node; + + /* Special case: the RTEMS filesystem code + * may emit '..' on a regular file node to + * find the parent directory :-(. + * (eval.c: rtems_filesystem_evaluate_parent()) + * Try to catch this case here: + */ + if ( NFDIR != SERP_ATTR(node).type && '.'==*p && '.'==*(p+1) ) { + for ( part = p+2; '/'==*part; part++ ) + /* skip trailing '/' */; + if ( !*part ) { + /* this is it; back out dir and let them look up the dir itself... */ + memcpy( &SERP_FILE(node), + &node->args.dir, + sizeof(node->args.dir)); + *(p+1)=0; + } + } + + for (part=p; part && *part; part=del) { + + if ( NFLNK == SERP_ATTR(node).type ) { + /* follow midpath link */ + char *b = malloc(NFS_MAXPATHLEN+1); + int l; + + if (!b) { + e = ENOMEM; + goto cleanup; + } + if (nfs_readlink(pathloc, b, NFS_MAXPATHLEN+1)) { + free(b); + e = errno; + goto cleanup; + } + + /* prepend the link value to the rest of the path */ + if ( (l=strlen(b)) + strlen(part) + 1 > NFS_MAXPATHLEN ) { + free(b); + e = EINVAL; + goto cleanup; + } + /* swap string buffers and reset delimiter */ + b[l++] = DELIM; + strcpy(b+l,part); + part = b; + b = p; + p = del = part; + + free(b); + + /* back up the directory filehandle (only necessary + * if we don't back out to the root + */ + if (! (DELIM == *part) ) { + memcpy( &SERP_FILE(node), + &node->args.dir, + sizeof(node->args.dir)); + + if (updateAttr(node, 1 /* force */)) { + e = errno; + goto cleanup; + } + } + } + + /* find delimiter and eat /// sequences + * (only if we don't restart at the root) + */ + if ( DELIM != *part && (del = strchr(part, DELIM))) { + do { + *del++=0; + } while (DELIM==*del); + } + + /* refuse to backup over the root */ + if ( 0==strcmp(part,UPDIR) + && locAreEqual(pathloc, &rtems_filesystem_root) ) { + part++; + } + + /* cross mountpoint upwards */ + if ( (0==strcmp(part,UPDIR) && locIsRoot(pathloc)) /* cross mountpoint up */ + || DELIM == *part /* link starts at root */ + ) { + int rval; + +#if DEBUG & DEBUG_EVALPATH + fprintf(stderr, + "Crossing mountpoint upwards\n"); +#endif + + if (DELIM == *part) { + *pathloc = rtems_filesystem_root; + } else { + *pathloc = pathloc->mt_entry->mt_point_node; + /* re-append the rest of the path */ + if (del) + while ( 0 == *--del ) + *del = DELIM; + } + + nfsNodeDestroy(node); + +#if DEBUG & DEBUG_EVALPATH + fprintf(stderr, + "Re-evaluating '%s'\n", + part); +#endif + + if (forMake) + rval = pathloc->ops->evalformake_h(part, pathloc, (const char**)arg); + else + rval = pathloc->ops->evalpath_h(part, (int)arg, pathloc); + + free(p); + return rval; + } + + /* lookup one element */ + SERP_ARGS(node).diroparg.name = part; + + /* remember args / directory fh */ + memcpy( &node->args, &SERP_FILE(node), sizeof(node->args)); + + /* don't lookup the item we want to create */ + if ( forMake && (!del || !*del) ) + break; + +#if DEBUG & DEBUG_EVALPATH + fprintf(stderr,"Looking up '%s'\n",part); +#endif + + if ( nfscall(server, + NFSPROC_LOOKUP, + xdr_diropargs, &SERP_FILE(node), + xdr_serporid, &node->serporid) || + NFS_OK != (errno=node->serporid.status) ) { + e = errno; + goto cleanup; + } + node->age = nowSeconds(); + +#if DEBUG & DEBUG_EVALPATH + if (NFLNK == SERP_ATTR(node).type && del) { + fprintf(stderr, + "Following midpath link '%s'\n", + part); + } +#endif + + } + + if (forMake) { + /* remember the name - do this _before_ copying + * the name to local storage; the caller expects a + * pointer into pathloc + */ + assert( node->args.name ); + + *(const char**)arg = pathname + (node->args.name - p); + +#if 0 + /* restore the directory node */ + + memcpy( &SERP_FILE(node), + &node->args.dir, + sizeof(node->args.dir)); + + if ( (nfscall(nfs->server, + NFSPROC_GETATTR, + xdr_nfs_fh, &SERP_FILE(node), + xdr_attrstat, &node->serporid) && !errno && (errno = EIO)) || + (NFS_OK != (errno=node->serporid.status) ) ) { + goto cleanup; + } +#endif + } + + if (locIsRoot(pathloc)) { + + /* stupid filesystem code has no 'op' for comparing nodes + * but just compares the 'node_access' pointers. + * Luckily, this is only done for comparing the root nodes. + * Hence, we never give them a copy of the root but always + * the root itself. + */ + pathloc->node_access = pathloc->mt_entry->mt_fs_root.node_access; + /* increment the 'in use' counter since we return one more + * reference to the root node + */ + LOCK(nfsGlob.lock); + nfs->nodesInUse++; + UNLOCK(nfsGlob.lock); + nfsNodeDestroy(node); + + + } else { + switch (SERP_ATTR(node).type) { + case NFDIR: pathloc->handlers = &nfs_dir_file_handlers; break; + case NFREG: pathloc->handlers = &nfs_file_file_handlers; break; + case NFLNK: pathloc->handlers = &nfs_link_file_handlers; break; + default: pathloc->handlers = &rtems_filesystem_null_handlers; break; + } + pathloc->node_access = node; + + /* remember the name of this directory entry */ + + if (node->args.name) { + if (node->str) { +#if DEBUG & DEBUG_COUNT_NODES + LOCK(nfsGlob.lock); + nfs->stringsInUse--; + UNLOCK(nfsGlob.lock); +#endif + free(node->str); + } + node->args.name = node->str = strdup(node->args.name); + if (!node->str) { + e = ENOMEM; + goto cleanup; + } + +#if DEBUG & DEBUG_COUNT_NODES + LOCK(nfsGlob.lock); + nfs->stringsInUse++; + UNLOCK(nfsGlob.lock); +#endif + } + + } + node = 0; + + e = 0; + +cleanup: + free(p); + if (node) { + nfsNodeDestroy(node); + pathloc->node_access = 0; + } +#if DEBUG & DEBUG_COUNT_NODES + fprintf(stderr, + "leaving evalpath, in use count is %i nodes, %i strings\n", + nfs->nodesInUse, nfs->stringsInUse); +#endif + if (e) { +#if DEBUG & DEBUG_EVALPATH + perror("Evalpath"); +#endif + rtems_set_errno_and_return_minus_one(e); + } else { + return 0; + } +} + +/* MANDATORY; may set errno=ENOSYS and return -1 */ +static int nfs_evalformake( + const char *path, /* IN */ + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + const char **pname /* OUT */ +) +{ + return nfs_do_evalpath(path, (void*)pname, pathloc, 1 /*forMake*/); +} + +static int nfs_evalpath( + const char *path, /* IN */ + int flags, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN/OUT */ +) +{ + return nfs_do_evalpath(path, (void*)flags, pathloc, 0 /*not forMake*/); +} + + +/* create a hard link */ + +static int nfs_link( + rtems_filesystem_location_info_t *to_loc, /* IN */ + rtems_filesystem_location_info_t *parent_loc, /* IN */ + const char *name /* IN */ +) +{ +NfsNode pNode; +nfsstat status; +NfsNode tNode = to_loc->node_access; + +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr,"Creating link '%s'\n",name); +#endif + + if ( !locIsNfs(parent_loc) ) { + errno = EXDEV; + return -1; + } + + pNode = parent_loc->node_access; + if ( tNode->nfs != pNode->nfs ) { + errno = EXDEV; + return -1; + } + memcpy(&SERP_ARGS(tNode).linkarg.to.dir, + &SERP_FILE(pNode), + sizeof(SERP_FILE(pNode))); + + SERP_ARGS(tNode).linkarg.to.name = (filename)name; + + if ( nfscall(tNode->nfs->server, + NFSPROC_LINK, + xdr_linkargs, &SERP_FILE(tNode), + xdr_nfsstat, &status) + || (NFS_OK != (errno = status)) + ) { +#if DEBUG & DEBUG_SYSCALLS + perror("nfs_link"); +#endif + return -1; + } + + return 0; + +} + +static int nfs_do_unlink( + rtems_filesystem_location_info_t *loc, /* IN */ + int proc +) +{ +nfsstat status; +NfsNode node = loc->node_access; +Nfs nfs = node->nfs; +#if DEBUG & DEBUG_SYSCALLS +char *name = NFSPROC_REMOVE == proc ? + "nfs_unlink" : "nfs_rmdir"; +#endif + + /* The FS generics have determined that pathloc is _not_ + * a directory. Hence we may assume that the parent + * is in our NFS. + */ + +#if DEBUG & DEBUG_SYSCALLS + assert( node->args.name == node->str && node->str ); + + fprintf(stderr,"%s '%s'\n", name, node->args.name); +#endif + + if ( nfscall(nfs->server, + proc, + xdr_diropargs, &node->args, + xdr_nfsstat, &status) + || (NFS_OK != (errno = status)) + ) { +#if DEBUG & DEBUG_SYSCALLS + perror(name); +#endif + return -1; + } + + return 0; +} + +static int nfs_unlink( + rtems_filesystem_location_info_t *loc /* IN */ +) +{ + return nfs_do_unlink(loc, NFSPROC_REMOVE); +} + +static int nfs_chown( + rtems_filesystem_location_info_t *pathloc, /* IN */ + uid_t owner, /* IN */ + gid_t group /* IN */ +) +{ +sattr arg; + + arg.uid = owner; + arg.gid = group; + + return nfs_sattr(pathloc->node_access, &arg, SATTR_UID | SATTR_GID); + +} + +/* Cleanup the FS private info attached to pathloc->node_access */ +static int nfs_freenode( + rtems_filesystem_location_info_t *pathloc /* IN */ +) +{ +Nfs nfs = ((NfsNode)pathloc->node_access)->nfs; + + /* never destroy the root node; it is released by the unmount + * code + */ + if (locIsRoot(pathloc)) { + /* just adjust the references to the root node but + * don't really release it + */ + LOCK(nfsGlob.lock); + nfs->nodesInUse--; + UNLOCK(nfsGlob.lock); + } else { + nfsNodeDestroy(pathloc->node_access); + pathloc->node_access = 0; + } +#if DEBUG & DEBUG_COUNT_NODES + fprintf(stderr, + "leaving freenode, in use count is %i nodes, %i strings\n", + nfs->nodesInUse, + nfs->stringsInUse); +#endif + return 0; +} + +/* NOTE/TODO: mounting on top of NFS is not currently supported + * + * Challenge: stateless protocol. It would be possible to + * delete mount points on the server. We would need some sort + * of a 'garbage collector' looking for dead/unreachable + * mount points and unmounting them. + * Also, the path evaluation routine would have to check + * for crossing mount points. Crossing over from one NFS + * into another NFS could probably handled iteratively + * rather than by recursion. + */ + +#ifdef DECLARE_BODY +/* This routine is called when they try to mount something + * on top of THIS filesystem, i.e. if one of our directories + * is used as a mount point + */ +static int nfs_mount( + rtems_filesystem_mount_table_entry_t *mt_entry /* in */ +)DECLARE_BODY +#else +#define nfs_mount 0 +#endif + +#ifdef DECLARE_BODY +/* This op is called when they try to unmount a FS + * from a mountpoint managed by THIS FS. + */ +static int nfs_unmount( + rtems_filesystem_mount_table_entry_t *mt_entry /* in */ +)DECLARE_BODY +#else +#define nfs_unmount 0 +#endif + +#if 0 + +/* for reference (libio.h) */ + +struct rtems_filesystem_mount_table_entry_tt { + Chain_Node Node; + rtems_filesystem_location_info_t mt_point_node; + rtems_filesystem_location_info_t mt_fs_root; + int options; + void *fs_info; + + rtems_filesystem_limits_and_options_t pathconf_limits_and_options; + + /* + * When someone adds a mounted filesystem on a real device, + * this will need to be used. + * + * The best option long term for this is probably an open file descriptor. + */ + char *dev; +}; +#endif + + +/* This op is called as the last step of mounting this FS */ +STATIC int nfs_fsmount_me( + rtems_filesystem_mount_table_entry_t *mt_entry +) +{ +char *host; +struct sockaddr_in saddr; +enum clnt_stat stat; +fhstatus fhstat; +u_long uid,gid; +#ifdef NFS_V2_PORT +int retry; +#endif +Nfs nfs = 0; +NfsNode rootNode = 0; +RpcUdpServer nfsServer = 0; +int e = -1; +char *path = mt_entry->dev; + + + if ( buildIpAddr(&uid, &gid, &host, &saddr, &path) ) + return -1; + + +#ifdef NFS_V2_PORT + /* if the portmapper fails, retry a fixed port */ + for (retry = 1, saddr.sin_port = 0, stat = RPC_FAILED; + retry >= 0 && stat; + stat && (saddr.sin_port = htons(NFS_V2_PORT)), retry-- ) +#endif + stat = rpcUdpServerCreate( + &saddr, + NFS_PROGRAM, + NFS_VERSION_2, + uid, + gid, + &nfsServer + ); + + if ( RPC_SUCCESS != stat ) { + fprintf(stderr, + "Unable to contact NFS server - invalid port? (%s)\n", + clnt_sperrno(stat)); + e = EPROTONOSUPPORT; + goto cleanup; + } + + + /* first, try to ping the NFS server by + * calling the NULL proc. + */ + if ( nfscall(nfsServer, + NFSPROC_NULL, + xdr_void, 0, + xdr_void, 0) ) { + + fputs("NFS Ping ",stderr); + fwrite(host, 1, path-host-1, stderr); + fprintf(stderr," failed: %s\n", strerror(errno)); + + e = errno ? errno : EIO; + goto cleanup; + } + + /* that seemed to work - we now try the + * actual mount + */ + + /* reuse server address but let the mntcall() + * search for the mountd's port + */ + saddr.sin_port = 0; + + stat = mntcall( &saddr, + MOUNTPROC_MNT, + xdr_dirpath, + &path, + xdr_fhstatus, + &fhstat, + uid, + gid ); + + if (stat) { + fprintf(stderr,"MOUNT -- %s\n",clnt_sperrno(stat)); + if ( e<=0 ) + e = EIO; + goto cleanup; + } else if (NFS_OK != (e=fhstat.fhs_status)) { + fprintf(stderr,"MOUNT: %s\n",strerror(e)); + goto cleanup; + } + + assert( nfs = nfsCreate(nfsServer) ); + nfsServer = 0; + + nfs->uid = uid; + nfs->gid = gid; + + /* that seemed to work - we now create the root node + * and we also must obtain the root node attributes + */ + assert( rootNode = nfsNodeCreate(nfs, (nfs_fh*)&fhstat.fhstatus_u.fhs_fhandle ) ); + + if ( updateAttr(rootNode, 1 /* force */) ) { + e = errno; + goto cleanup; + } + + /* looks good so far */ + + mt_entry->mt_fs_root.node_access = rootNode; + + rootNode = 0; + + mt_entry->mt_fs_root.ops = &nfs_fs_ops; + mt_entry->mt_fs_root.handlers = &nfs_dir_file_handlers; + mt_entry->pathconf_limits_and_options = nfs_limits_and_options; + + LOCK(nfsGlob.llock); + nfsGlob.num_mounted_fs++; + /* allocate a new ID for this FS */ + nfs->id = nfsGlob.fs_ids++; + UNLOCK(nfsGlob.llock); + + mt_entry->fs_info = nfs; + nfs->mt_entry = mt_entry; + nfs = 0; + + e = 0; + +cleanup: + if (nfs) + nfsDestroy(nfs); + if (nfsServer) + rpcUdpServerDestroy(nfsServer); + if (rootNode) + nfsNodeDestroy(rootNode); + if (e) + rtems_set_errno_and_return_minus_one(e); + else + return 0; +} + +/* This op is called when they try to unmount THIS fs */ +STATIC int nfs_fsunmount_me( + rtems_filesystem_mount_table_entry_t *mt_entry /* in */ +) +{ +enum clnt_stat stat; +struct sockaddr_in saddr; +char *path = mt_entry->dev; +int nodesInUse; +u_long uid,gid; + + LOCK(nfsGlob.lock); + nodesInUse = ((Nfs)mt_entry->fs_info)->nodesInUse; + UNLOCK(nfsGlob.lock); + + if (nodesInUse > 1 /* one ref to the root node used by us */) { + fprintf(stderr, + "Refuse to unmount; there are still %i nodes in use (1 used by us)\n", + nodesInUse); + rtems_set_errno_and_return_minus_one(EBUSY); + } + + assert( 0 == buildIpAddr(&uid, &gid, 0, &saddr, &path) ); + + stat = mntcall( &saddr, + MOUNTPROC_UMNT, + xdr_dirpath, &path, + xdr_void, 0, + uid, + gid + ); + + if (stat) { + fprintf(stderr,"NFS UMOUNT -- %s\n", clnt_sperrno(stat)); + errno = EIO; + return -1; + } + + nfsNodeDestroy(mt_entry->mt_fs_root.node_access); + mt_entry->mt_fs_root.node_access = 0; + + nfsDestroy(mt_entry->fs_info); + mt_entry->fs_info = 0; + + LOCK(nfsGlob.llock); + nfsGlob.num_mounted_fs--; + UNLOCK(nfsGlob.llock); + + return 0; +} + +/* OPTIONAL; may be NULL - BUT: CAUTION; mount() doesn't check + * for this handler to be present - a fs bug + * //NOTE: (10/25/2002) patch submitted and probably applied + */ +static rtems_filesystem_node_types_t nfs_node_type( + rtems_filesystem_location_info_t *pathloc /* in */ +) +{ +NfsNode node = pathloc->node_access; + + if (updateAttr(node, 0 /* only if old */)) + return -1; + + switch( SERP_ATTR(node).type ) { + default: + /* rtems has no value for 'unknown'; + */ + case NFNON: + case NFSOCK: + case NFBAD: + case NFFIFO: + break; + + + case NFREG: return RTEMS_FILESYSTEM_MEMORY_FILE; + case NFDIR: return RTEMS_FILESYSTEM_DIRECTORY; + + case NFBLK: + case NFCHR: return RTEMS_FILESYSTEM_DEVICE; + + case NFLNK: return RTEMS_FILESYSTEM_SYM_LINK; + } + return -1; +} + +static int nfs_mknod( + const char *path, /* IN */ + mode_t mode, /* IN */ + dev_t dev, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN/OUT */ +) +{ +rtems_clock_time_value now; +diropres res; +NfsNode node = pathloc->node_access; +mode_t type = S_IFMT & mode; + + if (type != S_IFDIR && type != S_IFREG) + rtems_set_errno_and_return_minus_one(ENOTSUP); + +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr,"nfs_mknod: creating %s\n", path); +#endif + + rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE, &now); + + SERP_ARGS(node).createarg.name = (filename)path; + SERP_ARGS(node).createarg.attributes.mode = mode; + /* TODO: either use our uid or use the Nfs credentials */ + SERP_ARGS(node).createarg.attributes.uid = 0; + SERP_ARGS(node).createarg.attributes.gid = 0; + SERP_ARGS(node).createarg.attributes.size = 0; + SERP_ARGS(node).createarg.attributes.atime.seconds = now.seconds; + SERP_ARGS(node).createarg.attributes.atime.useconds = now.microseconds; + SERP_ARGS(node).createarg.attributes.mtime.seconds = now.seconds; + SERP_ARGS(node).createarg.attributes.mtime.useconds = now.microseconds; + + if ( nfscall( node->nfs->server, + NFSPROC_CREATE, + xdr_createargs, &SERP_FILE(node), + xdr_diropres, &res) + || (NFS_OK != (errno = res.status)) ) { +#if DEBUG & DEBUG_SYSCALLS + perror("nfs_mknod"); +#endif + return -1; + } + + return 0; +} + +static int nfs_utime( + rtems_filesystem_location_info_t *pathloc, /* IN */ + time_t actime, /* IN */ + time_t modtime /* IN */ +) +{ +sattr arg; + + /* TODO: add rtems EPOCH - UNIX EPOCH seconds */ + arg.atime.seconds = actime; + arg.atime.useconds = 0; + arg.mtime.seconds = modtime; + arg.mtime.useconds = 0; + + return nfs_sattr(pathloc->node_access, &arg, SATTR_ATIME | SATTR_MTIME); +} + +static int nfs_symlink( + rtems_filesystem_location_info_t *loc, /* IN */ + const char *link_name, /* IN */ + const char *node_name +) +{ +rtems_clock_time_value now; +nfsstat status; +NfsNode node = loc->node_access; + + +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr,"nfs_symlink: creating %s -> %s\n", link_name, node_name); +#endif + + rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE, &now); + + SERP_ARGS(node).symlinkarg.name = (filename)link_name; + SERP_ARGS(node).symlinkarg.to = (nfspath) node_name; + + SERP_ARGS(node).symlinkarg.attributes.mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; + /* TODO */ + SERP_ARGS(node).symlinkarg.attributes.uid = 0; + SERP_ARGS(node).symlinkarg.attributes.gid = 0; + SERP_ARGS(node).symlinkarg.attributes.size = 0; + SERP_ARGS(node).symlinkarg.attributes.atime.seconds = now.seconds; + SERP_ARGS(node).symlinkarg.attributes.atime.useconds = now.microseconds; + SERP_ARGS(node).symlinkarg.attributes.mtime.seconds = now.seconds; + SERP_ARGS(node).symlinkarg.attributes.mtime.useconds = now.microseconds; + + if ( nfscall( node->nfs->server, + NFSPROC_SYMLINK, + xdr_symlinkargs, &SERP_FILE(node), + xdr_nfsstat, &status) + || (NFS_OK != (errno = status)) ) { +#if DEBUG & DEBUG_SYSCALLS + perror("nfs_symlink"); +#endif + return -1; + } + + return 0; +} + +static int nfs_do_readlink( + rtems_filesystem_location_info_t *loc, /* IN */ + strbuf *psbuf /* IN/OUT */ +) +{ +NfsNode node = loc->node_access; +Nfs nfs = node->nfs; +readlinkres_strbuf rr; +int wasAlloced; +int rval; + + rr.strbuf = *psbuf; + + wasAlloced = (0 == psbuf->buf); + + if ( (rval = nfscall(nfs->server, + NFSPROC_READLINK, + xdr_nfs_fh, &SERP_FILE(node), + xdr_readlinkres_strbuf, &rr)) ) { + if (wasAlloced) + xdr_free( xdr_strbuf, (caddr_t)&rr.strbuf ); + } + + + if (NFS_OK != rr.status) { + if (wasAlloced) + xdr_free( xdr_strbuf, (caddr_t)&rr.strbuf ); + rtems_set_errno_and_return_minus_one(rr.status); + } + + *psbuf = rr.strbuf; + + return 0; +} + +static int nfs_readlink( + rtems_filesystem_location_info_t *loc, /* IN */ + char *buf, /* OUT */ + size_t len +) +{ +strbuf sbuf; + sbuf.buf = buf; + sbuf.max = len; + + return nfs_do_readlink(loc, &sbuf); +} + +/* The semantics of this routine are: + * + * The caller submits a valid pathloc, i.e. it has + * an NfsNode attached to node_access. + * On return, pathloc points to the target node which + * may or may not be an NFS node. + * Hence, the original NFS node is released in either + * case: + * - link evaluation fails; pathloc points to no valid node + * - link evaluation success; pathloc points to a new valid + * node. If it's an NFS node, a new NfsNode will be attached + * to node_access... + */ + +#define LINKVAL_BUFLEN (MAXPATHLEN+1) +#define RVAL_ERR_BUT_DONT_FREENODE (-1) +#define RVAL_ERR_AND_DO_FREENODE ( 1) +#define RVAL_OK ( 0) + +static int nfs_eval_link( + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + int flags /* IN */ +) +{ +rtems_filesystem_node_types_t type; +char *buf = malloc(LINKVAL_BUFLEN); +int rval = RVAL_ERR_AND_DO_FREENODE; + + if (!buf) { + errno = ENOMEM; + goto cleanup; + } + + /* in this loop, we must not use NFS specific ops as we might + * step out of our FS during the process... + * This algorithm should actually be performed by the + * generic's evaluate_path routine :-( + * + * Unfortunately, there is no way of finding the + * directory node who contains 'pathloc', however :-( + */ + do { + /* assume the generics have verified 'pathloc' to be + * a link... + */ + if ( !pathloc->ops->readlink_h ) { + errno = ENOTSUP; + goto cleanup; + } + + if ( pathloc->ops->readlink_h(pathloc, buf, LINKVAL_BUFLEN) ) { + goto cleanup; + } + +#if DEBUG & DEBUG_EVALPATH + fprintf(stderr, "link value is '%s'\n", buf); +#endif + + /* is the link value an absolute path ? */ + if ( DELIM != *buf ) { + /* NO; a relative path */ + + /* we must backup to the link's directory - we + * know only how to do that for NFS, however. + * In this special case, we can avoid recursion. + * Otherwise (i.e. if the link is on another FS), + * we must step into its eval_link_h(). + */ + if (locIsNfs(pathloc)) { + NfsNode node = pathloc->node_access; + int err; + + memcpy( &SERP_FILE(node), + &node->args.dir, + sizeof(node->args.dir) ); + + if (updateAttr(node, 1 /* force */)) + goto cleanup; + + if (SERP_ATTR(node).type != NFDIR) { + errno = ENOTDIR; + goto cleanup; + } + + pathloc->handlers = &nfs_dir_file_handlers; + + err = nfs_evalpath(buf, flags, pathloc); + + /* according to its semantics, + * nfs_evalpath cloned the node attached + * to pathloc. Hence we have to + * release the old one (referring to + * the link; the new clone has been + * updated and refers to the link _value_). + */ + nfsNodeDestroy(node); + + if (err) { + /* nfs_evalpath has set errno; + * pathloc->node_access has no + * valid node attached in this case + */ + rval = RVAL_ERR_BUT_DONT_FREENODE; + goto cleanup; + } + + } else { + if ( ! pathloc->ops->eval_link_h ) { + errno = ENOTSUP; + goto cleanup; + } + if (!pathloc->ops->eval_link_h(pathloc, flags)) { + /* FS is responsible for freeing its pathloc->node_access + * if necessary + */ + rval = RVAL_ERR_BUT_DONT_FREENODE; + goto cleanup; + } + } + } else { + /* link points to an absolute path '/xxx' */ + + /* release this node; filesystem_evaluate_path() will + * lookup a new one. + */ + rtems_filesystem_freenode(pathloc); + + if (rtems_filesystem_evaluate_path(buf, flags, pathloc, 1)) { + goto cleanup; + } + } + + if ( !pathloc->ops->node_type_h ) { + errno = ENOTSUP; + goto cleanup; + } + + type = pathloc->ops->node_type_h(pathloc); + + + /* I dont know what to do about hard links */ + } while ( RTEMS_FILESYSTEM_SYM_LINK == type ); + + rval = RVAL_OK; + +cleanup: + + free(buf); + + if (RVAL_ERR_AND_DO_FREENODE == rval) { + rtems_filesystem_freenode(pathloc); + return -1; + } + + return rval; +} + + +struct _rtems_filesystem_operations_table nfs_fs_ops = { + nfs_evalpath, /* MANDATORY */ + nfs_evalformake, /* MANDATORY; may set errno=ENOSYS and return -1 */ + nfs_link, /* OPTIONAL; may be NULL */ + nfs_unlink, /* OPTIONAL; may be NULL */ + nfs_node_type, /* OPTIONAL; may be NULL; BUG in mount - no test!! */ + nfs_mknod, /* OPTIONAL; may be NULL */ + nfs_chown, /* OPTIONAL; may be NULL */ + nfs_freenode, /* OPTIONAL; may be NULL; (release node_access) */ + nfs_mount, /* OPTIONAL; may be NULL */ + nfs_fsmount_me, /* OPTIONAL; may be NULL -- but this makes NO SENSE */ + nfs_unmount, /* OPTIONAL; may be NULL */ + nfs_fsunmount_me, /* OPTIONAL; may be NULL */ + nfs_utime, /* OPTIONAL; may be NULL */ + nfs_eval_link, /* OPTIONAL; may be NULL */ + nfs_symlink, /* OPTIONAL; may be NULL */ + nfs_readlink, /* OPTIONAL; may be NULL */ +}; + +/***************************************** + File Handlers + + NOTE: the FS generics expect a FS' + evalpath_h() to switch the + pathloc->handlers according + to the pathloc/node's file + type. + We currently have 'file' and + 'directory' handlers and very + few 'symlink' handlers. + + The handlers for each type are + implemented or #defined ZERO + in a 'nfs_file_xxx', + 'nfs_dir_xxx', 'nfs_link_xxx' + sequence below this point. + + In some cases, a common handler, + can be used for all file types. + It is then simply called + 'nfs_xxx'. + *****************************************/ + + +#if 0 +/* from rtems/libio.h for convenience */ +struct rtems_libio_tt { + rtems_driver_name_t *driver; + off_t size; /* size of file */ + off_t offset; /* current offset into file */ + unsigned32 flags; + rtems_filesystem_location_info_t pathinfo; + Objects_Id sem; + unsigned32 data0; /* private to "driver" */ + void *data1; /* ... */ + void *file_info; /* used by file handlers */ + rtems_filesystem_file_handlers_r *handlers; /* type specific handlers */ +}; +#endif + +/* stateless NFS protocol makes this trivial */ +static int nfs_file_open( + rtems_libio_t *iop, + const char *pathname, + unsigned32 flag, + unsigned32 mode +) +{ + iop->file_info = 0; + return 0; +} + +/* reading directories is not stateless; we must + * remember the last 'read' position, i.e. + * the server 'cookie'. We do manage this information + * attached to the iop->file_info. + */ +static int nfs_dir_open( + rtems_libio_t *iop, + const char *pathname, + unsigned32 flag, + unsigned32 mode +) +{ +NfsNode node = iop->pathinfo.node_access; +DirInfo di; + + /* create a readdirargs object and copy the file handle; + * attach to the file_info. + */ + + di = (DirInfo) malloc(sizeof(*di)); + iop->file_info = di; + + if ( !di ) { + errno = ENOMEM; + return -1; + } + + memcpy( &di->readdirargs.dir, + &SERP_FILE(node), + sizeof(di->readdirargs.dir) ); + + /* rewind cookie */ + memset( &di->readdirargs.cookie, + 0, + sizeof(di->readdirargs.cookie) ); + + di->eofreached = FALSE; + + return 0; +} + +#define nfs_link_open 0 + +static int nfs_file_close( + rtems_libio_t *iop +) +{ + return 0; +} + +static int nfs_dir_close( + rtems_libio_t *iop +) +{ + free(iop->file_info); + iop->file_info = 0; + return 0; +} + +#define nfs_link_close 0 + +static int nfs_file_read( + rtems_libio_t *iop, + void *buffer, + unsigned32 count +) +{ +readres rr; +NfsNode node = iop->pathinfo.node_access; +Nfs nfs = node->nfs; + + if (count > NFS_MAXDATA) + count = NFS_MAXDATA; + + SERP_ARGS(node).readarg.offset = iop->offset; + SERP_ARGS(node).readarg.count = count; + SERP_ARGS(node).readarg.totalcount = 0xdeadbeef; + + rr.readres_u.reply.data.data_val = buffer; + + if ( nfscall( nfs->server, + NFSPROC_READ, + xdr_readargs, &SERP_FILE(node), + xdr_readres, &rr) ) { + return -1; + } + + + if (NFS_OK != rr.status) { + rtems_set_errno_and_return_minus_one(rr.status); + } + +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr, + "Read %i (asked for %i) bytes from offset %i to 0x%08x\n", + rr.readres_u.reply.data.data_len, + count, + iop->offset, + rr.readres_u.reply.data.data_val); +#endif + + + return rr.readres_u.reply.data.data_len; +} + +/* this is called by readdir() / getdents() */ +static int nfs_dir_read( + rtems_libio_t *iop, + void *buffer, + unsigned32 count +) +{ +DirInfo di = iop->file_info; +RpcUdpServer server = ((Nfs)iop->pathinfo.mt_entry->fs_info)->server; + + if ( di->eofreached ) + return 0; + + di->ptr = di->buf = buffer; + + /* align + round down the buffer */ + count &= ~ (DIRENT_HEADER_SIZE - 1); + di->len = count; + +#if 0 + /* now estimate the number of entries we should ask for */ + count /= DIRENT_HEADER_SIZE + CONFIG_AVG_NAMLEN; + + /* estimate the encoded size that might take up */ + count *= dirres_entry_size + CONFIG_AVG_NAMLEN; +#else + /* integer arithmetics are better done the other way round */ + count *= dirres_entry_size + CONFIG_AVG_NAMLEN; + count /= DIRENT_HEADER_SIZE + CONFIG_AVG_NAMLEN; +#endif + + if (count > NFS_MAXDATA) + count = NFS_MAXDATA; + + di->readdirargs.count = count; + +#if DEBUG & DEBUG_READDIR + fprintf(stderr, + "Readdir: asking for %i XDR bytes, buffer is %i\n", + count, di->len); +#endif + + if ( nfscall( + server, + NFSPROC_READDIR, + xdr_readdirargs, &di->readdirargs, + xdr_dir_info, di) ) { + return -1; + } + + + if (NFS_OK != di->status) { + rtems_set_errno_and_return_minus_one(di->status); + } + + return (char*)di->ptr - (char*)buffer; +} + +#define nfs_link_read 0 + +static int nfs_file_write( + rtems_libio_t *iop, + const void *buffer, + unsigned32 count +) +{ +NfsNode node = iop->pathinfo.node_access; +Nfs nfs = node->nfs; +int e; + + if (count > NFS_MAXDATA) + count = NFS_MAXDATA; + + SERP_ARGS(node).writearg.beginoffset = 0xdeadbeef; + SERP_ARGS(node).writearg.offset = iop->offset; + SERP_ARGS(node).writearg.totalcount = 0xdeadbeef; + SERP_ARGS(node).writearg.data.data_len = count; + SERP_ARGS(node).writearg.data.data_val = (void*)buffer; + + /* write XDR buffer size will be chosen by nfscall based + * on the PROC specifier + */ + + if ( nfscall( nfs->server, + NFSPROC_WRITE, + xdr_writeargs, &SERP_FILE(node), + xdr_attrstat, &node->serporid) ) { + return -1; + } + + + if (NFS_OK != (e=node->serporid.status) ) { + /* try at least to recover the current attributes */ + updateAttr(node, 1 /* force */); + rtems_set_errno_and_return_minus_one(e); + } + + node->age = nowSeconds(); + + return count; +} + +#define nfs_dir_write 0 +#define nfs_link_write 0 + +/* IOCTL is unneeded/unsupported */ +#ifdef DECLARE_BODY +static int nfs_file_ioctl( + rtems_libio_t *iop, + unsigned32 command, + void *buffer +)DECLARE_BODY +#else +#define nfs_file_ioctl 0 +#define nfs_dir_ioctl 0 +#define nfs_link_ioctl 0 +#endif + +static int nfs_file_lseek( + rtems_libio_t *iop, + off_t length, + int whence +) +{ +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr, + "lseek to %i (length %i, whence %i)\n", + iop->offset, + length, + whence); +#endif + + /* this is particularly easy :-) */ + return iop->offset; +} + +static int nfs_dir_lseek( + rtems_libio_t *iop, + off_t length, + int whence +) +{ +DirInfo di = iop->file_info; + + /* we don't support anything other than + * rewinding + */ + if (SEEK_SET != whence || 0 != length) { + errno = ENOTSUP; + return -1; + } + + /* rewind cookie */ + memset( &di->readdirargs.cookie, + 0, + sizeof(di->readdirargs.cookie) ); + + di->eofreached = FALSE; + + return iop->offset; +} + +#define nfs_link_lseek 0 + +#if 0 /* structure types for reference */ +struct fattr { + ftype type; + u_int mode; + u_int nlink; + u_int uid; + u_int gid; + u_int size; + u_int blocksize; + u_int rdev; + u_int blocks; + u_int fsid; + u_int fileid; + nfstime atime; + nfstime mtime; + nfstime ctime; +}; + +struct stat +{ + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + /* SysV/sco doesn't have the rest... But Solaris, eabi does. */ +#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__) + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +#else + time_t st_atime; + long st_spare1; + time_t st_mtime; + long st_spare2; + time_t st_ctime; + long st_spare3; + long st_blksize; + long st_blocks; + long st_spare4[2]; +#endif +}; +#endif + +/* common for file/dir/link */ +static int nfs_fstat( + rtems_filesystem_location_info_t *loc, + struct stat *buf +) +{ +NfsNode node = loc->node_access; +fattr *fa = &SERP_ATTR(node); + + if (updateAttr(node, 0 /* only if old */)) { + return -1; + } + +/* done by caller + memset(buf, 0, sizeof(*buf)); + */ + + /* translate */ + + /* one of the branches hopefully is optimized away */ + if (sizeof(ino_t) < sizeof(u_int)) { + buf->st_dev = NFS_MAKE_DEV_T_INO_HACK((NfsNode)loc->node_access); + } else { + buf->st_dev = NFS_MAKE_DEV_T((NfsNode)loc->node_access); + } + buf->st_mode = fa->mode; + buf->st_nlink = fa->nlink; + buf->st_uid = fa->uid; + buf->st_gid = fa->gid; + buf->st_size = fa->size; + /* TODO: set to "preferred size" of this NFS client implementation */ + buf->st_blksize = fa->blocksize; + buf->st_rdev = fa->rdev; + buf->st_blocks = fa->blocks; + buf->st_ino = fa->fileid; + buf->st_atime = fa->atime.seconds; + buf->st_mtime = fa->mtime.seconds; + buf->st_ctime = fa->ctime.seconds; + +#if 0 /* NFS should return the modes */ + switch(fa->type) { + default: + case NFNON: + case NFBAD: + break; + + case NFSOCK: buf->st_mode |= S_IFSOCK; break; + case NFFIFO: buf->st_mode |= S_IFIFO; break; + case NFREG : buf->st_mode |= S_IFREG; break; + case NFDIR : buf->st_mode |= S_IFDIR; break; + case NFBLK : buf->st_mode |= S_IFBLK; break; + case NFCHR : buf->st_mode |= S_IFCHR; break; + case NFLNK : buf->st_mode |= S_IFLNK; break; + } +#endif + + return 0; +} + +/* a helper which does the real work for + * a couple of handlers (such as chmod, + * ftruncate or utime) + */ +static int +nfs_sattr(NfsNode node, sattr *arg, u_long mask) +{ + +rtems_clock_time_value now; +nfstime nfsnow, t; +int e; +u_int mode; + + if (updateAttr(node, 0 /* only if old */)) + return -1; + + rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE, &now); + + /* TODO: add rtems EPOCH - UNIX EPOCH seconds */ + nfsnow.seconds = now.seconds; + nfsnow.useconds = now.microseconds; + + /* merge permission bits into existing type bits */ + mode = SERP_ATTR(node).mode; + if (mask & SATTR_MODE) { + mode &= S_IFMT; + mode |= arg->mode & ~S_IFMT; + } + SERP_ARGS(node).sattrarg.attributes.mode = mode; + + SERP_ARGS(node).sattrarg.attributes.uid = + (mask & SATTR_UID) ? arg->uid : SERP_ATTR(node).uid; + + SERP_ARGS(node).sattrarg.attributes.gid = + (mask & SATTR_GID) ? arg->gid : SERP_ATTR(node).gid; + + SERP_ARGS(node).sattrarg.attributes.size = + (mask & SATTR_SIZE) ? arg->size : SERP_ATTR(node).size; + + if (mask & SATTR_ATIME) + t = arg->atime; + else if (mask & SATTR_TOUCHA) + t = nfsnow; + else + t = SERP_ATTR(node).atime; + SERP_ARGS(node).sattrarg.attributes.atime = t; + + if (mask & SATTR_ATIME) + t = arg->mtime; + else if (mask & SATTR_TOUCHA) + t = nfsnow; + else + t = SERP_ATTR(node).mtime; + SERP_ARGS(node).sattrarg.attributes.mtime = t; + + node->serporid.status = NFS_OK; + + if ( nfscall( node->nfs->server, + NFSPROC_SETATTR, + xdr_sattrargs, &SERP_FILE(node), + xdr_attrstat, &node->serporid) ) { +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr, + "nfs_sattr (mask 0x%08x): %s", + mask, + strerror(errno)); +#endif + return -1; + } + + if (NFS_OK != (e=node->serporid.status) ) { +#if DEBUG & DEBUG_SYSCALLS + fprintf(stderr,"nfs_sattr: %s\n",strerror(e)); +#endif + /* try at least to recover the current attributes */ + updateAttr(node, 1 /* force */); + rtems_set_errno_and_return_minus_one(e); + } + + node->age = nowSeconds(); + + return 0; +} + + +/* common for file/dir/link */ +static int nfs_fchmod( + rtems_filesystem_location_info_t *loc, + mode_t mode +) +{ +sattr arg; + + arg.mode = mode; + return nfs_sattr(loc->node_access, &arg, SATTR_MODE); + +} + +/* just set the size attribute to 'length' + * the server will take care of the rest :-) + */ +static int nfs_file_ftruncate( + rtems_libio_t *iop, + off_t length +) +{ +sattr arg; + + arg.size = length; + return nfs_sattr(iop->pathinfo.node_access, + &arg, + SATTR_SIZE | SATTR_TOUCH); +} + +#define nfs_dir_ftruncate 0 +#define nfs_link_ftruncate 0 + +/* not implemented */ +#ifdef DECLARE_BODY +static int nfs_file_fpathconf( + rtems_libio_t *iop, + int name +)DECLARE_BODY +#else +#define nfs_file_fpathconf 0 +#define nfs_dir_fpathconf 0 +#define nfs_link_fpathconf 0 +#endif + +/* unused */ +#ifdef DECLARE_BODY +static int nfs_file_fsync( + rtems_libio_t *iop +)DECLARE_BODY +#else +#define nfs_file_fsync 0 +#define nfs_dir_fsync 0 +#define nfs_link_fsync 0 +#endif + +/* unused */ +#ifdef DECLARE_BODY +static int nfs_file_fdatasync( + rtems_libio_t *iop +)DECLARE_BODY +#else +#define nfs_file_fdatasync 0 +#define nfs_dir_fdatasync 0 +#define nfs_link_fdatasync 0 +#endif + +/* unused */ +#ifdef DECLARE_BODY +static int nfs_file_fcntl( + int cmd, + rtems_libio_t *iop +)DECLARE_BODY +#else +#define nfs_file_fcntl 0 +#define nfs_dir_fcntl 0 +#define nfs_link_fcntl 0 +#endif + +/* files and symlinks are removed + * by the common nfs_unlink() routine. + * NFS has a different NFSPROC_RMDIR + * call, though... + */ +static int nfs_dir_rmnod( + rtems_filesystem_location_info_t *pathloc /* IN */ +) +{ + return nfs_do_unlink(pathloc, NFSPROC_RMDIR); +} + +/* the file handlers table */ +static +struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = { + nfs_file_open, /* OPTIONAL; may be NULL */ + nfs_file_close, /* OPTIONAL; may be NULL */ + nfs_file_read, /* OPTIONAL; may be NULL */ + nfs_file_write, /* OPTIONAL; may be NULL */ + nfs_file_ioctl, /* OPTIONAL; may be NULL */ + nfs_file_lseek, /* OPTIONAL; may be NULL */ + nfs_fstat, /* OPTIONAL; may be NULL */ + nfs_fchmod, /* OPTIONAL; may be NULL */ + nfs_file_ftruncate, /* OPTIONAL; may be NULL */ + nfs_file_fpathconf, /* OPTIONAL; may be NULL - UNUSED */ + nfs_file_fsync, /* OPTIONAL; may be NULL */ + nfs_file_fdatasync, /* OPTIONAL; may be NULL */ + nfs_file_fcntl, /* OPTIONAL; may be NULL */ + nfs_unlink, /* OPTIONAL; may be NULL */ +}; + +/* the directory handlers table */ +static +struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = { + nfs_dir_open, /* OPTIONAL; may be NULL */ + nfs_dir_close, /* OPTIONAL; may be NULL */ + nfs_dir_read, /* OPTIONAL; may be NULL */ + nfs_dir_write, /* OPTIONAL; may be NULL */ + nfs_dir_ioctl, /* OPTIONAL; may be NULL */ + nfs_dir_lseek, /* OPTIONAL; may be NULL */ + nfs_fstat, /* OPTIONAL; may be NULL */ + nfs_fchmod, /* OPTIONAL; may be NULL */ + nfs_dir_ftruncate, /* OPTIONAL; may be NULL */ + nfs_dir_fpathconf, /* OPTIONAL; may be NULL - UNUSED */ + nfs_dir_fsync, /* OPTIONAL; may be NULL */ + nfs_dir_fdatasync, /* OPTIONAL; may be NULL */ + nfs_dir_fcntl, /* OPTIONAL; may be NULL */ + nfs_dir_rmnod, /* OPTIONAL; may be NULL */ +}; + +/* the link handlers table */ +static +struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = { + nfs_link_open, /* OPTIONAL; may be NULL */ + nfs_link_close, /* OPTIONAL; may be NULL */ + nfs_link_read, /* OPTIONAL; may be NULL */ + nfs_link_write, /* OPTIONAL; may be NULL */ + nfs_link_ioctl, /* OPTIONAL; may be NULL */ + nfs_link_lseek, /* OPTIONAL; may be NULL */ + nfs_fstat, /* OPTIONAL; may be NULL */ + nfs_fchmod, /* OPTIONAL; may be NULL */ + nfs_link_ftruncate, /* OPTIONAL; may be NULL */ + nfs_link_fpathconf, /* OPTIONAL; may be NULL - UNUSED */ + nfs_link_fsync, /* OPTIONAL; may be NULL */ + nfs_link_fdatasync, /* OPTIONAL; may be NULL */ + nfs_link_fcntl, /* OPTIONAL; may be NULL */ + nfs_unlink, /* OPTIONAL; may be NULL */ +}; + +/* we need a dummy driver entry table to get a + * major number from the system + */ +static +rtems_device_driver nfs_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + /* we don't really use this routine because + * we cannot supply an argument (contrary + * to what the 'arg' parameter suggests - it + * is always set to 0 by the generics :-() + * and because we don't want the user to + * have to deal with the major number (which + * OTOH is something WE are interested in. The + * only reason for using this API was getting + * a major number, after all). + * + * Something must be present, however, to + * reserve a slot in the driver table. + */ + return RTEMS_SUCCESSFUL; +} + +static rtems_driver_address_table drvNfs = { + nfs_initialize, + 0, /* open */ + 0, /* close */ + 0, /* read */ + 0, /* write */ + 0 /* control */ +}; + +/* Dump a list of the currently mounted NFS to a file */ +int +nfsMountsShow(FILE *f) +{ +char *mntpt = 0; +Nfs nfs; + + if (!f) + f = stdout; + + if ( !(mntpt=malloc(MAXPATHLEN)) ) { + fprintf(stderr,"nfsMountsShow(): no memory\n"); + return -1; + } + + fprintf(f,"Currently Mounted NFS:\n"); + + LOCK(nfsGlob.llock); + + for (nfs = nfsGlob.mounted_fs; nfs; nfs=nfs->next) { + fprintf(f,"%s on ", nfs->mt_entry->dev); + if (rtems_filesystem_resolve_location(mntpt, MAXPATHLEN, &nfs->mt_entry->mt_fs_root)) + fprintf(f,"\n"); + else + fprintf(f,"%s\n",mntpt); + } + + UNLOCK(nfsGlob.llock); + + free(mntpt); + return 0; +} + +/* convenience wrapper + * + * NOTE: this routine calls NON-REENTRANT + * gethostbyname() if the host is + * not in 'dot' notation. + */ +int +nfsMount(char *uidhost, char *path, char *mntpoint) +{ +rtems_filesystem_mount_table_entry_t *mtab; +struct stat st; +int devl; +char *host; +int rval = -1; +char *dev = 0; + + if (!uidhost || !path || !mntpoint) { + fprintf(stderr,"usage: nfsMount(""[uid.gid@]host"",""path"",""mountpoint"")\n"); + nfsMountsShow(stderr); + return -1; + } + + if ( !(dev = malloc((devl=strlen(uidhost) + 20 + strlen(path)+1))) ) { + fprintf(stderr,"nfsMount: out of memory\n"); + return -1; + } + + /* Try to create the mount point if nonexistent */ + if (stat(mntpoint, &st)) { + if (ENOENT != errno) { + perror("nfsMount trying to create mount point - stat failed"); + goto cleanup; + } else if (mkdir(mntpoint,0777)) { + perror("nfsMount trying to create mount point"); + goto cleanup; + } + } + + if ( !(host=strchr(uidhost,UIDSEP)) ) { + host = uidhost; + } else { + host++; + } + + if (isdigit(*host)) { + /* avoid using gethostbyname */ + sprintf(dev,"%s:%s",uidhost,path); + } else { + struct hostent *h; + + /* copy the uid part (hostname will be + * overwritten) + */ + strcpy(dev, uidhost); + + /* NOTE NOTE NOTE: gethostbyname is NOT + * thread safe. This is UGLY + */ + +/* BEGIN OF NON-THREAD SAFE REGION */ + + h = gethostbyname(host); + + if ( !h || + !inet_ntop( AF_INET, + (struct in_addr*)h->h_addr_list[0], + dev + (host - uidhost), + devl - (host - uidhost) ) + ) { + fprintf(stderr,"nfsMount: host '%s' not found\n",host); + goto cleanup; + } + +/* END OF NON-THREAD SAFE REGION */ + + /* append ':' */ + strcat(dev,":"); + strcat(dev,path); + } + + printf("Trying to mount %s on %s\n",dev,mntpoint); + + if (mount(&mtab, + &nfs_fs_ops, + RTEMS_FILESYSTEM_READ_WRITE, + dev, + mntpoint)) { + perror("nfsMount - mount"); + goto cleanup; + } + + rval = 0; + +cleanup: + free(dev); + return rval; +} + +/* HERE COMES A REALLY UGLY HACK */ + +/* This is stupid; it is _very_ hard to find the path + * leading to a rtems_filesystem_location_info_t node :-( + * The only easy way is making the location the current + * directory and issue a getcwd(). + * However, since we don't want to tamper with the + * current directory, we must create a separate + * task to do the job for us - sigh. + */ + +typedef struct ResolvePathArgRec_ { + rtems_filesystem_location_info_t *loc; /* IN: location to resolve */ + char *buf; /* IN/OUT: buffer where to put the path */ + int len; /* IN: buffer length */ + rtems_id sync; /* IN: synchronization */ + rtems_status_code status; /* OUT: result */ +} ResolvePathArgRec, *ResolvePathArg; + +static void +resolve_path(rtems_task_argument arg) +{ +ResolvePathArg rpa = (ResolvePathArg)arg; +rtems_filesystem_location_info_t old; + + /* IMPORTANT: let the helper task have its own libio environment (i.e. cwd) */ + if (RTEMS_SUCCESSFUL == (rpa->status = rtems_libio_set_private_env())) { + + old = rtems_filesystem_current; + + rtems_filesystem_current = *(rpa->loc); + + if ( !getcwd(rpa->buf, rpa->len) ) + rpa->status = RTEMS_UNSATISFIED; + + /* must restore the cwd because 'freenode' will be called on it */ + rtems_filesystem_current = old; + } + rtems_semaphore_release(rpa->sync); + rtems_task_delete(RTEMS_SELF); +} + + +/* a utility routine to find the path leading to a + * rtems_filesystem_location_info_t node + * + * INPUT: 'loc' and a buffer 'buf' (length 'len') to hold the + * path. + * OUTPUT: path copied into 'buf' + * + * RETURNS: 0 on success, RTEMS error code on error. + */ +rtems_status_code +rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc) +{ +ResolvePathArgRec arg; +rtems_id tid = 0; +rtems_task_priority pri; +rtems_status_code status; + + arg.loc = loc; + arg.buf = buf; + arg.len = len; + arg.sync = 0; + + status = rtems_semaphore_create( + rtems_build_name('r','e','s','s'), + 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &arg.sync); + + if (RTEMS_SUCCESSFUL != status) + goto cleanup; + + rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &pri); + + status = rtems_task_create( + rtems_build_name('r','e','s','s'), + pri, + RTEMS_MINIMUM_STACK_SIZE + 50000, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &tid); + + if (RTEMS_SUCCESSFUL != status) + goto cleanup; + + status = rtems_task_start(tid, resolve_path, (rtems_task_argument)&arg); + + if (RTEMS_SUCCESSFUL != status) { + rtems_task_delete(tid); + goto cleanup; + } + + + /* synchronize with the helper task */ + rtems_semaphore_obtain(arg.sync, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + + status = arg.status; + +cleanup: + if (arg.sync) + rtems_semaphore_delete(arg.sync); + + return status; +} diff --git a/rtemsNfs/src/nfs.modini.c b/rtemsNfs/src/nfs.modini.c new file mode 100644 index 0000000..834102e --- /dev/null +++ b/rtemsNfs/src/nfs.modini.c @@ -0,0 +1,27 @@ +#include "librtemsNfs.h" + +/* CEXP dynamic loader support */ + +void +_cexpModuleInitialize(void *mod) +{ +#if defined(DEBUG) + /* print load address (in case we crash while initializing) */ +unsigned lr; + __asm__ __volatile__( + " bl thisis_loaded_at \n" + "thisis_loaded_at: \n" + " mflr %0 \n" + : "=r"(lr) ::"lr"); + printf("thisis_loaded_at: 0x%08x\n",lr); +#endif + nfsInit(0,0); +} + +int +_cexpModuleFinalize(void *mod) +{ + return nfsCleanup(); +} + + diff --git a/rtemsNfs/src/rpcio.c b/rtemsNfs/src/rpcio.c new file mode 100644 index 0000000..667ba6a --- /dev/null +++ b/rtemsNfs/src/rpcio.c @@ -0,0 +1,1717 @@ +/* $Id$ */ + +/* RPC multiplexor for a multitasking environment */ + +/* Author: Till Straumann , 2002 */ + +/* This code funnels arbitrary task's UDP/RPC requests + * through one socket to arbitrary servers. + * The replies are gathered and dispatched to the + * requestors. + * One task handles all the sending and receiving + * work including retries. + * It is up to the requestor, however, to do + * the XDR encoding of the arguments / decoding + * of the results (except for the RPC header which + * is handled by the daemon). + * + * Copyright 2002, Stanford University and + * Till Straumann + * + * Stanford Notice + * *************** + * + * Acknowledgement of sponsorship + * * * * * * * * * * * * * * * * * + * This software was produced by the Stanford Linear Accelerator Center, + * Stanford University, under Contract DE-AC03-76SFO0515 with the Department + * of Energy. + * + * Government disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, + * or assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately + * owned rights. + * + * Stanford disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * This product is subject to the EPICS open license + * - - - - - - - - - - - - - - - - - - - - - - - - - + * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php + * for more information. + * + * Maintenance of notice + * - - - - - - - - - - - + * In the interest of clarity regarding the origin and status of this + * software, Stanford University requests that any recipient of it maintain + * this notice affixed to any distribution by the recipient that contains a + * copy or derivative of this software. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rpcio.h" + +/****************************************************************/ +/* CONFIGURABLE PARAMETERS */ +/****************************************************************/ + +#define MBUF_RX /* If defined: use mbuf XDR stream for + * decoding directly out of mbufs + * Otherwise, the regular 'recvfrom()' + * interface will be used involving an + * extra buffer allocation + copy step. + */ + +#define MBUF_TX /* If defined: avoid copying data when + * sending. Instead, use a wrapper to + * 'sosend()' which will point an MBUF + * directly to our buffer space. + * Note that the BSD stack does not copy + * data when fragmenting packets - it + * merely uses an mbuf chain pointing + * into different areas of the data. + * + * If undefined, the regular 'sendto()' + * interface is used. + */ + +/* daemon task parameters */ +#define RPCIOD_STACK 10000 +#define RPCIOD_PRIO 50 + +/* depth of the message queue for sending + * RPC requests to the daemon + */ +#define RPCIOD_QDEPTH 20 + +/* Maximum retry limit for retransmission */ +#define RPCIOD_RETX_CAP_S 3 /* seconds */ + +/* Default timeout for RPC calls */ +#define RPCIOD_DEFAULT_TIMEOUT (&_rpc_default_timeout) +static struct timeval _rpc_default_timeout = { 10 /* secs */, 0 /* usecs */ }; + +/* how many times should we try to resend a failed + * transaction with refreshed AUTHs + */ +#define RPCIOD_REFRESH 2 + +/* Events we are using; the RPC_EVENT + * MUST NOT be used by any application + * thread doing RPC IO (e.g. NFS) + */ +#define RTEMS_RPC_EVENT RTEMS_EVENT_30 /* THE event used by RPCIO. Every task doing + * RPC IO will receive this - hence it is + * RESERVED + */ +#define RPCIOD_RX_EVENT RTEMS_EVENT_1 /* Events the RPCIOD is using/waiting for */ +#define RPCIOD_TX_EVENT RTEMS_EVENT_2 +#define RPCIOD_KILL_EVENT RTEMS_EVENT_3 /* send to the daemon to kill it */ + +#define LD_XACT_HASH 8 /* ld of the size of the transaction hash table */ + + +/* Debugging Flags */ + +/* NOTE: defining DEBUG 0 leaves some 'assert()' paranoia checks + * but produces no output + */ + +#define DEBUG_TRACE_XACT (1<<0) +#define DEBUG_EVENTS (1<<1) +#define DEBUG_MALLOC (1<<2) +#define DEBUG_TIMEOUT (1<<3) +#define DEBUG_PACKLOSS (1<<4) /* This introduces random, artificial packet losses to test retransmission */ + +#define DEBUG_PACKLOSS_FRACT (0xffffffff/10) + +/* USE PARENTHESIS WHEN 'or'ing MULTIPLE FLAGS: (DEBUG_XX | DEBUG_YY) */ +#define DEBUG (0) + +/****************************************************************/ +/* END OF CONFIGURABLE SECTION */ +/****************************************************************/ + +/* prevent rollover of our timers by readjusting the epoch on the fly */ +#if (DEBUG) & DEBUG_TIMEOUT +#define RPCIOD_EPOCH_SECS 10 +#else +#define RPCIOD_EPOCH_SECS 10000 +#endif + +#ifdef DEBUG +#define ASSERT(arg) assert(arg) +#else +#define ASSERT(arg) if (arg) +#endif + +/****************************************************************/ +/* MACROS */ +/****************************************************************/ + + +#define XACT_HASHS (1<<(LD_XACT_HASH)) /* the hash table size derived from the ld */ +#define XACT_HASH_MSK ((XACT_HASHS)-1) /* mask to extract the hash index from a RPC-XID */ + + +#define MU_LOCK(mutex) do { \ + assert( \ + RTEMS_SUCCESSFUL == \ + rtems_semaphore_obtain( \ + (mutex), \ + RTEMS_WAIT, \ + RTEMS_NO_TIMEOUT \ + ) ); \ + } while(0) + +#define MU_UNLOCK(mutex) do { \ + assert( \ + RTEMS_SUCCESSFUL == \ + rtems_semaphore_release( \ + (mutex) \ + ) ); \ + } while(0) + +#define MU_CREAT(pmutex) do { \ + assert( \ + RTEMS_SUCCESSFUL == \ + rtems_semaphore_create( \ + rtems_build_name( \ + 'R','P','C','l' \ + ), \ + 1, \ + MUTEX_ATTRIBUTES, \ + 0, \ + (pmutex)) ); \ + } while (0) + + +#define MU_DESTROY(mutex) do { \ + assert( \ + RTEMS_SUCCESSFUL == \ + rtems_semaphore_delete( \ + mutex \ + ) ); \ + } while (0) + +#define MUTEX_ATTRIBUTES (RTEMS_LOCAL | \ + RTEMS_PRIORITY | \ + RTEMS_INHERIT_PRIORITY | \ + RTEMS_BINARY_SEMAPHORE) + +#define FIRST_ATTEMPT 0x88888888 /* some time that is never reached */ + +/****************************************************************/ +/* TYPE DEFINITIONS */ +/****************************************************************/ + +typedef rtems_interval TimeoutT; + +/* 100000th implementation of a doubly linked list; + * since only one thread is looking at these, + * we need no locking + */ +typedef struct ListNodeRec_ { + struct ListNodeRec_ *next, *prev; +} ListNodeRec, *ListNode; + + +/* Structure representing an RPC server */ +typedef struct RpcUdpServerRec_ { + RpcUdpServer next; /* linked list of all servers; protected by hlock */ + struct sockaddr_in addr; + AUTH *auth; + rtems_id authlock; /* must MUTEX the auth object - it's not clear + * what is better: + * 1 having one (MUTEXed) auth per server + * who is shared among all transactions + * using that server + * 2 maintaining an AUTH per transaction + * (there are then other options: manage + * XACT pools on a per-server basis instead + * of associating a server with a XACT when + * sending) + * experience will show if the current (1) + * approach has to be changed. + */ + TimeoutT retry_period; /* dynamically adjusted retry period + * (based on packet roundtrip time) + */ + /* STATISTICS */ + unsigned long retrans; /* how many retries were issued by this server */ + unsigned long requests; /* how many requests have been sent */ + unsigned long timeouts; /* how many requests have timed out */ + unsigned long errors; /* how many errors have occurred (other than timeouts) */ + char name[20]; /* server's address in IP 'dot' notation */ +} RpcUdpServerRec; + +typedef union RpcBufU_ { + u_long xid; + char buf[1]; +} RpcBufU, *RpcBuf; + +/* RX Buffer implementation; this is either + * an MBUF chain (MBUF_RX configuration) + * or a buffer allocated from the heap + * where recvfrom copies the (encoded) reply + * to. The XDR routines the copy/decode + * it into the user's data structures. + */ +#ifdef MBUF_RX +typedef struct mbuf * RxBuf; /* an MBUF chain */ +static void bufFree(struct mbuf **m); +#define XID(ibuf) (*(mtod((ibuf), u_long *))) +extern void xdrmbuf_create(XDR *, struct mbuf *, enum xdr_op); +#else +typedef RpcBuf RxBuf; +#define bufFree(b) do { MY_FREE(*(b)); *(b)=0; } while(0) +#define XID(ibuf) ((ibuf)->xid) +#endif + +/* A RPC 'transaction' consisting + * of server and requestor information, + * buffer space and an XDR object + * (for encoding arguments). + */ +typedef struct RpcUdpXactRec_ { + ListNodeRec node; /* so we can put XACTs on a list */ + RpcUdpServer server; /* server this XACT goes to */ + long lifetime; /* during the lifetime, retry attempts are made */ + long tolive; /* lifetime timer */ + struct rpc_err status; /* RPC reply error status */ + long age; /* age info; needed to manage retransmission */ + long trip; /* record round trip time in ticks */ + rtems_id requestor; /* the task waiting for this XACT to complete */ + RpcUdpXactPool pool; /* if this XACT belong to a pool, this is it */ + XDR xdrs; /* argument encoder stream */ + int xdrpos; /* stream position after the (permanent) header */ + xdrproc_t xres; /* reply decoder proc - TODO needn't be here */ + caddr_t pres; /* reply decoded obj - TODO needn't be here */ +#ifndef MBUF_RX + int ibufsize; /* size of the ibuf (bytes) */ +#endif +#ifdef MBUF_TX + int refcnt; /* mbuf external storage reference count */ +#endif + int obufsize; /* size of the obuf (bytes) */ + RxBuf ibuf; /* pointer to input buffer assigned by daemon */ + RpcBufU obuf; /* output buffer (encoded args) APPENDED HERE */ +} RpcUdpXactRec; + +typedef struct RpcUdpXactPoolRec_ { + rtems_id box; + int prog; + int version; + int xactSize; +} RpcUdpXactPoolRec; + +/* a global hash table where all 'living' transaction + * objects are registered. + * A number of bits in a transaction's XID maps 1:1 to + * an index in this table. Hence, the XACT matching + * an RPC/UDP reply packet can quickly be found + * The size of this table imposes a hard limit on the + * number of all created transactions in the system. + */ +static RpcUdpXact xactHashTbl[XACT_HASHS]={0}; + +/* forward declarations */ +static RpcUdpXact +sockRcv(void); + +static void +rpcio_daemon(rtems_task_argument); + +#ifdef MBUF_TX +ssize_t +sendto_nocpy ( + int s, + const void *buf, size_t buflen, + int flags, + const struct sockaddr *toaddr, int tolen, + void *closure, + void (*freeproc)(caddr_t, u_int), + void (*refproc)(caddr_t, u_int) +); +static void paranoia_free(caddr_t closure, u_int size); +static void paranoia_ref (caddr_t closure, u_int size); +#define SENDTO sendto_nocpy +#else +#define SENDTO sendto +#endif + +static RpcUdpServer rpcUdpServers = 0; /* linked list of all servers; protected by llock */ + +static int ourSock = -1; /* the socket we are using for communication */ +static rtems_id rpciod = 0; /* task id of the RPC daemon */ +static rtems_id msgQ = 0; /* message queue where the daemon picks up + * requests + */ +static rtems_id llock = 0; /* MUTEX protecting the server list */ +static rtems_id hlock = 0; /* MUTEX protecting the hash table and the list of servers */ +static rtems_id fini = 0; /* a synchronization semaphore we use during + * module cleanup / driver unloading + */ +static rtems_interval ticksPerSec; /* cached system clock rate (WHO IS ASSUMED NOT + * TO CHANGE) + */ +#if (DEBUG) & DEBUG_MALLOC +/* malloc wrappers for debugging */ +static int nibufs = 0; + +static inline void *MY_MALLOC(int s) +{ + if (s) { + void *rval; + MU_LOCK(hlock); + assert(nibufs++ < 2000); + MU_UNLOCK(hlock); + assert(rval = malloc(s)); + return rval; + } + return 0; +} + +static inline void *MY_CALLOC(int n, int s) +{ + if (s) { + void *rval; + MU_LOCK(hlock); + assert(nibufs++ < 2000); + MU_UNLOCK(hlock); + assert(rval = calloc(n,s)); + return rval; + } + return 0; +} + + +static inline void MY_FREE(void *p) +{ + if (p) { + MU_LOCK(hlock); + nibufs--; + MU_UNLOCK(hlock); + free(p); + } +} +#else +#define MY_MALLOC malloc +#define MY_CALLOC calloc +#define MY_FREE free +#endif + +static inline bool_t +locked_marshal(RpcUdpServer s, XDR *xdrs) +{ +bool_t rval; + MU_LOCK(s->authlock); + rval = AUTH_MARSHALL(s->auth, xdrs); + MU_UNLOCK(s->authlock); + return rval; +} + +/* Locked operations on a server's auth object */ +static inline bool_t +locked_validate(RpcUdpServer s, struct opaque_auth *v) +{ +bool_t rval; + MU_LOCK(s->authlock); + rval = AUTH_VALIDATE(s->auth, v); + MU_UNLOCK(s->authlock); + return rval; +} + +static inline bool_t +locked_refresh(RpcUdpServer s) +{ +bool_t rval; + MU_LOCK(s->authlock); + rval = AUTH_REFRESH(s->auth); + MU_UNLOCK(s->authlock); + return rval; +} + +/* Create a server object + * + */ +enum clnt_stat +rpcUdpServerCreate( + struct sockaddr_in *paddr, + int prog, + int vers, + u_long uid, + u_long gid, + RpcUdpServer *psrv + ) +{ +RpcUdpServer rval; +u_short port; +char hname[MAX_MACHINE_NAME + 1]; +int theuid, thegid; +int thegids[NGRPS]; +gid_t gids[NGROUPS]; +int len,i; +AUTH *auth; +enum clnt_stat pmap_err; +struct pmap pmaparg; + + if ( gethostname(hname, MAX_MACHINE_NAME) ) { + fprintf(stderr, + "RPCIO - error: I have no hostname ?? (%s)\n", + strerror(errno)); + return RPC_UNKNOWNHOST; + } + + if ( (len = getgroups(NGROUPS, gids) < 0 ) ) { + fprintf(stderr, + "RPCIO - error: I unable to get group ids (%s)\n", + strerror(errno)); + return RPC_FAILED; + } + + if ( len > NGRPS ) + len = NGRPS; + + for (i=0; isin_port) { + + paddr->sin_port = htons(PMAPPORT); + + pmaparg.pm_prog = prog; + pmaparg.pm_vers = vers; + pmaparg.pm_prot = IPPROTO_UDP; + pmaparg.pm_port = 0; /* not needed or used */ + + + /* dont use non-reentrant pmap_getport ! */ + + pmap_err = rpcUdpCallRp( + paddr, + PMAPPROG, + PMAPVERS, + PMAPPROC_GETPORT, + xdr_pmap, + &pmaparg, + xdr_u_short, + &port, + uid, + gid, + 0); + + if ( RPC_SUCCESS != pmap_err ) { + paddr->sin_port = 0; + return pmap_err; + } + + paddr->sin_port = htons(port); + } + + if (0==paddr->sin_port) { + return RPC_PROGNOTREGISTERED; + } + + rval = (RpcUdpServer)MY_MALLOC(sizeof(*rval)); + memset(rval, 0, sizeof(*rval)); + + if (!inet_ntop(AF_INET, &paddr->sin_addr, rval->name, sizeof(rval->name))) + sprintf(rval->name,"?.?.?.?"); + rval->addr = *paddr; + + /* start with a long retransmission interval - it + * will be adapted dynamically + */ + rval->retry_period = RPCIOD_RETX_CAP_S * ticksPerSec; + + rval->auth = auth; + + MU_CREAT( &rval->authlock ); + + /* link into list */ + MU_LOCK( llock ); + rval->next = rpcUdpServers; + rpcUdpServers = rval; + MU_UNLOCK( llock ); + + *psrv = rval; + return RPC_SUCCESS; +} + +void +rpcUdpServerDestroy(RpcUdpServer s) +{ +RpcUdpServer prev; + if (!s) + return; + /* we should probably verify (but how?) that nobody + * (at least: no outstanding XACTs) is using this + * server; + */ + + /* remove from server list */ + MU_LOCK(llock); + prev = rpcUdpServers; + if ( s == prev ) { + rpcUdpServers = s->next; + } else { + for ( ; prev ; prev = prev->next) { + if (prev->next == s) { + prev->next = s->next; + break; + } + } + } + MU_UNLOCK(llock); + + /* MUST have found it */ + assert(prev); + + auth_destroy(s->auth); + + MU_DESTROY(s->authlock); + MY_FREE(s); +} + +int +rpcUdpStats(FILE *f) +{ +RpcUdpServer s; + + if (!f) f = stdout; + + fprintf(f,"RPCIOD statistics:\n"); + + MU_LOCK(llock); + for (s = rpcUdpServers; s; s=s->next) { + fprintf(f,"\nServer -- %s:\n", s->name); + fprintf(f," requests sent: %10ld, retransmitted: %10ld\n", + s->requests, s->retrans); + fprintf(f," timed out: %10ld, send errors: %10ld\n", + s->timeouts, s->errors); + fprintf(f," current retransmission interval: %dms\n", + s->retry_period * 1000 / ticksPerSec ); + } + MU_UNLOCK(llock); + + return 0; +} + +RpcUdpXact +rpcUdpXactCreate( + u_long program, + u_long version, + u_long size + ) +{ +RpcUdpXact rval=0; +struct rpc_msg header; +register int i,j; + + if (!size) + size = UDPMSGSIZE; + /* word align */ + size = (size + 3) & ~3; + + rval = (RpcUdpXact)MY_CALLOC(1,sizeof(*rval) - sizeof(rval->obuf) + size); + + if (rval) { + + header.rm_xid = 0; + header.rm_direction = CALL; + header.rm_call.cb_rpcvers = RPC_MSG_VERSION; + header.rm_call.cb_prog = program; + header.rm_call.cb_vers = version; + xdrmem_create(&(rval->xdrs), rval->obuf.buf, size, XDR_ENCODE); + + if (!xdr_callhdr(&(rval->xdrs), &header)) { + MY_FREE(rval); + return 0; + } + /* pick a free table slot and initialize the XID */ + rval->obuf.xid = time(0) ^ (unsigned long)rval; + MU_LOCK(hlock); + i=j=(rval->obuf.xid & XACT_HASH_MSK); + if (msgQ) { + /* if there's no message queue, refuse to + * give them transactions; we might be in the process to + * go away... + */ + do { + i=(i+1) & XACT_HASH_MSK; /* cheap modulo */ + if (!xactHashTbl[i]) { +#if (DEBUG) & DEBUG_TRACE_XACT + fprintf(stderr,"RPCIO: entering index %i, val %x\n",i,rval); +#endif + xactHashTbl[i]=rval; + j=-1; + break; + } + } while (i!=j); + } + MU_UNLOCK(hlock); + if (i==j) { + XDR_DESTROY(&rval->xdrs); + MY_FREE(rval); + return 0; + } + rval->obuf.xid = (rval->obuf.xid << LD_XACT_HASH) | i; + rval->xdrpos = XDR_GETPOS(&(rval->xdrs)); + rval->obufsize = size; + } + return rval; +} + +void +rpcUdpXactDestroy(RpcUdpXact xact) +{ +int i = xact->obuf.xid & XACT_HASH_MSK; + +#if (DEBUG) & DEBUG_TRACE_XACT + fprintf(stderr,"RPCIO: removing index %i, val %x\n",i,xact); +#endif + + ASSERT( xactHashTbl[i]==xact ); + + MU_LOCK(hlock); + xactHashTbl[i]=0; + MU_UNLOCK(hlock); + + bufFree(&xact->ibuf); + + XDR_DESTROY(&xact->xdrs); + MY_FREE(xact); +} + + + +/* Send a transaction, i.e. enqueue it to the + * RPC daemon who will actually send it. + */ +enum clnt_stat +rpcUdpSend( + RpcUdpXact xact, + RpcUdpServer srvr, + struct timeval *timeout, + u_long proc, + xdrproc_t xres, caddr_t pres, + xdrproc_t xargs, caddr_t pargs, + ... + ) +{ +register XDR *xdrs; +unsigned long ms; +va_list ap; + + va_start(ap,pargs); + + if (!timeout) + timeout = RPCIOD_DEFAULT_TIMEOUT; + + ms = 1000 * timeout->tv_sec + timeout->tv_usec/1000; + + xact->lifetime = ms * ticksPerSec / 1000; +#if (DEBUG) & DEBUG_TIMEOUT + { + static int once=0; + if (!once++) { + fprintf(stderr, + "Initial lifetime: %i (ticks)\n", + xact->lifetime); + } + } +#endif + + xact->tolive = xact->lifetime; + + xact->xres = xres; + xact->pres = pres; + xact->server = srvr; + + xdrs = &xact->xdrs; + xdrs->x_op = XDR_ENCODE; + /* increment transaction ID */ + xact->obuf.xid += XACT_HASHS; + XDR_SETPOS(xdrs, xact->xdrpos); + if ( !XDR_PUTLONG(xdrs,&proc) || !locked_marshal(srvr, xdrs) || + !xargs(xdrs, pargs) ) { + va_end(ap); + return(xact->status.re_status=RPC_CANTENCODEARGS); + } + while ((xargs=va_arg(ap,xdrproc_t))) { + if (!xargs(xdrs, va_arg(ap,caddr_t))) + va_end(ap); + return(xact->status.re_status=RPC_CANTENCODEARGS); + } + + va_end(ap); + + rtems_task_ident(RTEMS_SELF, RTEMS_WHO_AM_I, &xact->requestor); + if ( rtems_message_queue_send( msgQ, &xact, sizeof(xact)) ) { + return RPC_CANTSEND; + } + /* wakeup the rpciod */ + ASSERT( RTEMS_SUCCESSFUL==rtems_event_send(rpciod, RPCIOD_TX_EVENT) ); + + return RPC_SUCCESS; +} + +/* Block for the RPC reply to an outstanding + * transaction. + * The caller is woken by the RPC daemon either + * upon reception of the reply or on timeout. + */ +enum clnt_stat +rpcUdpRcv(RpcUdpXact xact) +{ +int refresh; +XDR reply_xdrs; +struct rpc_msg reply_msg; +rtems_event_set gotEvents; + + refresh = 0; + + do { + + /* block for the reply */ + ASSERT( RTEMS_SUCCESSFUL == + rtems_event_receive( + RTEMS_RPC_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, + &gotEvents) ); + + if (xact->status.re_status) { +#ifdef MBUF_RX + /* add paranoia */ + ASSERT( !xact->ibuf ); +#endif + return xact->status.re_status; + } + +#ifdef MBUF_RX + xdrmbuf_create(&reply_xdrs, xact->ibuf, XDR_DECODE); +#else + xdrmem_create(&reply_xdrs, xact->ibuf->buf, xact->ibufsize, XDR_DECODE); +#endif + + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = xact->pres; + reply_msg.acpted_rply.ar_results.proc = xact->xres; + + if (xdr_replymsg(&reply_xdrs, &reply_msg)) { + /* OK */ + _seterr_reply(&reply_msg, &xact->status); + if (RPC_SUCCESS == xact->status.re_status) { + if ( !locked_validate(xact->server, + &reply_msg.acpted_rply.ar_verf) ) { + xact->status.re_status = RPC_AUTHERROR; + xact->status.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base) { + reply_xdrs.x_op = XDR_FREE; + xdr_opaque_auth(&reply_xdrs, &reply_msg.acpted_rply.ar_verf); + } + refresh = 0; + } else { + /* should we try to refresh our credentials ? */ + if ( !refresh ) { + /* had never tried before */ + refresh = RPCIOD_REFRESH; + } + } + } else { + reply_xdrs.x_op = XDR_FREE; + xdr_replymsg(&reply_xdrs, &reply_msg); + xact->status.re_status = RPC_CANTDECODERES; + } + XDR_DESTROY(&reply_xdrs); + + bufFree(&xact->ibuf); + +#ifndef MBUF_RX + xact->ibufsize = 0; +#endif + + if (refresh && locked_refresh(xact->server)) { + rtems_task_ident(RTEMS_SELF, RTEMS_WHO_AM_I, &xact->requestor); + if ( rtems_message_queue_send(msgQ, &xact, sizeof(xact)) ) { + return RPC_CANTSEND; + } + /* wakeup the rpciod */ + fprintf(stderr,"RPCIO INFO: refreshing my AUTH\n"); + ASSERT( RTEMS_SUCCESSFUL==rtems_event_send(rpciod, RPCIOD_TX_EVENT) ); + } + + } while ( 0 && refresh-- > 0 ); + + return xact->status.re_status; +} + + +/* On RTEMS, I'm told to avoid select(); this seems to + * be more efficient + */ +static void +rxWakeupCB(struct socket *sock, caddr_t arg) +{ +rtems_event_send((rtems_id)arg, RPCIOD_RX_EVENT); +} + +int +rpcUdpInit(void) +{ +int noblock = 1; +struct sockwakeup wkup; + + fprintf(stderr,"This is RTEMS-RPCIOD Release $Name$\n"); + fprintf(stderr,"($Id$)\n\n"); + fprintf(stderr,"Till Straumann, Stanford/SLAC/SSRL 2002\n"); + fprintf(stderr,"See LICENSE file for licensing info\n"); + + if (ourSock < 0) { + ourSock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (ourSock>=0) { + bindresvport(ourSock,(struct sockaddr_in*)0); + assert( 0==ioctl(ourSock, FIONBIO, (char*)&noblock) ); + /* assume nobody tampers with the clock !! */ + assert( RTEMS_SUCCESSFUL == rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_PER_SECOND, + &ticksPerSec)); + MU_CREAT( &hlock ); + MU_CREAT( &llock ); + + assert( RTEMS_SUCCESSFUL == rtems_task_create( + rtems_build_name('R','P','C','d'), + RPCIOD_PRIO, + RPCIOD_STACK, + RTEMS_DEFAULT_MODES, + /* fprintf saves/restores FP registers on PPC :-( */ + RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, + &rpciod) ); + wkup.sw_pfn = rxWakeupCB; + wkup.sw_arg = (caddr_t)rpciod; + assert( 0==setsockopt(ourSock, SOL_SOCKET, SO_RCVWAKEUP, &wkup, sizeof(wkup)) ); + assert( RTEMS_SUCCESSFUL == rtems_message_queue_create( + rtems_build_name('R','P','C','q'), + RPCIOD_QDEPTH, + sizeof(RpcUdpXact), + RTEMS_DEFAULT_ATTRIBUTES, + &msgQ) ); + assert( RTEMS_SUCCESSFUL == rtems_task_start( + rpciod, + rpcio_daemon, + 0 ) ); + + } else { + return -1; + } + } + return 0; +} + +int +rpcUdpCleanup(void) +{ + rtems_semaphore_create( + rtems_build_name('R','P','C','f'), + 0, + RTEMS_DEFAULT_ATTRIBUTES, + 0, + &fini); + rtems_event_send(rpciod, RPCIOD_KILL_EVENT); + /* synchronize with daemon */ + rtems_semaphore_obtain(fini, RTEMS_WAIT, 5*ticksPerSec); + /* if the message queue is still there, something went wrong */ + if (!msgQ) { + rtems_task_delete(rpciod); + } + rtems_semaphore_delete(fini); + return (msgQ !=0); +} + +/* Another API - simpler but less efficient. + * For each RPCall, a server and a Xact + * are created and destroyed on the fly. + * + * This should be used for infrequent calls + * (e.g. a NFS mount request). + * + * This is roughly compatible with the original + * clnt_call() etc. API - but it uses our + * daemon and is fully reentrant. + */ +enum clnt_stat +rpcUdpClntCreate( + struct sockaddr_in *psaddr, + int prog, + int vers, + u_long uid, + u_long gid, + RpcUdpClnt *pclnt +) +{ +RpcUdpXact x; +RpcUdpServer s; +enum clnt_stat err; + + if ( RPC_SUCCESS != (err=rpcUdpServerCreate(psaddr, prog, vers, uid, gid, &s)) ) + return err; + + if ( !(x=rpcUdpXactCreate(prog, vers, UDPMSGSIZE)) ) { + rpcUdpServerDestroy(s); + return RPC_FAILED; + } + /* TODO: could maintain a server cache */ + + x->server = s; + + *pclnt = x; + + return RPC_SUCCESS; +} + +void +rpcUdpClntDestroy(RpcUdpClnt xact) +{ + rpcUdpServerDestroy(xact->server); + rpcUdpXactDestroy(xact); +} + +enum clnt_stat +rpcUdpClntCall( + RpcUdpClnt xact, + u_long proc, + XdrProcT xargs, + CaddrT pargs, + XdrProcT xres, + CaddrT pres, + struct timeval *timeout + ) +{ +enum clnt_stat stat; + + if ( (stat = rpcUdpSend(xact, xact->server, timeout, proc, + xres, pres, + xargs, pargs, + 0)) ) { + fprintf(stderr,"RPCIO Send failed: %i\n",stat); + return stat; + } + return rpcUdpRcv(xact); +} + +/* a yet simpler interface */ +enum clnt_stat +rpcUdpCallRp( + struct sockaddr_in *psrvr, + u_long prog, + u_long vers, + u_long proc, + XdrProcT xargs, + CaddrT pargs, + XdrProcT xres, + CaddrT pres, + u_long uid, /* RPCIO_DEFAULT_ID picks default */ + u_long gid, /* RPCIO_DEFAULT_ID picks default */ + struct timeval *timeout /* NULL picks default */ +) +{ +RpcUdpClnt clp; +enum clnt_stat stat; + + stat = rpcUdpClntCreate( + psrvr, + prog, + vers, + uid, + gid, + &clp); + + if ( RPC_SUCCESS != stat ) + return stat; + + stat = rpcUdpClntCall( + clp, + proc, + xargs, pargs, + xres, pres, + timeout); + + rpcUdpClntDestroy(clp); + + return stat; +} + +/* linked list primitives */ +static void +nodeXtract(ListNode n) +{ + if (n->prev) + n->prev->next = n->next; + if (n->next) + n->next->prev = n->prev; + n->next = n->prev = 0; +} + +static void +nodeAppend(ListNode l, ListNode n) +{ + if ( (n->next = l->next) ) + n->next->prev = n; + l->next = n; + n->prev = l; + +} + +/* this code does the work */ +static void +rpcio_daemon(rtems_task_argument arg) +{ +rtems_status_code stat; +RpcUdpXact xact; +RpcUdpServer srv; +rtems_interval next_retrans, then, unow; +long now; /* need to do signed comparison with age! */ +rtems_event_set events; +ListNode newList; +rtems_unsigned32 size; +rtems_id q = 0; +ListNodeRec listHead = {0}; +unsigned long epoch = RPCIOD_EPOCH_SECS * ticksPerSec; +unsigned long max_period = RPCIOD_RETX_CAP_S * ticksPerSec; + + assert( RTEMS_SUCCESSFUL == rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + &then) ); + + for (next_retrans = epoch;;) { + + if ( RTEMS_SUCCESSFUL != + (stat = rtems_event_receive( + RPCIOD_RX_EVENT | RPCIOD_TX_EVENT | RPCIOD_KILL_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + next_retrans, + &events)) ) { + ASSERT( RTEMS_TIMEOUT == stat ); + events = 0; + } + + if (events & RPCIOD_KILL_EVENT) { + int i; + +#if (DEBUG) & DEBUG_EVENTS + fprintf(stderr,"RPCIO: got KILL event\n"); +#endif + + MU_LOCK(hlock); + for (i=XACT_HASHS-1; i>=0; i--) { + if (xactHashTbl[i]) { + break; + } + } + if (i<0) { + /* prevent them from creating and enqueueing more messages */ + q=msgQ; + /* messages queued after we executed this assignment will fail */ + msgQ=0; + } + MU_UNLOCK(hlock); + if (i>=0) { + fprintf(stderr,"RPCIO There are still transactions circulating; I refuse to go away\n"); + fprintf(stderr,"(1st in slot %i)\n",i); + rtems_semaphore_release(fini); + } else { + break; + } + } + + ASSERT( RTEMS_SUCCESSFUL == rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + &unow ) ); + + /* measure everything relative to then to protect against + * rollover + */ + now = unow - then; + + /* NOTE: we don't lock the hash table while we are operating + * on transactions; the paradigm is that we 'own' a particular + * transaction (and hence it's hash table slot) from the + * time the xact was put into the message queue until we + * wake up the requestor. + */ + + if (RPCIOD_RX_EVENT & events) { + +#if (DEBUG) & DEBUG_EVENTS + fprintf(stderr,"RPCIO: got RX event\n"); +#endif + + while ((xact=sockRcv())) { + + /* extract from the retransmission list */ + nodeXtract(&xact->node); + + /* change the ID - there might already be + * a retransmission on the way. When it's + * reply arrives we must not find it's ID + * in the hashtable + */ + xact->obuf.xid += XACT_HASHS; + + xact->status.re_status = RPC_SUCCESS; + + /* calculate roundtrip ticks */ + xact->trip = now - xact->trip; + + srv = xact->server; + + /* adjust the server's retry period */ + { + register TimeoutT rtry = srv->retry_period; + register TimeoutT trip = xact->trip; + + ASSERT( trip >= 0 ); + + if ( 0==trip ) + trip = 1; + + /* retry_new = 0.75*retry_old + 0.25 * 8 * roundrip */ + rtry = (3*rtry + (trip << 3)) >> 2; + + if ( rtry > max_period ) + rtry = max_period; + + srv->retry_period = rtry; + } + + /* wakeup requestor */ + rtems_event_send(xact->requestor, RTEMS_RPC_EVENT); + } + } + + if (RPCIOD_TX_EVENT & events) { + +#if (DEBUG) & DEBUG_EVENTS + fprintf(stderr,"RPCIO: got TX event\n"); +#endif + + while (RTEMS_SUCCESSFUL == rtems_message_queue_receive( + msgQ, + &xact, + &size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT)) { + /* put to the head of timeout q */ + nodeAppend(&listHead, &xact->node); + + xact->age = now; + xact->trip = FIRST_ATTEMPT; + } + } + + + /* work the timeout q */ + newList = 0; + for ( xact=(RpcUdpXact)listHead.next; + xact && xact->age <= now; + xact=(RpcUdpXact)listHead.next ) { + + /* extract from the list */ + nodeXtract(&xact->node); + + srv = xact->server; + + if (xact->tolive < 0) { + /* this one timed out */ + xact->status.re_errno = ETIMEDOUT; + xact->status.re_status = RPC_TIMEDOUT; + + srv->timeouts++; + +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr,"RPCIO XACT timed out; waking up requestor\n"); +#endif + if ( rtems_event_send(xact->requestor, RTEMS_RPC_EVENT) ) { + rtems_panic("RPCIO PANIC file %s line: %i, requestor id was 0x%08x", + __FILE__, + __LINE__, + xact->requestor); + } + + } else { + int len; + + len = (int)XDR_GETPOS(&xact->xdrs); + +#ifdef MBUF_TX + xact->refcnt = 1; /* sendto itself */ +#endif + if ( len != SENDTO( ourSock, + xact->obuf.buf, + len, + 0, + (struct sockaddr*) &srv->addr, + sizeof(srv->addr) +#ifdef MBUF_TX + , xact, + paranoia_free, + paranoia_ref +#endif + ) ) { + + xact->status.re_errno = errno; + xact->status.re_status = RPC_CANTSEND; + srv->errors++; + + /* wakeup requestor */ + fprintf(stderr,"RPCIO: SEND failure\n"); + ASSERT( RTEMS_SUCCESSFUL == + rtems_event_send(xact->requestor, RTEMS_RPC_EVENT) ); + + } else { + /* send successful; calculate retransmission time + * and enqueue to temporary list + */ + if (FIRST_ATTEMPT != xact->trip) { +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr, + "timed out; tolive is %i (ticks), retry period is %i (ticks)\n", + xact->tolive, + srv->retry_period); +#endif + /* this is a real retry; we backup + * the server's retry interval + */ + if ( srv->retry_period < max_period ) { + + /* If multiple transactions for this server + * fail (e.g. because it died) this will + * back-off very agressively (doubling + * the retransmission period for every + * timed out transaction up to the CAP limit) + * which is desirable - single packet failure + * is treated more gracefully by this algorithm. + */ + + srv->retry_period<<=1; +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr, + "adjusted to; retry period %i\n", + srv->retry_period); +#endif + } else { + /* never wait longer than RPCIOD_RETX_CAP_S seconds */ + fprintf(stderr, + "RPCIO: server '%s' not responding - still trying\n", + srv->name); + } + if ( 0 == ++srv->retrans % 1000) { + fprintf(stderr, + "RPCIO - statistics: already %li retries to server %s\n", + srv->retrans, + srv->name); + } + } else { + srv->requests++; + } + xact->trip = now; + xact->age = now + srv->retry_period; + xact->tolive -= srv->retry_period; + /* enqueue to the list of newly sent transactions */ + xact->node.next = newList; + newList = &xact->node; +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr, + "XACT (0x%08x) age is 0x%x, now: 0x%x\n", + xact, + xact->age, + now); +#endif + } + } + } + + /* insert the newly sent transactions into the + * sorted retransmission list + */ + for (; (xact = (RpcUdpXact)newList); ) { + register ListNode p,n; + newList = newList->next; + for ( p=&listHead; (n=p->next) && xact->age > ((RpcUdpXact)n)->age; p=n ) + /* nothing else to do */; + nodeAppend(p, &xact->node); + } + + if (now > epoch) { + /* every now and then, readjust the epoch */ + register ListNode n; + then += now; + for (n=listHead.next; n; n=n->next) { + /* readjust outstanding time intervals subject to the + * condition that the 'absolute' time must remain + * the same. 'age' and 'trip' are measured with + * respect to 'then' - hence: + * + * abs_age == old_age + old_then == new_age + new_then + * + * ==> new_age = old_age + old_then - new_then == old_age - 'now' + */ + ((RpcUdpXact)n)->age -= now; + ((RpcUdpXact)n)->trip -= now; +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr, + "readjusted XACT (0x%08x); age is 0x%x, trip: 0x%x now: 0x%x\n", + (RpcUdpXact)n, + ((RpcUdpXact)n)->trip, + ((RpcUdpXact)n)->age, + now); +#endif + } + now = 0; + } + + next_retrans = listHead.next ? + ((RpcUdpXact)listHead.next)->age - now : + epoch; /* make sure we don't miss updating the epoch */ +#if (DEBUG) & DEBUG_TIMEOUT + fprintf(stderr,"RPCIO: next timeout is %x\n",next_retrans); +#endif + } + /* close our socket; shut down the receiver */ + close(ourSock); + +#if 0 /* if we get here, no transactions exist, hence there can be none + * in the queue whatsoever + */ + /* flush the message queue */ + while (RTEMS_SUCCESSFUL == rtems_message_queue_receive( + q, + &xact, + &size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT)) { + /* TODO enque xact */ + } + + /* flush all outstanding transactions */ + + for (xact=((RpcUdpXact)listHead.next); xact; xact=((RpcUdpXact)xact->node.next)) { + xact->status.re_status = RPC_TIMEDOUT; + rtems_event_send(xact->requestor, RTEMS_RPC_EVENT); + } +#endif + + rtems_message_queue_delete(q); + + MU_DESTROY(hlock); + + fprintf(stderr,"RPC daemon exited...\n"); + + rtems_semaphore_release(fini); + rtems_task_suspend(RTEMS_SELF); +} + + +/* support for transaction 'pools'. A number of XACT objects + * is always kept around. The initial number is 0 but it + * is allowed to grow up to a maximum. + * If the need grows beyond the maximum, behavior depends: + * Users can either block until a transaction becomes available, + * they can create a new XACT on the fly or get an error + * if no free XACT is available from the pool. + */ + +RpcUdpXactPool +rpcUdpXactPoolCreate( + int prog, int version, + int xactsize, int poolsize) +{ +RpcUdpXactPool rval = MY_MALLOC(sizeof(*rval)); + + ASSERT( rval && + RTEMS_SUCCESSFUL == rtems_message_queue_create( + rtems_build_name('R','P','C','p'), + poolsize, + sizeof(RpcUdpXact), + RTEMS_DEFAULT_ATTRIBUTES, + &rval->box) ); + rval->prog = prog; + rval->version = version; + rval->xactSize = xactsize; + return rval; +} + +void +rpcUdpXactPoolDestroy(RpcUdpXactPool pool) +{ +RpcUdpXact xact; + + while ((xact = rpcUdpXactPoolGet(pool, XactGetFail))) { + rpcUdpXactDestroy(xact); + } + rtems_message_queue_delete(pool->box); + MY_FREE(pool); +} + +RpcUdpXact +rpcUdpXactPoolGet(RpcUdpXactPool pool, XactPoolGetMode mode) +{ +RpcUdpXact xact = 0; +rtems_unsigned32 size; + + if (RTEMS_SUCCESSFUL != rtems_message_queue_receive( + pool->box, + &xact, + &size, + XactGetWait == mode ? + RTEMS_WAIT : RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT)) { + + /* nothing found in box; should we create a new one ? */ + + xact = (XactGetCreate == mode) ? + rpcUdpXactCreate( + pool->prog, + pool->version, + pool->xactSize) : 0 ; + if (xact) + xact->pool = pool; + + } + return xact; +} + +void +rpcUdpXactPoolPut(RpcUdpXact xact) +{ +RpcUdpXactPool pool; + ASSERT( pool=xact->pool ); + if (RTEMS_SUCCESSFUL != rtems_message_queue_send( + pool->box, + &xact, + sizeof(xact))) + rpcUdpXactDestroy(xact); +} + +#ifdef MBUF_RX + +/* WORKAROUND: include sys/mbuf.h (or other bsdnet headers) only + * _after_ using malloc()/free() & friends because + * the RTEMS/BSDNET headers redefine those :-( + */ + +#define KERNEL +#include + +ssize_t +recv_mbuf_from(int s, struct mbuf **ppm, long len, struct sockaddr *fromaddr, int *fromlen); + +static void +bufFree(struct mbuf **m) +{ + if (*m) { + rtems_bsdnet_semaphore_obtain(); + m_freem(*m); + rtems_bsdnet_semaphore_release(); + *m = 0; + } +} +#endif + +#ifdef MBUF_TX +static void +paranoia_free(caddr_t closure, u_int size) +{ +#if (DEBUG) +RpcUdpXact xact = (RpcUdpXact)closure; +int len = (int)XDR_GETPOS(&xact->xdrs); + + ASSERT( --xact->refcnt >= 0 && size == len ); +#endif +} + +static void +paranoia_ref (caddr_t closure, u_int size) +{ +#if (DEBUG) +RpcUdpXact xact = (RpcUdpXact)closure; +int len = (int)XDR_GETPOS(&xact->xdrs); + ASSERT( size == len ); + xact->refcnt++; +#endif +} +#endif + +/* receive from a socket and find + * the transaction corresponding to the + * transaction ID received in the server + * reply. + * + * The semantics of the 'pibuf' pointer are + * as follows: + * + * MBUF_RX: + * + */ + +#define RPCIOD_RXBUFSZ UDPMSGSIZE + +static RpcUdpXact +sockRcv(void) +{ +int len,i; +u_long xid; +struct sockaddr_in fromAddr; +int fromLen = sizeof(fromAddr); +RxBuf ibuf = 0; +RpcUdpXact xact = 0; + + do { + + /* rcv_mbuf() and recvfrom() differ in that the + * former allocates buffers and passes them back + * to us whereas the latter requires us to provide + * buffer space. + * Hence, in the first case whe have to make sure + * no old buffer is leaked - in the second case, + * we might well re-use an old buffer but must + * make sure we have one allocated + */ +#ifdef MBUF_RX + if (ibuf) + bufFree(&ibuf); + + len = recv_mbuf_from( + ourSock, + &ibuf, + RPCIOD_RXBUFSZ, + (struct sockaddr*)&fromAddr, + &fromLen); +#else + if ( !ibuf ) + ibuf = (RpcBuf)MY_MALLOC(RPCIOD_RXBUFSZ); + if ( !ibuf ) + goto cleanup; /* no memory - drop this message */ + + len = recvfrom(ourSock, + ibuf->buf, + RPCIOD_RXBUFSZ, + 0, + (struct sockaddr*)&fromAddr, + &fromLen); +#endif + + if (len <= 0) { + if (EAGAIN != errno) + fprintf(stderr,"RECV failed: %s\n",strerror(errno)); + goto cleanup; + } + +#if (DEBUG) & DEBUG_PACKLOSS + if ( (unsigned)rand() < DEBUG_PACKLOSS_FRACT ) { + /* lose packets once in a while */ + static int xxx = 0; + if ( ++xxx % 16 == 0 ) + fprintf(stderr,"DEBUG: dropped %i packets, so far...\n",xxx); + if ( ibuf ) + bufFree( &ibuf ); + continue; + } +#endif + + i = (xid=XID(ibuf)) & XACT_HASH_MSK; + + if ( !(xact=xactHashTbl[i]) || + xact->obuf.xid != xid || + xact->server->addr.sin_addr.s_addr != fromAddr.sin_addr.s_addr || + xact->server->addr.sin_port != fromAddr.sin_port ) { + + if (xact) { + if (xact->server->addr.sin_addr.s_addr == fromAddr.sin_addr.s_addr && + xact->server->addr.sin_port == fromAddr.sin_port && + ( xact->obuf.xid == xid + XACT_HASHS || + xact->obuf.xid == xid + 2*XACT_HASHS ) + ) { +#ifndef DEBUG /* don't complain if it's just a late arrival of a retry */ + fprintf(stderr,"RPCIO - FYI sockRcv(): dropping late/redundant retry answer\n"); +#endif + } else { + fprintf(stderr,"RPCIO WARNING sockRcv(): transaction mismatch\n"); + fprintf(stderr,"xact: xid 0x%08lx -- got 0x%08lx\n", + xact->obuf.xid, xid); + fprintf(stderr,"xact: addr 0x%08lx -- got 0x%08lx\n", + xact->server->addr.sin_addr.s_addr, + fromAddr.sin_addr.s_addr); + fprintf(stderr,"xact: port 0x%08x -- got 0x%08x\n", + xact->server->addr.sin_port, + fromAddr.sin_port); + } + } else { + fprintf(stderr, + "RPCIO WARNING sockRcv(): got xid 0x%08lx but its slot is empty\n", + xid); + } + /* forget about this one and try again */ + xact = 0; + } + + } while ( !xact ); + + xact->ibuf = ibuf; +#ifndef MBUF_RX + xact->ibufsize = RPCIOD_RXBUFSZ; +#endif + + return xact; + +cleanup: + + bufFree(&ibuf); + + return 0; +} + + +#include +/* double check the event configuration; should probably globally + * manage system events!! + * We do this at the end of the file for the same reason we had + * included mbuf.h only a couple of lines above - see comment up + * there... + */ +#if RTEMS_RPC_EVENT & SOSLEEP_EVENT & SBWAIT_EVENT & NETISR_EVENTS +#error ILLEGAL EVENT CONFIGURATION +#endif diff --git a/rtemsNfs/src/rpcio.h b/rtemsNfs/src/rpcio.h new file mode 100644 index 0000000..922bc0d --- /dev/null +++ b/rtemsNfs/src/rpcio.h @@ -0,0 +1,205 @@ +#ifndef RPCIO_H +#define RPCIO_H +/* $Id$ */ + +/* A multihreaded RPC/UDP multiplexor */ + +/* Author: Till Straumann, , 2002 */ + +/* + * Copyright 2002, Stanford University and + * Till Straumann + * + * Stanford Notice + * *************** + * + * Acknowledgement of sponsorship + * * * * * * * * * * * * * * * * * + * This software was produced by the Stanford Linear Accelerator Center, + * Stanford University, under Contract DE-AC03-76SFO0515 with the Department + * of Energy. + * + * Government disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, + * or assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately + * owned rights. + * + * Stanford disclaimer of liability + * - - - - - - - - - - - - - - - - - + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * This product is subject to the EPICS open license + * - - - - - - - - - - - - - - - - - - - - - - - - - + * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php + * for more information. + * + * Maintenance of notice + * - - - - - - - - - - - + * In the interest of clarity regarding the origin and status of this + * software, Stanford University requests that any recipient of it maintain + * this notice affixed to any distribution by the recipient that contains a + * copy or derivative of this software. + */ + + +#ifdef __rtems +#include +#endif + +#include +#include +#include +#include +#include + +typedef struct RpcUdpServerRec_ *RpcUdpServer; +typedef struct RpcUdpXactRec_ *RpcUdpXact; + +typedef RpcUdpXact RpcUdpClnt; + +#define RPCIOD_DEFAULT_ID 0xdef10000 + +int +rpcUdpInit(void); + +enum clnt_stat +rpcUdpServerCreate( + struct sockaddr_in *paddr, + int prog, + int vers, + u_long uid, /* RPCIO_DEFAULT_ID picks default */ + u_long gid, /* RPCIO_DEFAULT_ID picks default */ + RpcUdpServer *pclnt /* new server is returned here */ + ); + + +void +rpcUdpServerDestroy(RpcUdpServer s); + +/* Dump statistics to a file (stdout if NULL); + * returns 0 for convenience + */ +int +rpcUdpStats(FILE *f); + +enum clnt_stat +rpcUdpClntCreate( + struct sockaddr_in *psaddr, + int prog, + int vers, + u_long uid, /* RPCIO_DEFAULT_ID picks default */ + u_long gid, /* RPCIO_DEFAULT_ID picks default */ + RpcUdpClnt *pclnt /* new client is returned here */ + ); + +void +RpcUdpClntDestroy(RpcUdpClnt clnt); + +/* mute compiler warnings */ +typedef void *XdrProcT; +typedef void *CaddrT; + +enum clnt_stat +rpcUdpClntCall( + RpcUdpClnt clnt, + u_long proc, + XdrProcT xargs, + CaddrT pargs, + XdrProcT xres, + CaddrT pres, + struct timeval *timeout /* optional timeout; maybe NULL to pick default */ + ); + +RpcUdpXact +rpcUdpXactCreate( + u_long program, + u_long version, + u_long size + ); + +void +rpcUdpXactDestroy( + RpcUdpXact xact + ); + +/* send a transaction */ +enum clnt_stat +rpcUdpSend( + RpcUdpXact xact, + RpcUdpServer srvr, + struct timeval *timeout, /* maybe NULL to pick default */ + u_long proc, + xdrproc_t xres, + caddr_t pres, + xdrproc_t xargs, + caddr_t pargs, + ... /* 0 terminated xdrproc/pobj additional argument list */ + ); + +/* wait for a transaction to complete */ +enum clnt_stat +rpcUdpRcv(RpcUdpXact xact); + +/* a yet simpler interface */ +enum clnt_stat +rpcUdpCallRp( + struct sockaddr_in *pserver_addr, + u_long prog, + u_long vers, + u_long proc, + XdrProcT xargs, + CaddrT pargs, + XdrProcT xres, + CaddrT pres, + u_long uid, /* RPCIO_DEFAULT_ID picks default */ + u_long gid, /* RPCIO_DEFAULT_ID picks default */ + struct timeval *timeout /* NULL picks default */ +); + + +/* manage pools of transactions */ + +/* A pool of transactions. The idea is not to malloc/free them + * all the time but keep a limited number around in a 'pool'. + * Users who need a XACT may get it from the pool and put it back + * when done. + * The pool is implemented by RTEMS message queues who manage + * the required task synchronization. + * A requestor has different options if the pool is empty: + * - it can wait (block) for a XACT to become available + * - it can get an error status + * - or it can malloc an extra XACT from the heap which + * will eventually be released. + */ + +typedef struct RpcUdpXactPoolRec_ *RpcUdpXactPool; + +/* NOTE: the pool is empty initially, must get messages (in + * GetCreate mode + */ +RpcUdpXactPool +rpcUdpXactPoolCreate( + int prog, int version, + int xactsize, int poolsize); + +void +rpcUdpXactPoolDestroy(RpcUdpXactPool pool); + +typedef enum { + XactGetFail, /* call fails if no transaction available */ + XactGetWait, /* call blocks until transaction available */ + XactGetCreate /* a new transaction is allocated (and freed when put back to the pool */ +} XactPoolGetMode; + +RpcUdpXact +rpcUdpXactPoolGet(RpcUdpXactPool pool, XactPoolGetMode mode); + +void +rpcUdpXactPoolPut(RpcUdpXact xact); + +#endif diff --git a/rtemsNfs/src/rpcio.modini.c b/rtemsNfs/src/rpcio.modini.c new file mode 100644 index 0000000..7773b3d --- /dev/null +++ b/rtemsNfs/src/rpcio.modini.c @@ -0,0 +1,15 @@ +#include "librtemsNfs.h" +/* CEXP module support (magic init) */ +void +_cexpModuleInitialize(void *mod) +{ + rpcUdpInit(); +} + +int +_cexpModuleFinalize(void *mod) +{ + return rpcUdpCleanup(); +} + + diff --git a/rtemsNfs/src/sock_mbuf.c b/rtemsNfs/src/sock_mbuf.c new file mode 100644 index 0000000..70c09d6 --- /dev/null +++ b/rtemsNfs/src/sock_mbuf.c @@ -0,0 +1,279 @@ +/* + * $Id$ + * + * NOTE: + * This is derived from libnetworking/rtems/rtems_syscall.c + * + * RTEMS/libnetworking LICENSING restrictions may apply + * + * Author (modifications only): + * Copyright: 2002, Stanford University and + * Till Straumann, + * Licensing: 'LICENSE.NET' file in the RTEMS top source directory + * for more information. + */ + +/* +The RTEMS TCP/IP stack is a port of the FreeBSD TCP/IP stack. The following +copyright and licensing information applies to this code. + +This code is found under the c/src/libnetworking directory but does not +constitute the entire contents of that subdirectory. + +============================================================================= + +Copyright (c) 1980, 1983, 1988, 1993 + The Regents of the University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgment: + This product includes software developed by the University of + California, Berkeley and its contributors. +4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +- +Portions Copyright (c) 1993 by Digital Equipment Corporation. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies, and that +the name of Digital Equipment Corporation not be used in advertising or +publicity pertaining to distribution of the document or software without +specific, written prior permission. + +THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT +CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +============================================================================= +*/ + + +#include +#include +#include + +#include +#include +#include + +#define KERNEL +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct socket *rtems_bsdnet_fdToSocket(int fd); + +/* + * Package system call argument into mbuf. + * + * (unfortunately, the original is not public) + */ +static int +sockaddrtombuf (struct mbuf **mp, const struct sockaddr *buf, int buflen) +{ +struct mbuf *m; +struct sockaddr *sa; + + if ((u_int)buflen > MLEN) + return (EINVAL); + + rtems_bsdnet_semaphore_obtain(); + m = m_get(M_WAIT, MT_SONAME); + rtems_bsdnet_semaphore_release(); + + if (m == NULL) + return (ENOBUFS); + m->m_len = buflen; + memcpy (mtod(m, caddr_t), buf, buflen); + *mp = m; + sa = mtod(m, struct sockaddr *); + sa->sa_len = buflen; + + return 0; +} + +static void +dummyproc(caddr_t ext_buf, u_int ext_size) +{ +} + +/* + * send data by simply allocating an MBUF packet + * header and pointing it to our data region. + * + * Optionally, the caller may supply 'reference' + * and 'free' procs. (The latter may call the + * user back once the networking stack has + * released the buffer). + * + * The callbacks are provided with the 'closure' + * pointer and the 'buflen' argument. + */ +ssize_t +sendto_nocpy ( + int s, + const void *buf, size_t buflen, + int flags, + const struct sockaddr *toaddr, int tolen, + void *closure, + void (*freeproc)(caddr_t, u_int), + void (*refproc)(caddr_t, u_int) +) +{ + int error; + struct socket *so; + struct mbuf *to, *m; + int ret = -1; + + rtems_bsdnet_semaphore_obtain (); + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { + rtems_bsdnet_semaphore_release (); + return -1; + } + + error = sockaddrtombuf (&to, toaddr, tolen); + if (error) { + errno = error; + rtems_bsdnet_semaphore_release (); + return -1; + } + + MGETHDR(m, M_WAIT, MT_DATA); + m->m_pkthdr.len = 0; + m->m_pkthdr.rcvif = (struct ifnet *) 0; + + m->m_flags |= M_EXT; + m->m_ext.ext_buf = closure ? closure : (void*)buf; + m->m_ext.ext_size = buflen; + /* we _must_ supply non-null procs; otherwise, + * the kernel code assumes it's a mbuf cluster + */ + m->m_ext.ext_free = freeproc ? freeproc : dummyproc; + m->m_ext.ext_ref = refproc ? refproc : dummyproc; + m->m_pkthdr.len += buflen; + m->m_len = buflen; + m->m_data = (void*)buf; + + error = sosend (so, to, NULL, m, NULL, flags); + if (error) { + if (/*auio.uio_resid != len &&*/ (error == EINTR || error == EWOULDBLOCK)) + error = 0; + } + if (error) + errno = error; + else + ret = buflen; + if (to) + m_freem(to); + rtems_bsdnet_semaphore_release (); + return (ret); +} + + +/* + * receive data in an 'mbuf chain'. + * The chain must be released once the + * data has been extracted: + * + * rtems_bsdnet_semaphore_obtain(); + * m_freem(chain); + * rtems_bsdnet_semaphore_release(); + */ +ssize_t +recv_mbuf_from(int s, struct mbuf **ppm, long len, struct sockaddr *fromaddr, int *fromlen) +{ + int ret = -1; + int error; + struct uio auio; + struct socket *so; + struct mbuf *from = NULL; + + memset(&auio, 0, sizeof(auio)); + *ppm = 0; + + rtems_bsdnet_semaphore_obtain (); + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { + rtems_bsdnet_semaphore_release (); + return -1; + } +/* auio.uio_iov = mp->msg_iov; + auio.uio_iovcnt = mp->msg_iovlen; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_rw = UIO_READ; + auio.uio_offset = 0; +*/ + auio.uio_resid = len; + error = soreceive (so, &from, &auio, (struct mbuf **) ppm, + (struct mbuf **)NULL, + NULL); + if (error) { + if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK)) + error = 0; + } + if (error) { + errno = error; + } + else { + ret = len - auio.uio_resid; + if (fromaddr) { + len = *fromlen; + if ((len <= 0) || (from == NULL)) { + len = 0; + } + else { + if (len > from->m_len) + len = from->m_len; + memcpy (fromaddr, mtod(from, caddr_t), len); + } + *fromlen = len; + } + } + if (from) + m_freem (from); + if (error && *ppm) { + m_freem(*ppm); + *ppm = 0; + } + rtems_bsdnet_semaphore_release (); + return (ret); +} diff --git a/rtemsNfs/src/xdr_mbuf.c b/rtemsNfs/src/xdr_mbuf.c new file mode 100644 index 0000000..22f972d --- /dev/null +++ b/rtemsNfs/src/xdr_mbuf.c @@ -0,0 +1,534 @@ +/* $Id$ */ + +/* xdr_mbuf is derived from xdr_mem */ + +/* Author (mbuf specifica): Till Straumann , 10/2002 */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_mem.c,v 1.8 1999/08/28 00:02:56 peter Exp $"; +#endif + +/* + * xdr_mbuf, XDR implementation using mbuf buffers + * + * derived from: + * + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The MBUF stream is useful for BSDNET kernel (or RTEMS for that matter) + * use. + */ + +#include +#include +#include +#include + +#include + +#define TODO + +/* TODO remove: a hack because malloc is redefined */ +#ifdef TODO +static inline void * +my_malloc(size_t i) +{ + return malloc(i); +} + +static inline void +my_free(void *p) +{ + return free(p); +} +#endif + +#define DEBUG_ASSERT (1<<0) +#define DEBUG_VERB (1<<1) + +#define DEBUG DEBUG_ASSERT + +#define KERNEL +#include + +#include + +#if DEBUG & DEBUG_VERB || defined(TODO) +#include +#endif + +static bool_t xdrmbuf_getlong_aligned(); +static bool_t xdrmbuf_putlong_aligned(); +static bool_t xdrmbuf_getlong_unaligned(); +static bool_t xdrmbuf_putlong_unaligned(); +static bool_t xdrmbuf_getbytes(); +static bool_t xdrmbuf_putbytes(); +static u_int xdrmbuf_getpos(); /* XXX w/64-bit pointers, u_int not enough! */ +static bool_t xdrmbuf_setpos(); +static int32_t *xdrmbuf_inline_aligned(); +static int32_t *xdrmbuf_inline_unaligned(); +static void xdrmbuf_destroy(); + +static struct xdr_ops xdrmbuf_ops_aligned = { + xdrmbuf_getlong_aligned, + xdrmbuf_putlong_aligned, + xdrmbuf_getbytes, + xdrmbuf_putbytes, + xdrmbuf_getpos, + xdrmbuf_setpos, + xdrmbuf_inline_aligned, + xdrmbuf_destroy +}; + +static struct xdr_ops xdrmbuf_ops_unaligned = { + xdrmbuf_getlong_unaligned, + xdrmbuf_putlong_unaligned, + xdrmbuf_getbytes, + xdrmbuf_putbytes, + xdrmbuf_getpos, + xdrmbuf_setpos, + xdrmbuf_inline_unaligned, + xdrmbuf_destroy +}; + +typedef struct MBPrivateRec_ { + struct mbuf *mchain; + struct mbuf *mcurrent; + u_int pos; /* number of bytes contained in all MUBFS ahead + * of mcurrent + */ +} MBPrivateRec, *MBPrivate; + +/* NOTE: the stream position helper 'pos' + * must be managed by the caller! + */ +static inline void +xdrmbuf_setup(XDR *xdrs, struct mbuf *m) +{ +MBPrivate mbp = (MBPrivate)xdrs->x_base; + + mbp->mcurrent = m; + xdrs->x_private = mtod(m,caddr_t); + xdrs->x_handy = m->m_len; + xdrs->x_ops = ((size_t)xdrs->x_private & (sizeof(int32_t) - 1)) + ? &xdrmbuf_ops_unaligned : &xdrmbuf_ops_aligned; +} + +static struct mbuf * +xdrmbuf_next(XDR *xdrs) +{ +struct mbuf *rval; +MBPrivate mbp = (MBPrivate)xdrs->x_base; + + if (mbp->mcurrent) { + mbp->pos += mbp->mcurrent->m_len; + rval = mbp->mcurrent->m_next; + } else { + rval = 0; + } + + if (rval) { + xdrmbuf_setup(xdrs, rval); + } +#if DEBUG & DEBUG_VERB + else { + fprintf(stderr,"xdrmbuf: end of chain\n"); + } +#endif + + return rval; +} + +/* + * The procedure xdrmbuf_create initializes a stream descriptor for a + * memory buffer. + */ +void +xdrmbuf_create(XDR *xdrs, struct mbuf *mbuf, enum xdr_op op) +{ +MBPrivate mbp; + + xdrs->x_op = op; + assert( mbp = (MBPrivate)my_malloc(sizeof(*mbp)) ); + xdrs->x_base = (caddr_t) mbp; + + mbp->mchain = mbuf; + mbp->pos = 0; + +#if DEBUG & DEBUG_VERB + { + struct mbuf *mbf; + fprintf(stderr,"Dumping chain:\n"); + for (mbf = mbuf; mbf; mbf=mbf->m_next) { + int ii; + fprintf(stderr,"MBUF------------"); + for (ii=0; iim_len; ii++) { + fprintf(stderr,"%02x ",mtod(mbf,char*)[ii]); + if (ii%16==0) + fputc('\n',stderr); + } + fputc('\n',stderr); + } + } +#endif + + xdrmbuf_setup(xdrs, mbuf); +} + +static void +xdrmbuf_destroy(XDR *xdrs) +{ +MBPrivate mbp = (MBPrivate)xdrs->x_base; +#if 0 /* leave destroying the chain to the user */ +struct mbuf *m = mbp->mchain; + + rtems_bsdnet_semaphore_obtain(); + m_freem(m); + rtems_bsdnet_semaphore_release(); +#endif + + my_free(mbp); +} + +static bool_t +xdrmbuf_getlong_aligned(register XDR *xdrs, register long *lp) +{ + while ( (signed int)(xdrs->x_handy -= sizeof(int32_t)) < 0) { + if ((xdrs->x_handy += sizeof(int32_t)) == 0) { + /* handy was 0 on entry; request a new buffer. + * Coded this way, so the most frequently executed + * path needs only one comparison... + */ + if (!xdrmbuf_next(xdrs)) + return FALSE; + } else { + /* uh-oh an aligned long spread over two MBUFS ?? + * let the unaligned handler deal with this rare + * situation. + */ + return xdrmbuf_getlong_unaligned(xdrs,lp); + } + } + *lp = ntohl(*(int32_t *)(xdrs->x_private)); + xdrs->x_private += sizeof(int32_t); +#if DEBUG & DEBUG_VERB + fprintf(stderr,"Got aligned long %x\n",*lp); +#endif + return (TRUE); +} + +static bool_t +xdrmbuf_putlong_aligned(xdrs, lp) + register XDR *xdrs; + long *lp; +{ +fprintf(stderr,"TODO: xdrmbuf_putlong_aligned() is unimplemented\n"); + return FALSE; +#if 0 + if ((xdrs->x_handy -= sizeof(int32_t)) < 0) + return (FALSE); + *(int32_t *)xdrs->x_private = htonl(*lp); + xdrs->x_private += sizeof(int32_t); + return (TRUE); +#endif +} + +static bool_t +xdrmbuf_getlong_unaligned(xdrs, lp) + register XDR *xdrs; + long *lp; +{ +union { + int32_t l; + char c[sizeof(int32_t)]; +} u; + +register int i,j; +register char *cp,*sp; + + i = xdrs->x_handy - sizeof(int32_t); + + /* handle the most common case first */ + if ( i >= 0 ) { + + xdrs->x_handy = i; + sp = (char*)xdrs->x_private; + xdrs->x_private = sp + sizeof(int32_t); + +#ifdef CANDO_UNALIGNED + { + *lp = ntohl(*(int32_t *)sp); +# if DEBUG & DEBUG_VERB + fprintf(stderr,"Got unaligned long %x (%i remaining)\n",*lp, xdrs->x_handy); +# endif + return TRUE; + } +#else /* machine can't do unaligned access */ + { + u.c[0] = *sp; + u.c[1] = *++sp; + u.c[2] = *++sp; + u.c[3] = *++sp; + + goto done; + } +#endif /* CANDO_UNALIGNED */ + } + + /* here the messy 'crossing buffers' business starts */ + + + j = sizeof(int32_t); + + cp = u.c-1; + + /* NOTE: on entry to this section, handy < j holds */ + do { + sp = ((char*)xdrs->x_private)-1; + + if ( (i=xdrs->x_handy) >= j ) { + /* more data in the buffer than we need: + * copy everything we need and goto 'done' + */ + xdrs->x_handy = i-j; + do { + *++cp = *++sp; + } while (--j > 0); + xdrs->x_private = (caddr_t)++sp; + + goto done; + + } else { + /* not enough data - copy as much as possible + * then get retrieve the next MBUF and start + * over + */ + j-=i; + while (i--) + *++cp = *++sp; + if (!xdrmbuf_next(xdrs)) + return FALSE; +#if DEBUG & DEBUG_VERB + fprintf(stderr,"getlong_unaligned: crossed mbuf boundary\n"); +#endif + } + } while (j > 0); + +done: + + *lp = ntohl(u.l); + +#if DEBUG & DEBUG_VERB + fprintf(stderr,"Got unaligned long %x (%i remaining)\n",*lp, xdrs->x_handy); +#endif + return (TRUE); +} + +static bool_t +xdrmbuf_putlong_unaligned(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + fprintf(stderr,"TODO: xdrmbuf_putlong_unaligned() is unimplemented\n"); + return FALSE; +#if 0 + { + int32_t l; + + if ((xdrs->x_handy -= sizeof(int32_t)) < 0) + return (FALSE); + l = htonl(*lp); + memcpy(xdrs->x_private, &l, sizeof(int32_t)); + xdrs->x_private += sizeof(int32_t); + return (TRUE); + } +#endif +} + +static bool_t +xdrmbuf_getbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ +#if DEBUG & DEBUG_VERB +int olen=len,bufs=0; +#endif + +#if DEBUG & DEBUG_VERB + fprintf(stderr,"wanting %i bytes (have %i)\n",olen,xdrs->x_handy); +#endif + + while (len>0) { + if (xdrs->x_handy >= len) { + memcpy(addr, xdrs->x_private, len); + xdrs->x_private += len; + xdrs->x_handy -= len; +#if 0 /* save a couple of instructions */ + len = 0; +#else + goto done; +#endif + } else { + if (xdrs->x_handy > 0) { + memcpy(addr, xdrs->x_private, xdrs->x_handy); + len -= xdrs->x_handy; + addr += xdrs->x_handy; + } + if (!xdrmbuf_next(xdrs)) + return FALSE; +#if DEBUG & DEBUG_VERB + bufs++; +#endif + } + } +done: +#if DEBUG & DEBUG_VERB + fprintf(stderr,"Got %i bytes (out of %i mbufs)\n",olen,bufs); +#endif + return (TRUE); +} + +static bool_t +xdrmbuf_putbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + fprintf(stderr,"TODO: xdrmbuf_putbytes() is unimplemented\n"); + return FALSE; +#if 0 + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + memcpy(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +#endif +} + +static u_int +xdrmbuf_getpos(xdrs) + register XDR *xdrs; +{ +#if 1 +MBPrivate mbp = (MBPrivate)xdrs->x_base; +struct mbuf *m = mbp->mcurrent; +u_int rval = mbp->pos; + + if (m) { + rval += (u_long)xdrs->x_private - mtod(m, u_long); + } +#else +struct mbuf *m; +u_int rval = 0; +MBPrivate mbp = (MBPrivate)xdrs->x_base; + + for ( m = mbp->mchain; m && m != mbp->mcurrent; m = m->m_next ) + rval += m->m_len; + if (m) { + rval += (u_long)xdrs->x_private - mtod(m, u_long); + } + +#endif + return rval; +} + +static bool_t +xdrmbuf_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ +struct mbuf *m; +MBPrivate mbp = (MBPrivate)xdrs->x_base; + + if (pos >= mbp->pos) { + pos -= mbp->pos; + m = mbp->mcurrent; + } else { + m = mbp->mchain; + mbp->pos = 0; + } + + while ( m && pos >= m->m_len ) { + pos -= m->m_len; + mbp->pos += m->m_len; + m = m->m_next; + } + + if (m) { + xdrmbuf_setup(xdrs, m); + xdrs->x_private += pos; + return TRUE; + } + + return 0 == pos ? TRUE : FALSE; +} + +static int32_t * +xdrmbuf_inline_aligned(xdrs, len) + register XDR *xdrs; + int len; +{ +int32_t *buf = 0; + + if (xdrs->x_handy == 0 && !xdrmbuf_next(xdrs)) + return 0; + + if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (int32_t *) xdrs->x_private; + xdrs->x_private += len; +#if DEBUG & DEBUG_VERB + fprintf(stderr,"Got %i aligned inline bytes at %x\n", len, buf); +#endif + } +#if DEBUG & DEBUG_VERB + else { + fprintf(stderr,"Skipped %i aligned inline bytes\n",len); + } +#endif + return (buf); +} + +static int32_t * +xdrmbuf_inline_unaligned(xdrs, len) + register XDR *xdrs; + int len; +{ + return (0); +} diff --git a/zlib-1.1.4/ChangeLog b/zlib-1.1.4/ChangeLog new file mode 100644 index 0000000..bf2e3f9 --- /dev/null +++ b/zlib-1.1.4/ChangeLog @@ -0,0 +1,481 @@ + + ChangeLog file for zlib + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occuring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/zlib-1.1.4/FAQ b/zlib-1.1.4/FAQ new file mode 100644 index 0000000..47a7d60 --- /dev/null +++ b/zlib-1.1.4/FAQ @@ -0,0 +1,100 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. If you + want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions + about the zlib DLL should be sent to Gilles Vollant (info@winimage.com). + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.winimage.com/zLibDll/cmp-z-it.zip + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage + are in the files example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the directories contrib/delphi and contrib/delphi2 in the zlib + distribution. + +11. Can zlib handle .zip archives? + + See the directory contrib/minizip in the zlib distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. Why does "make test" fail on Mac OS X? + + Mac OS X already includes zlib as a shared library, and so -lz links the + shared library instead of the one that the "make" compiled. For zlib + 1.1.3, the two are incompatible due to different compile-time + options. Simply change the -lz in the Makefile to libz.a, and it will use + the compiled library instead of the shared one and the "make test" will + succeed. + +15. I have a question about OttoPDF + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site Joel Hainley jhainley@myndkryme.com. diff --git a/zlib-1.1.4/INDEX b/zlib-1.1.4/INDEX new file mode 100644 index 0000000..8a24576 --- /dev/null +++ b/zlib-1.1.4/INDEX @@ -0,0 +1,86 @@ +ChangeLog history of changes +INDEX this file +FAQ Frequently Asked Questions about zlib +Make_vms.com script for Vax/VMS +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +Makefile.riscos makefile for RISCOS +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +descrip.mms makefile for Vax/VMS +zlib.3 mini man page for zlib (volunteers to write full + man pages from zlib.h welcome. write to jloup@gzip.org) + +amiga/Makefile.sas makefile for Amiga SAS/C +amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC + +msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit +msdos/Makefile.b32 makefile for Borland C++ 32-bit +msdos/Makefile.bor makefile for Borland C/C++ 16-bit +msdos/Makefile.dj2 makefile for DJGPP 2.x +msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2) +msdos/Makefile.msc makefile for Microsoft C 16-bit +msdos/Makefile.tc makefile for Turbo C +msdos/Makefile.wat makefile for Watcom C +msdos/zlib.def definition file for Windows DLL +msdos/zlib.rc definition file for Windows DLL + +nt/Makefile.nt makefile for Windows NT +nt/zlib.dnt definition file for Windows NT DLL +nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel) +nt/Makefile.gcc makefile for Windows NT using GCC (mingw32) + + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +deflate.c +deflate.h +gzio.c +infblock.c +infblock.h +infcodes.c +infcodes.h +inffast.c +inffast.h +inflate.c +inftrees.c +inftrees.h +infutil.c +infutil.h +maketree.c +trees.c +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties + +contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + +contrib/minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + See http://www.winimage.com/zLibDll/unzip.html + +contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz extractor using zlib + +contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. diff --git a/zlib-1.1.4/Make_vms.com b/zlib-1.1.4/Make_vms.com new file mode 100644 index 0000000..1c57e8f --- /dev/null +++ b/zlib-1.1.4/Make_vms.com @@ -0,0 +1,115 @@ +$! make libz under VMS +$! written by Martin P.J. Zinser +$! +$! Look for the compiler used +$! +$ ccopt = "" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ comp = "__vaxc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$! +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - + gzio.c zutil.h zlib.h zconf.h +$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - + infblock.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - + infcodes.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" - + infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ else +$ mms/macro=('comp') +$ endif +$ write sys$output "Zlib build completed" +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/zlib-1.1.4/Makefile b/zlib-1.1.4/Makefile new file mode 100644 index 0000000..43cb757 --- /dev/null +++ b/zlib-1.1.4/Makefile @@ -0,0 +1,175 @@ +# Makefile for zlib +# Copyright (C) 1995-2002 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=m68k-rtems-gcc --pipe -B/opt/rtems/m68k-rtems/mvme167/lib/ -specs bsp_specs -qrtems -m68040 + +CFLAGS=-O3 -DHAVE_UNISTD_H +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=m68k-rtems-gcc --pipe -B/opt/rtems/m68k-rtems/mvme167/lib/ -specs bsp_specs -qrtems -m68040 +CPP=m68k-rtems-gcc --pipe -B/opt/rtems/m68k-rtems/mvme167/lib/ -specs bsp_specs -qrtems -m68040 -E + +VER=1.1.4 +LIBS=libz.a +SHAREDLIB=libz.so + +AR=m68k-rtems-ar cr +RANLIB=m68k-rtems-ranlib +TAR=tar +SHELL=/bin/sh + +prefix =/opt/rtems/m68k-rtems +exec_prefix =${prefix} +libdir =/opt/rtems/m68k-rtems/mvme167/lib +includedir =/opt/rtems/m68k-rtems/mvme167/lib/include + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ + algorithm.txt zlib.3 zlib.html \ + msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ + contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ + contrib/asm[56]86/*.S contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ + contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ + contrib/delphi*/*.??? + +all: example minigzip + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIB).$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIB).1 + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIB).1 + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ + rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ + (ldconfig || true) >/dev/null 2>&1; \ + fi +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + v=$(VER); \ + if test -f zlib.h; then \ + v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ + rm -f zlib.h zconf.h; \ + fi; \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIB).$$v; then \ + rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ + fi + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ + _match.s maketree + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib-1.1.4/Makefile.in b/zlib-1.1.4/Makefile.in new file mode 100644 index 0000000..531562b --- /dev/null +++ b/zlib-1.1.4/Makefile.in @@ -0,0 +1,175 @@ +# Makefile for zlib +# Copyright (C) 1995-2002 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=-L. -lz +LDSHARED=$(CC) +CPP=$(CC) -E + +VER=1.1.4 +LIBS=libz.a +SHAREDLIB=libz.so + +AR=ar rc +RANLIB=ranlib +TAR=tar +SHELL=/bin/sh + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ + algorithm.txt zlib.3 zlib.html \ + msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ + contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ + contrib/asm[56]86/*.S contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ + contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ + contrib/delphi*/*.??? + +all: example minigzip + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIB).$(VER): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIB).1 + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIB).1 + +example: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ + rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ + ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ + (ldconfig || true) >/dev/null 2>&1; \ + fi +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + v=$(VER); \ + if test -f zlib.h; then \ + v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ + rm -f zlib.h zconf.h; \ + fi; \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIB).$$v; then \ + rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ + fi + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ + _match.s maketree + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c contrib/minizip/test.zip + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib-1.1.4/Makefile.riscos b/zlib-1.1.4/Makefile.riscos new file mode 100644 index 0000000..d97f449 --- /dev/null +++ b/zlib-1.1.4/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/zlib-1.1.4/README b/zlib-1.1.4/README new file mode 100644 index 0000000..29d6714 --- /dev/null +++ b/zlib-1.1.4/README @@ -0,0 +1,147 @@ +zlib 1.1.4 is a general purpose data compression library. All the code +is thread safe. The data format used by the zlib library +is described by RFCs (Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate +format) and rfc1952.txt (gzip format). These documents are also available in +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage +example of the library is given in the file example.c which also tests that +the library is working correctly. Another example is given in the file +minigzip.c. The compression library itself is composed of all source files +except example.c and minigzip.c. + +To compile all files and run the test program, follow the instructions +given at the top of Makefile. In short "make test; make install" +should work for most machines. For Unix: "./configure; make test; make install" +For MSDOS, use one of the special makefiles such as Makefile.msc. +For VMS, use Make_vms.com or descrip.mms. + +Questions about zlib should be sent to , or to +Gilles Vollant for the Windows DLL version. +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ +Before reporting a problem, please check this site to verify that +you have the latest version of zlib; otherwise get the latest version and +check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html +before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.1.4 are documented in the file ChangeLog. +The only changes made since 1.1.3 are bug corrections: + +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +The beta version 1.1.5beta includes many more changes. A new official +version 1.1.5 will be released as soon as extensive testing has been +completed on it. + + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess +is in the CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling +is available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html + +An experimental package to read and write files in .zip format, +written on top of zlib by Gilles Vollant , is +available at http://www.winimage.com/zLibDll/unzip.html +and also in the contrib/minizip directory of zlib. + + +Notes for some targets: + +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL + The zlib DLL support was initially done by Alessandro Iacopetti and is + now maintained by Gilles Vollant . Check the zlib DLL + home page at http://www.winimage.com/zLibDll + + From Visual Basic, you can call the DLL functions which do not take + a structure as argument: compress, uncompress and all gz* functions. + See contrib/visual-basic.txt for more information, or get + http://www.tcfb.com/dowseware/cmp-z-it.zip + +- For 64-bit Irix, deflate.c must be compiled without any optimization. + With -O, one libpng test fails. The test works in 32 bit mode (with + the -n32 compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 + it works when compiled with cc. + +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 + is necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works + with other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For Turbo C the small model is supported only with reduced performance to + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 + +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html + Per Harald Myrvang + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. diff --git a/zlib-1.1.4/adler32.c b/zlib-1.1.4/adler32.c new file mode 100644 index 0000000..fae88b6 --- /dev/null +++ b/zlib-1.1.4/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/zlib-1.1.4/algorithm.txt b/zlib-1.1.4/algorithm.txt new file mode 100644 index 0000000..cdc830b --- /dev/null +++ b/zlib-1.1.4/algorithm.txt @@ -0,0 +1,213 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The real question is, given a Huffman tree, how to decode fast. The most +important realization is that shorter codes are much more common than +longer codes, so pay attention to decoding the short codes fast, and let +the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and set it +for the maximum speed. + +inflate() sends new trees relatively often, so it is possibly set for a +smaller first level table than an application that has only one tree for +all the data. For inflate, which has 286 possible codes for the +literal/length tree, the size of the first table is nine bits. Also the +distance trees have 30 possible values, and the size of the first table is +six bits. Note that for each of those cases, the table ended up one bit +longer than the ``average'' code length, i.e. the code length of an +approximately flat code which would be a little more than eight bits for +286 symbols and a little less than five bits for 30 symbols. It would be +interesting to see if optimizing the first level table for other +applications gave values within a bit or two of the flat code size. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode to and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +ftp://ds.internic.net/rfc/rfc1951.txt diff --git a/zlib-1.1.4/amiga/Makefile.pup b/zlib-1.1.4/amiga/Makefile.pup new file mode 100644 index 0000000..6cfad1d --- /dev/null +++ b/zlib-1.1.4/amiga/Makefile.pup @@ -0,0 +1,66 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 +LIBNAME = libzip.a +AR = ppc-amigaos-ar +AR_FLAGS = cr +RANLIB = ppc-amigaos-ranlib +LDFLAGS = -r -o +LDLIBS = LIB:scppc.a +LN = ppc-amigaos-ld +RM = delete quiet + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +test: all + example + echo hello world | minigzip | minigzip -d + +$(LIBNAME): $(OBJS) + $(AR) $(AR_FLAGS) $@ $(OBJS) + $(RANLIB) $@ + +example: example.o $(LIBNAME) + $(LN) $(LDFLAGS) example LIB:c_ppc.o example.o $(LIBNAME) $(LDLIBS) LIB:end.o + +minigzip: minigzip.o $(LIBNAME) + $(LN) $(LDFLAGS) minigzip LIB:c_ppc.o minigzip.o $(LIBNAME) $(LDLIBS) LIB:end.o + +clean: + $(RM) *.o example minigzip $(LIBNAME) foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ + descrip.mms *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zutil.h zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib-1.1.4/amiga/Makefile.sas b/zlib-1.1.4/amiga/Makefile.sas new file mode 100644 index 0000000..5323e82 --- /dev/null +++ b/zlib-1.1.4/amiga/Makefile.sas @@ -0,0 +1,64 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +test: all + `cd`/example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy zlib.h zconf.h INCLUDE: clone + copy z.lib LIB: clone + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +clean: + -delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Smakefile + copy to $@ 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} diff --git a/zlib-1.1.4/configure b/zlib-1.1.4/configure new file mode 100755 index 0000000..e894235 --- /dev/null +++ b/zlib-1.1.4/configure @@ -0,0 +1,212 @@ +#!/bin/sh +# configure script for zlib. This script is needed only if +# you wish to build a shared library and your system supports them, +# of if you need special compiler, flags or install directory. +# Otherwise, you can just use directly "make test; make install" +# +# To create a shared library, use "configure --shared"; by default a static +# library is created. If the primitive shared library support provided here +# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) +# LDSHARED is the command to be used to create a shared library + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +LIBS=libz.a +SHAREDLIB=libz.so +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +AR=${AR-"ar rc"} +RANLIB=${RANLIB-"ranlib"} +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +libdir=${libdir-'${exec_prefix}/lib'} +includedir=${includedir-'${prefix}/include'} +shared_ext='.so' +shared=0 +gcc=0 +old_cc="$CC" +old_cflags="$CFLAGS" + +while test $# -ge 1 +do +case "$1" in + -h* | --h*) + echo 'usage:' + echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' + echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' + exit 0;; + -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; + -p* | --p*) prefix="$2"; shift; shift;; + -e* | --e*) exec_prefix="$2"; shift; shift;; + -l* | --l*) libdir="$2"; shift; shift;; + -i* | --i*) includedir="$2"; shift; shift;; + -s* | --s*) shared=1; shift;; + esac +done + +test=ztest$$ +cat > $test.c </dev/null; then + CC="$cc" + SFLAGS=${CFLAGS-"-fPIC -O3"} + CFLAGS="$cflags" + case `(uname -s || echo unknown) 2>/dev/null` in + Linux | linux) LDSHARED=${LDSHARED-"gcc -shared -Wl,-soname,libz.so.1"};; + *) LDSHARED=${LDSHARED-"gcc -shared"};; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + case `(uname -sr || echo unknown) 2>/dev/null` in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} +# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} + LDSHARED=${LDSHARED-"ld -b"} + shared_ext='.sl' + SHAREDLIB='libz.sl';; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared"};; + OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,$SHAREDLIB -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; + OSF1*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared"};; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc -A";; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; + SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg89"} + LDSHARED=${LDSHARED-"cc -G"};; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"};; + UNIX_System_V\ 4.2.0) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"};; + UNIX_SV\ 4.2MP) + SFLAGS=${CFLAGS-"-Kconform_pic -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"};; + # send working options for other systems to support@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"};; + esac +fi + +if test $shared -eq 1; then + echo Checking for shared library support... + # we must test in two steps (cc then ld), required at least on SunOS 4.x + if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && + test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then + CFLAGS="$SFLAGS" + LIBS="$SHAREDLIB.$VER" + echo Building shared library $SHAREDLIB.$VER with $CC. + elif test -z "$old_cc" -a -z "$old_cflags"; then + echo No shared library suppport. + shared=0; + else + echo 'No shared library suppport; try without defining CC and CFLAGS' + shared=0; + fi +fi +if test $shared -eq 0; then + LDSHARED="$CC" + echo Building static library $LIBS version $VER with $CC. +fi + +cat > $test.c < +int main() { return 0; } +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" + echo "Checking for unistd.h... Yes." +else + echo "Checking for unistd.h... No." +fi + +cat > $test.c < +int main() { return 0; } +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + echo "Checking for errno.h... Yes." +else + echo "Checking for errno.h... No." + CFLAGS="$CFLAGS -DNO_ERRNO_H" +fi + +cat > $test.c < +#include +#include +caddr_t hello() { + return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); +} +EOF +if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then + CFLAGS="$CFLAGS -DUSE_MMAP" + echo Checking for mmap support... Yes. +else + echo Checking for mmap support... No. +fi + +CPP=${CPP-"$CC -E"} +case $CFLAGS in + *ASMV*) + if test "`nm $test.o | grep _hello`" = ""; then + CPP="$CPP -DNO_UNDERLINE" + echo Checking for underline in external names... No. + else + echo Checking for underline in external names... Yes. + fi;; +esac + +rm -f $test.[co] $test$shared_ext + +# udpate Makefile +sed < Makefile.in " +/^CC *=/s%=.*%=$CC% +/^CFLAGS *=/s%=.*%=$CFLAGS% +/^CPP *=/s%=.*%=$CPP% +/^LDSHARED *=/s%=.*%=$LDSHARED% +/^LIBS *=/s%=.*%=$LIBS% +/^SHAREDLIB *=/s%=.*%=$SHAREDLIB% +/^AR *=/s%=.*%=$AR% +/^RANLIB *=/s%=.*%=$RANLIB% +/^VER *=/s%=.*%=$VER% +/^prefix *=/s%=.*%=$prefix% +/^exec_prefix *=/s%=.*%=$exec_prefix% +/^libdir *=/s%=.*%=$libdir% +/^includedir *=/s%=.*%=$includedir% +" > Makefile diff --git a/zlib-1.1.4/contrib/README.contrib b/zlib-1.1.4/contrib/README.contrib new file mode 100644 index 0000000..7ad191c --- /dev/null +++ b/zlib-1.1.4/contrib/README.contrib @@ -0,0 +1,34 @@ +All files under this contrib directory are UNSUPPORTED. There were +provided by users of zlib and were not tested by the authors of zlib. +Use at your own risk. Please contact the authors of the contributions +for help about these, not the zlib authors. Thanks. + + +asm386/ by Gilles Vollant + 386 asm code replacing longest_match(), for Visual C++ 4.2 and ML 6.11c + +asm586/ and asm686/ by Brian Raiter + asm code for Pentium and Pentium Pro + See http://www.muppetlabs.com/~breadbox/software/assembly.html + +delphi/ by Bob Dellaca + Support for Delphi + +delphi2/ by Davide Moretti + Another support for C++Builder and Delphi + +minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + See http://www.winimage.com/zLibDll/unzip.html + +iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + +visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. diff --git a/zlib-1.1.4/contrib/asm386/gvmat32.asm b/zlib-1.1.4/contrib/asm386/gvmat32.asm new file mode 100644 index 0000000..28d527f --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/gvmat32.asm @@ -0,0 +1,559 @@ +; +; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. +; File written by Gilles Vollant, by modifiying the longest_match +; from Jean-loup Gailly in deflate.c +; It need wmask == 0x7fff +; (assembly code is faster with a fixed wmask) +; +; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK) +; I compile with : "ml /coff /Zi /c gvmat32.asm" +; + +;uInt longest_match_7fff(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ + + NbStack equ 76 + cur_match equ dword ptr[esp+NbStack-0] + str_s equ dword ptr[esp+NbStack-4] +; 5 dword on top (ret,ebp,esi,edi,ebx) + adrret equ dword ptr[esp+NbStack-8] + pushebp equ dword ptr[esp+NbStack-12] + pushedi equ dword ptr[esp+NbStack-16] + pushesi equ dword ptr[esp+NbStack-20] + pushebx equ dword ptr[esp+NbStack-24] + + chain_length equ dword ptr [esp+NbStack-28] + limit equ dword ptr [esp+NbStack-32] + best_len equ dword ptr [esp+NbStack-36] + window equ dword ptr [esp+NbStack-40] + prev equ dword ptr [esp+NbStack-44] + scan_start equ word ptr [esp+NbStack-48] + wmask equ dword ptr [esp+NbStack-52] + match_start_ptr equ dword ptr [esp+NbStack-56] + nice_match equ dword ptr [esp+NbStack-60] + scan equ dword ptr [esp+NbStack-64] + + windowlen equ dword ptr [esp+NbStack-68] + match_start equ dword ptr [esp+NbStack-72] + strend equ dword ptr [esp+NbStack-76] + NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + dep_chain_length equ 70h+4 + dep_window equ 2ch+4 + dep_strstart equ 60h+4 + dep_prev_length equ 6ch+4 + dep_nice_match equ 84h+4 + dep_w_size equ 20h+4 + dep_prev equ 34h+4 + dep_w_mask equ 28h+4 + dep_good_match equ 80h+4 + dep_match_start equ 64h+4 + dep_lookahead equ 68h+4 + + +_TEXT segment + +IFDEF NOUNDERLINE + public longest_match_7fff +; public match_init +ELSE + public _longest_match_7fff +; public _match_init +ENDIF + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + +IFDEF NOUNDERLINE +;match_init proc near +; ret +;match_init endp +ELSE +;_match_init proc near +; ret +;_match_init endp +ENDIF + + +IFDEF NOUNDERLINE +longest_match_7fff proc near +ELSE +_longest_match_7fff proc near +ENDIF + + mov edx,[esp+4] + + + + push ebp + push edi + push esi + push ebx + + sub esp,NbStackAdd + +; initialize or check the variables used in match.asm. + mov ebp,edx + +; chain_length = s->max_chain_length +; if (prev_length>=good_match) chain_length >>= 2 + mov edx,[ebp+dep_chain_length] + mov ebx,[ebp+dep_prev_length] + cmp [ebp+dep_good_match],ebx + ja noshr + shr edx,2 +noshr: +; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop + inc edx + mov edi,[ebp+dep_nice_match] + mov chain_length,edx + mov eax,[ebp+dep_lookahead] + cmp eax,edi +; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + jae nolookaheadnicematch + mov edi,eax +nolookaheadnicematch: +; best_len = s->prev_length + mov best_len,ebx + +; window = s->window + mov esi,[ebp+dep_window] + mov ecx,[ebp+dep_strstart] + mov window,esi + + mov nice_match,edi +; scan = window + strstart + add esi,ecx + mov scan,esi +; dx = *window + mov dx,word ptr [esi] +; bx = *(window+best_len-1) + mov bx,word ptr [esi+ebx-1] + add esi,MAX_MATCH-1 +; scan_start = *scan + mov scan_start,dx +; strend = scan + MAX_MATCH-1 + mov strend,esi +; bx = scan_end = *(window+best_len-1) + +; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +; s->strstart - (IPos)MAX_DIST(s) : NIL; + + mov esi,[ebp+dep_w_size] + sub esi,MIN_LOOKAHEAD +; here esi = MAX_DIST(s) + sub ecx,esi + ja nodist + xor ecx,ecx +nodist: + mov limit,ecx + +; prev = s->prev + mov edx,[ebp+dep_prev] + mov prev,edx + +; + mov edx,dword ptr [ebp+dep_match_start] + mov bp,scan_start + mov eax,cur_match + mov match_start,edx + + mov edx,window + mov edi,edx + add edi,best_len + mov esi,prev + dec edi +; windowlen = window + best_len -1 + mov windowlen,edi + + jmp beginloop2 + align 4 + +; here, in the loop +; eax = ax = cur_match +; ecx = limit +; bx = scan_end +; bp = scan_start +; edi = windowlen (window + best_len -1) +; esi = prev + + +;// here; chain_length <=16 +normalbeg0add16: + add chain_length,16 + jz exitloop +normalbeg0: + cmp word ptr[edi+eax],bx + je normalbeg2noroll +rcontlabnoroll: +; cur_match = prev[cur_match & wmask] + and eax,7fffh + mov ax,word ptr[esi+eax*2] +; if cur_match > limit, go to exitloop + cmp ecx,eax + jnb exitloop +; if --chain_length != 0, go to exitloop + dec chain_length + jnz normalbeg0 + jmp exitloop + +normalbeg2noroll: +; if (scan_start==*(cur_match+window)) goto normalbeg2 + cmp bp,word ptr[edx+eax] + jne rcontlabnoroll + jmp normalbeg2 + +contloop3: + mov edi,windowlen + +; cur_match = prev[cur_match & wmask] + and eax,7fffh + mov ax,word ptr[esi+eax*2] +; if cur_match > limit, go to exitloop + cmp ecx,eax +jnbexitloopshort1: + jnb exitloop +; if --chain_length != 0, go to exitloop + + +; begin the main loop +beginloop2: + sub chain_length,16+1 +; if chain_length <=16, don't use the unrolled loop + jna normalbeg0add16 + +do16: + cmp word ptr[edi+eax],bx + je normalbeg2dc0 + +maccn MACRO lab + and eax,7fffh + mov ax,word ptr[esi+eax*2] + cmp ecx,eax + jnb exitloop + cmp word ptr[edi+eax],bx + je lab + ENDM + +rcontloop0: + maccn normalbeg2dc1 + +rcontloop1: + maccn normalbeg2dc2 + +rcontloop2: + maccn normalbeg2dc3 + +rcontloop3: + maccn normalbeg2dc4 + +rcontloop4: + maccn normalbeg2dc5 + +rcontloop5: + maccn normalbeg2dc6 + +rcontloop6: + maccn normalbeg2dc7 + +rcontloop7: + maccn normalbeg2dc8 + +rcontloop8: + maccn normalbeg2dc9 + +rcontloop9: + maccn normalbeg2dc10 + +rcontloop10: + maccn short normalbeg2dc11 + +rcontloop11: + maccn short normalbeg2dc12 + +rcontloop12: + maccn short normalbeg2dc13 + +rcontloop13: + maccn short normalbeg2dc14 + +rcontloop14: + maccn short normalbeg2dc15 + +rcontloop15: + and eax,7fffh + mov ax,word ptr[esi+eax*2] + cmp ecx,eax + jnb exitloop + + sub chain_length,16 + ja do16 + jmp normalbeg0add16 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +normbeg MACRO rcontlab,valsub +; if we are here, we know that *(match+best_len-1) == scan_end + cmp bp,word ptr[edx+eax] +; if (match != scan_start) goto rcontlab + jne rcontlab +; calculate the good chain_length, and we'll compare scan and match string + add chain_length,16-valsub + jmp iseq + ENDM + + +normalbeg2dc11: + normbeg rcontloop11,11 + +normalbeg2dc12: + normbeg short rcontloop12,12 + +normalbeg2dc13: + normbeg short rcontloop13,13 + +normalbeg2dc14: + normbeg short rcontloop14,14 + +normalbeg2dc15: + normbeg short rcontloop15,15 + +normalbeg2dc10: + normbeg rcontloop10,10 + +normalbeg2dc9: + normbeg rcontloop9,9 + +normalbeg2dc8: + normbeg rcontloop8,8 + +normalbeg2dc7: + normbeg rcontloop7,7 + +normalbeg2dc6: + normbeg rcontloop6,6 + +normalbeg2dc5: + normbeg rcontloop5,5 + +normalbeg2dc4: + normbeg rcontloop4,4 + +normalbeg2dc3: + normbeg rcontloop3,3 + +normalbeg2dc2: + normbeg rcontloop2,2 + +normalbeg2dc1: + normbeg rcontloop1,1 + +normalbeg2dc0: + normbeg rcontloop0,0 + + +; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end + +normalbeg2: + mov edi,window + + cmp bp,word ptr[edi+eax] + jne contloop3 ; if *(ushf*)match != scan_start, continue + +iseq: +; if we are here, we know that *(match+best_len-1) == scan_end +; and (match == scan_start) + + mov edi,edx + mov esi,scan ; esi = scan + add edi,eax ; edi = window + cur_match = match + + mov edx,[esi+3] ; compare manually dword at match+3 + xor edx,[edi+3] ; and scan +3 + + jz begincompare ; if equal, go to long compare + +; we will determine the unmatch byte and calculate len (in esi) + or dl,dl + je eq1rr + mov esi,3 + jmp trfinval +eq1rr: + or dx,dx + je eq1 + + mov esi,4 + jmp trfinval +eq1: + and edx,0ffffffh + jz eq11 + mov esi,5 + jmp trfinval +eq11: + mov esi,6 + jmp trfinval + +begincompare: + ; here we now scan and match begin same + add edi,6 + add esi,6 + mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes + repe cmpsd ; loop until mismatch + + je trfin ; go to trfin if not unmatch +; we determine the unmatch byte + sub esi,4 + mov edx,[edi-4] + xor edx,[esi] + + or dl,dl + jnz trfin + inc esi + + or dx,dx + jnz trfin + inc esi + + and edx,0ffffffh + jnz trfin + inc esi + +trfin: + sub esi,scan ; esi = len +trfinval: +; here we have finised compare, and esi contain len of equal string + cmp esi,best_len ; if len > best_len, go newbestlen + ja short newbestlen +; now we restore edx, ecx and esi, for the big loop + mov esi,prev + mov ecx,limit + mov edx,window + jmp contloop3 + +newbestlen: + mov best_len,esi ; len become best_len + + mov match_start,eax ; save new position as match_start + cmp esi,nice_match ; if best_len >= nice_match, exit + jae exitloop + mov ecx,scan + mov edx,window ; restore edx=window + add ecx,esi + add esi,edx + + dec esi + mov windowlen,esi ; windowlen = window + best_len-1 + mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end + +; now we restore ecx and esi, for the big loop : + mov esi,prev + mov ecx,limit + jmp contloop3 + +exitloop: +; exit : s->match_start=match_start + mov ebx,match_start + mov ebp,str_s + mov ecx,best_len + mov dword ptr [ebp+dep_match_start],ebx + mov eax,dword ptr [ebp+dep_lookahead] + cmp ecx,eax + ja minexlo + mov eax,ecx +minexlo: +; return min(best_len,s->lookahead) + +; restore stack and register ebx,esi,edi,ebp + add esp,NbStackAdd + + pop ebx + pop esi + pop edi + pop ebp + ret +InfoAuthor: +; please don't remove this string ! +; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary! + db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah + + + +IFDEF NOUNDERLINE +longest_match_7fff endp +ELSE +_longest_match_7fff endp +ENDIF + + +IFDEF NOUNDERLINE +cpudetect32 proc near +ELSE +_cpudetect32 proc near +ENDIF + + + pushfd ; push original EFLAGS + pop eax ; get original EFLAGS + mov ecx, eax ; save original EFLAGS + xor eax, 40000h ; flip AC bit in EFLAGS + push eax ; save new EFLAGS value on stack + popfd ; replace current EFLAGS value + pushfd ; get new EFLAGS + pop eax ; store new EFLAGS in EAX + xor eax, ecx ; can’t toggle AC bit, processor=80386 + jz end_cpu_is_386 ; jump if 80386 processor + push ecx + popfd ; restore AC bit in EFLAGS first + + pushfd + pushfd + pop ecx + + mov eax, ecx ; get original EFLAGS + xor eax, 200000h ; flip ID bit in EFLAGS + push eax ; save new EFLAGS value on stack + popfd ; replace current EFLAGS value + pushfd ; get new EFLAGS + pop eax ; store new EFLAGS in EAX + popfd ; restore original EFLAGS + xor eax, ecx ; can’t toggle ID bit, + je is_old_486 ; processor=old + + mov eax,1 + db 0fh,0a2h ;CPUID + +exitcpudetect: + ret + +end_cpu_is_386: + mov eax,0300h + jmp exitcpudetect + +is_old_486: + mov eax,0400h + jmp exitcpudetect + +IFDEF NOUNDERLINE +cpudetect32 endp +ELSE +_cpudetect32 endp +ENDIF + +_TEXT ends +end diff --git a/zlib-1.1.4/contrib/asm386/gvmat32c.c b/zlib-1.1.4/contrib/asm386/gvmat32c.c new file mode 100644 index 0000000..d853bb7 --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/gvmat32c.c @@ -0,0 +1,200 @@ +/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86 + * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. + * File written by Gilles Vollant, by modifiying the longest_match + * from Jean-loup Gailly in deflate.c + * it prepare all parameters and call the assembly longest_match_gvasm + * longest_match execute standard C code is wmask != 0x7fff + * (assembly code is faster with a fixed wmask) + * + */ + +#include "deflate.h" + +#undef FAR +#include + +#ifdef ASMV +#define NIL 0 + +#define UNALIGNED_OK + + +/* if your C compiler don't add underline before function name, + define ADD_UNDERLINE_ASMFUNC */ +#ifdef ADD_UNDERLINE_ASMFUNC +#define longest_match_7fff _longest_match_7fff +#endif + + + +void match_init() +{ +} + +unsigned long cpudetect32(); + +uInt longest_match_c( + deflate_state *s, + IPos cur_match); /* current match */ + + +uInt longest_match_7fff( + deflate_state *s, + IPos cur_match); /* current match */ + +uInt longest_match( + deflate_state *s, + IPos cur_match) /* current match */ +{ + static uInt iIsPPro=2; + + if ((s->w_mask == 0x7fff) && (iIsPPro==0)) + return longest_match_7fff(s,cur_match); + + if (iIsPPro==2) + iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0; + + return longest_match_c(s,cur_match); +} + + + +uInt longest_match_c(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#endif /* ASMV */ diff --git a/zlib-1.1.4/contrib/asm386/mkgvmt32.bat b/zlib-1.1.4/contrib/asm386/mkgvmt32.bat new file mode 100644 index 0000000..6c5ffd7 --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/mkgvmt32.bat @@ -0,0 +1 @@ +c:\masm611\bin\ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm diff --git a/zlib-1.1.4/contrib/asm386/zlibvc.def b/zlib-1.1.4/contrib/asm386/zlibvc.def new file mode 100644 index 0000000..7e9d60d --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/zlibvc.def @@ -0,0 +1,74 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + + +VERSION 1.11 + + +HEAPSIZE 1048576,8192 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/zlib-1.1.4/contrib/asm386/zlibvc.dsp b/zlib-1.1.4/contrib/asm386/zlibvc.dsp new file mode 100644 index 0000000..a70d4d4 --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/zlib-1.1.4/contrib/asm386/zlibvc.dsw b/zlib-1.1.4/contrib/asm386/zlibvc.dsw new file mode 100644 index 0000000..493cd87 --- /dev/null +++ b/zlib-1.1.4/contrib/asm386/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/zlib-1.1.4/contrib/asm586/README.586 b/zlib-1.1.4/contrib/asm586/README.586 new file mode 100644 index 0000000..6bb78f3 --- /dev/null +++ b/zlib-1.1.4/contrib/asm586/README.586 @@ -0,0 +1,43 @@ +This is a patched version of zlib modified to use +Pentium-optimized assembly code in the deflation algorithm. The files +changed/added by this patch are: + +README.586 +match.S + +The effectiveness of these modifications is a bit marginal, as the the +program's bottleneck seems to be mostly L1-cache contention, for which +there is no real way to work around without rewriting the basic +algorithm. The speedup on average is around 5-10% (which is generally +less than the amount of variance between subsequent executions). +However, when used at level 9 compression, the cache contention can +drop enough for the assembly version to achieve 10-20% speedup (and +sometimes more, depending on the amount of overall redundancy in the +files). Even here, though, cache contention can still be the limiting +factor, depending on the nature of the program using the zlib library. +This may also mean that better improvements will be seen on a Pentium +with MMX, which suffers much less from L1-cache contention, but I have +not yet verified this. + +Note that this code has been tailored for the Pentium in particular, +and will not perform well on the Pentium Pro (due to the use of a +partial register in the inner loop). + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o diff --git a/zlib-1.1.4/contrib/asm586/match.S b/zlib-1.1.4/contrib/asm586/match.S new file mode 100644 index 0000000..8f16140 --- /dev/null +++ b/zlib-1.1.4/contrib/asm586/match.S @@ -0,0 +1,354 @@ +/* match.s -- Pentium-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define wmask 0 /* local copy of s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define chainlenscanend 12 /* high word: current chain len */ + /* low word: last bytes sought */ +#define scanstart 16 /* first two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the scanend */ +/* scanend value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ + + movw (%edi), %bx + movw %bx, scanstart(%esp) + movw -1(%edi,%eax), %bx + movl %ebx, chainlenscanend(%esp) + +/* Posf *prev = s->prev; */ +/* uInt wmask = s->w_mask; */ + + movl dsPrev(%edx), %edi + movl dsWMask(%edx), %edx + mov %edx, wmask(%esp) + +/* Jump into the main loop. */ + + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) + * %ecx = curmatch + * %edx = curmatch & wmask + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + * + * Two optimization notes on the choice of instructions: + * + * The first instruction uses a 16-bit address, which costs an extra, + * unpairable cycle. This is cheaper than doing a 32-bit access and + * zeroing the high word, due to the 3-cycle misalignment penalty which + * would occur half the time. This also turns out to be cheaper than + * doing two separate 8-bit accesses, as the memory is so rarely in the + * L1 cache. + * + * The window buffer, however, apparently spends a lot of time in the + * cache, and so it is faster to retrieve the word at the end of the + * match string with two 8-bit loads. The instructions that test the + * word at the beginning of the match string, however, are executed + * much less frequently, and there it was cheaper to use 16-bit + * instructions, which avoided the necessity of saving off and + * subsequently reloading one of the other registers. + */ +LookupLoop: + /* 1 U & V */ + movw (%edi,%edx,2), %cx /* 2 U pipe */ + movl wmask(%esp), %edx /* 2 V pipe */ + cmpl %ebp, %ecx /* 3 U pipe */ + jbe LeaveNow /* 3 V pipe */ + subl $0x00010000, %ebx /* 4 U pipe */ + js LeaveNow /* 4 V pipe */ +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ + andl %ecx, %edx /* 5 V pipe */ + cmpb %bl, %al /* 6 U pipe */ + jnz LookupLoop /* 6 V pipe */ + movb (%esi,%ecx), %ah + cmpb %bh, %ah + jnz LookupLoop + movl window(%esp), %eax + movw (%eax,%ecx), %ax + cmpw scanstart(%esp), %ax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %ebx, chainlenscanend(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + movl (%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + movl 4(%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl chainlenscanend(%esp), %ebx + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movl chainlenscanend(%esp), %ebx + movw -1(%edi,%eax), %bx + movl dsPrev(%edx), %edi + movl %ebx, chainlenscanend(%esp) + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff --git a/zlib-1.1.4/contrib/asm686/README.686 b/zlib-1.1.4/contrib/asm686/README.686 new file mode 100644 index 0000000..a593f23 --- /dev/null +++ b/zlib-1.1.4/contrib/asm686/README.686 @@ -0,0 +1,34 @@ +This is a patched version of zlib, modified to use +Pentium-Pro-optimized assembly code in the deflation algorithm. The +files changed/added by this patch are: + +README.686 +match.S + +The speedup that this patch provides varies, depending on whether the +compiler used to build the original version of zlib falls afoul of the +PPro's speed traps. My own tests show a speedup of around 10-20% at +the default compression level, and 20-30% using -9, against a version +compiled using gcc 2.7.2.3. Your mileage may vary. + +Note that this code has been tailored for the PPro/PII in particular, +and will not perform particuarly well on a Pentium. + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o diff --git a/zlib-1.1.4/contrib/asm686/match.S b/zlib-1.1.4/contrib/asm686/match.S new file mode 100644 index 0000000..8e86c33 --- /dev/null +++ b/zlib-1.1.4/contrib/asm686/match.S @@ -0,0 +1,327 @@ +/* match.s -- Pentium-Pro-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff --git a/zlib-1.1.4/contrib/delphi/zlib.mak b/zlib-1.1.4/contrib/delphi/zlib.mak new file mode 100644 index 0000000..ba557e2 --- /dev/null +++ b/zlib-1.1.4/contrib/delphi/zlib.mak @@ -0,0 +1,36 @@ +# Makefile for zlib32bd.lib +# ------------- Borland C++ 4.5 ------------- + +# The (32-bit) zlib32bd.lib made with this makefile is intended for use +# in making the (32-bit) DLL, png32bd.dll. It uses the "stdcall" calling +# convention. + +CFLAGS= -ps -O2 -C -K -N- -k- -d -3 -r- -w-par -w-aus -WDE +CC=f:\bc45\bin\bcc32 +LIBFLAGS= /C +LIB=f:\bc45\bin\tlib +ZLIB=zlib32bd.lib + +.autodepend +.c.obj: + $(CC) -c $(CFLAGS) $< + +OBJ1=adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj +OBJ2=infcodes.obj inflate.obj inftrees.obj infutil.obj inffast.obj +OBJ3=trees.obj uncompr.obj zutil.obj +pOBJ1=+adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infblock.obj +pOBJ2=+infcodes.obj+inflate.obj+inftrees.obj+infutil.obj+inffast.obj +pOBJ3=+trees.obj+uncompr.obj+zutil.obj + +all: $(ZLIB) + +$(ZLIB): $(OBJ1) $(OBJ2) $(OBJ3) + @if exist $@ del $@ + $(LIB) @&&| +$@ $(LIBFLAGS) & +$(pOBJ1) & +$(pOBJ2) & +$(pOBJ3) +| + +# End of makefile for zlib32bd.lib diff --git a/zlib-1.1.4/contrib/delphi/zlibdef.pas b/zlib-1.1.4/contrib/delphi/zlibdef.pas new file mode 100644 index 0000000..4f96b7d --- /dev/null +++ b/zlib-1.1.4/contrib/delphi/zlibdef.pas @@ -0,0 +1,169 @@ +unit zlibdef; + +interface + +uses + Windows; + +const + ZLIB_VERSION = '1.1.3'; + +type + voidpf = Pointer; + int = Integer; + uInt = Cardinal; + pBytef = PChar; + uLong = Cardinal; + + alloc_func = function(opaque: voidpf; items, size: uInt): voidpf; + stdcall; + free_func = procedure(opaque, address: voidpf); + stdcall; + + internal_state = Pointer; + + z_streamp = ^z_stream; + z_stream = packed record + next_in: pBytef; // next input byte + avail_in: uInt; // number of bytes available at next_in + total_in: uLong; // total nb of input bytes read so far + + next_out: pBytef; // next output byte should be put there + avail_out: uInt; // remaining free space at next_out + total_out: uLong; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + state: internal_state; // not visible by applications + + zalloc: alloc_func; // used to allocate the internal state + zfree: free_func; // used to free the internal state + opaque: voidpf; // private data object passed to zalloc and zfree + + data_type: int; // best guess about the data type: ascii or binary + adler: uLong; // adler32 value of the uncompressed data + reserved: uLong; // reserved for future use + end; + +const + Z_NO_FLUSH = 0; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + MAX_MEM_LEVEL = 9; + +function adler32(adler: uLong; const buf: pBytef; len: uInt): uLong; + stdcall; +function crc32(crc: uLong; const buf: pBytef; len: uInt): uLong; + stdcall; +function deflate(strm: z_streamp; flush: int): int; + stdcall; +function deflateCopy(dest, source: z_streamp): int; + stdcall; +function deflateEnd(strm: z_streamp): int; + stdcall; +function deflateInit2_(strm: z_streamp; level, method, + windowBits, memLevel, strategy: int; + const version: PChar; stream_size: int): int; + stdcall; +function deflateInit_(strm: z_streamp; level: int; + const version: PChar; stream_size: int): int; + stdcall; +function deflateParams(strm: z_streamp; level, strategy: int): int; + stdcall; +function deflateReset(strm: z_streamp): int; + stdcall; +function deflateSetDictionary(strm: z_streamp; + const dictionary: pBytef; + dictLength: uInt): int; + stdcall; +function inflate(strm: z_streamp; flush: int): int; + stdcall; +function inflateEnd(strm: z_streamp): int; + stdcall; +function inflateInit2_(strm: z_streamp; windowBits: int; + const version: PChar; stream_size: int): int; + stdcall; +function inflateInit_(strm: z_streamp; const version: PChar; + stream_size: int): int; + stdcall; +function inflateReset(strm: z_streamp): int; + stdcall; +function inflateSetDictionary(strm: z_streamp; + const dictionary: pBytef; + dictLength: uInt): int; + stdcall; +function inflateSync(strm: z_streamp): int; + stdcall; + +function deflateInit(strm: z_streamp; level: int): int; +function deflateInit2(strm: z_streamp; level, method, windowBits, + memLevel, strategy: int): int; +function inflateInit(strm: z_streamp): int; +function inflateInit2(strm: z_streamp; windowBits: int): int; + +implementation + +function deflateInit(strm: z_streamp; level: int): int; +begin + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(strm: z_streamp; level, method, windowBits, + memLevel, strategy: int): int; +begin + Result := deflateInit2_(strm, level, method, windowBits, memLevel, + strategy, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(strm: z_streamp): int; +begin + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2(strm: z_streamp; windowBits: int): int; +begin + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, + sizeof(z_stream)); +end; + +const + zlibDLL = 'png32bd.dll'; + +function adler32; external zlibDLL; +function crc32; external zlibDLL; +function deflate; external zlibDLL; +function deflateCopy; external zlibDLL; +function deflateEnd; external zlibDLL; +function deflateInit2_; external zlibDLL; +function deflateInit_; external zlibDLL; +function deflateParams; external zlibDLL; +function deflateReset; external zlibDLL; +function deflateSetDictionary; external zlibDLL; +function inflate; external zlibDLL; +function inflateEnd; external zlibDLL; +function inflateInit2_; external zlibDLL; +function inflateInit_; external zlibDLL; +function inflateReset; external zlibDLL; +function inflateSetDictionary; external zlibDLL; +function inflateSync; external zlibDLL; + +end. diff --git a/zlib-1.1.4/contrib/delphi2/d_zlib.bpr b/zlib-1.1.4/contrib/delphi2/d_zlib.bpr new file mode 100644 index 0000000..78bb254 --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/d_zlib.bpr @@ -0,0 +1,224 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = d_zlib.lib +OBJFILES = d_zlib.obj adler32.obj deflate.obj infblock.obj infcodes.obj inffast.obj \ + inflate.obj inftrees.obj infutil.obj trees.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = VCL35.lib +SPARELIBS = VCL35.lib +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -O2 -Ve -d -k- -vi +CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm +CFLAG3 = -ff -pr -5 +PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn +LFLAGS = +IFLAGS = -g -Gn +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include +Item1=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + + --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = TLib +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include;$(BCB)\include\vcl +Item1=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/zlib-1.1.4/contrib/delphi2/d_zlib.cpp b/zlib-1.1.4/contrib/delphi2/d_zlib.cpp new file mode 100644 index 0000000..f5dea59 --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/d_zlib.cpp @@ -0,0 +1,17 @@ +#include +#pragma hdrstop +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("deflate.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +//--------------------------------------------------------------------------- +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + diff --git a/zlib-1.1.4/contrib/delphi2/readme.txt b/zlib-1.1.4/contrib/delphi2/readme.txt new file mode 100644 index 0000000..cbd3162 --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/readme.txt @@ -0,0 +1,17 @@ +These are files used to compile zlib under Borland C++ Builder 3. + +zlib.bpg is the main project group that can be loaded in the BCB IDE and +loads all other *.bpr projects + +zlib.bpr is a project used to create a static zlib.lib library with C calling +convention for functions. + +zlib32.bpr creates a zlib32.dll dynamic link library with Windows standard +calling convention. + +d_zlib.bpr creates a set of .obj files with register calling convention. +These files are used by zlib.pas to create a Delphi unit containing zlib. +The d_zlib.lib file generated isn't useful and can be deleted. + +zlib.cpp, zlib32.cpp and d_zlib.cpp are used by the above projects. + diff --git a/zlib-1.1.4/contrib/delphi2/zlib.bpg b/zlib-1.1.4/contrib/delphi2/zlib.bpg new file mode 100644 index 0000000..b6c9acd --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib.bpg @@ -0,0 +1,26 @@ +#------------------------------------------------------------------------------ +VERSION = BWS.01 +#------------------------------------------------------------------------------ +!ifndef ROOT +ROOT = $(MAKEDIR)\.. +!endif +#------------------------------------------------------------------------------ +MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$** +DCC = $(ROOT)\bin\dcc32.exe $** +BRCC = $(ROOT)\bin\brcc32.exe $** +#------------------------------------------------------------------------------ +PROJECTS = zlib zlib32 d_zlib +#------------------------------------------------------------------------------ +default: $(PROJECTS) +#------------------------------------------------------------------------------ + +zlib: zlib.bpr + $(MAKE) + +zlib32: zlib32.bpr + $(MAKE) + +d_zlib: d_zlib.bpr + $(MAKE) + + diff --git a/zlib-1.1.4/contrib/delphi2/zlib.bpr b/zlib-1.1.4/contrib/delphi2/zlib.bpr new file mode 100644 index 0000000..cf3945b --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib.bpr @@ -0,0 +1,225 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = zlib.lib +OBJFILES = zlib.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \ + infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \ + uncompr.obj zutil.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = VCL35.lib +SPARELIBS = VCL35.lib +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -O2 -Ve -d -k- -vi +CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm +CFLAG3 = -ff -5 +PFLAGS = -U;$(DEBUGLIBPATH) -I$(BCB)\include;$(BCB)\include\vcl -H -W -$I- -v -JPHN -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn +LFLAGS = +IFLAGS = -g -Gn +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include +Item1=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + + --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = TLib +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=2 +Item0=$(BCB)\include;$(BCB)\include\vcl +Item1=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/zlib-1.1.4/contrib/delphi2/zlib.cpp b/zlib-1.1.4/contrib/delphi2/zlib.cpp new file mode 100644 index 0000000..bf6953b --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib.cpp @@ -0,0 +1,22 @@ +#include +#pragma hdrstop +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("compress.c"); +USEUNIT("crc32.c"); +USEUNIT("deflate.c"); +USEUNIT("gzio.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +USEUNIT("uncompr.c"); +USEUNIT("zutil.c"); +//--------------------------------------------------------------------------- +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + diff --git a/zlib-1.1.4/contrib/delphi2/zlib.pas b/zlib-1.1.4/contrib/delphi2/zlib.pas new file mode 100644 index 0000000..10ae4ca --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib.pas @@ -0,0 +1,534 @@ +{*******************************************************} +{ } +{ Delphi Supplemental Components } +{ ZLIB Data Compression Interface Unit } +{ } +{ Copyright (c) 1997 Borland International } +{ } +{*******************************************************} + +{ Modified for zlib 1.1.3 by Davide Moretti Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, sizeof(strm), 0); + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then + OutBytes := BufInc + else + OutBytes := OutEstimate; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +// TCustomZlibStream + +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; +end; + +procedure TCustomZLibStream.Progress(Sender: TObject); +begin + if Assigned(FOnProgress) then FOnProgress(Sender); +end; + + +// TCompressionStream + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream); +const + Levels: array [TCompressionLevel] of ShortInt = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); +begin + inherited Create(Dest); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) + and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + end; + if FZRec.avail_out < sizeof(FBuffer) then + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + raise ECompressionError.Create('Invalid stream operation'); +end; + +function TCompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + FZRec.next_in := @Buffer; + FZRec.avail_in := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_in > 0) do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + FStrmPos := FStrm.Position; + Progress(Self); + end; + end; + Result := Count; +end; + +function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + if (Offset = 0) and (Origin = soFromCurrent) then + Result := FZRec.total_in + else + raise ECompressionError.Create('Invalid stream operation'); +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then + Result := 0 + else + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; +end; + + +// TDecompressionStream + +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); +end; + +destructor TDecompressionStream.Destroy; +begin + inflateEnd(FZRec); + inherited Destroy; +end; + +function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + FZRec.next_out := @Buffer; + FZRec.avail_out := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_out > 0) do + begin + if FZRec.avail_in = 0 then + begin + FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); + if FZRec.avail_in = 0 then + begin + Result := Count - FZRec.avail_out; + Exit; + end; + FZRec.next_in := FBuffer; + FStrmPos := FStrm.Position; + Progress(Self); + end; + DCheck(inflate(FZRec, 0)); + end; + Result := Count; +end; + +function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + raise EDecompressionError.Create('Invalid stream operation'); +end; + +function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +var + I: Integer; + Buf: array [0..4095] of Char; +begin + if (Offset = 0) and (Origin = soFromBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + FStrm.Position := 0; + FStrmPos := 0; + end + else if ( (Offset >= 0) and (Origin = soFromCurrent)) or + ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then + begin + if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); + if Offset > 0 then + begin + for I := 1 to Offset div sizeof(Buf) do + ReadBuffer(Buf, sizeof(Buf)); + ReadBuffer(Buf, Offset mod sizeof(Buf)); + end; + end + else + raise EDecompressionError.Create('Invalid stream operation'); + Result := FZRec.total_out; +end; + +end. diff --git a/zlib-1.1.4/contrib/delphi2/zlib32.bpr b/zlib-1.1.4/contrib/delphi2/zlib32.bpr new file mode 100644 index 0000000..cabcec4 --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib32.bpr @@ -0,0 +1,174 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = zlib32.dll +OBJFILES = zlib32.obj adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj \ + infcodes.obj inffast.obj inflate.obj inftrees.obj infutil.obj trees.obj \ + uncompr.obj zutil.obj +RESFILES = +RESDEPEN = $(RESFILES) +LIBFILES = +LIBRARIES = +SPARELIBS = +DEFFILE = +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi ibsmp35.bpi bcbsmp35.bpi \ + dclocx35.bpi QRPT35.bpi TEEUI35.bpi TEEDB35.bpi TEE35.bpi DSS35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi VCLMID35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -WD -O2 -Ve -d -k- -vi -c -tWD +CFLAG2 = -D_NO_VCL;ZLIB_DLL -I$(BCB)\include +CFLAG3 = -ff -5 +PFLAGS = -D_NO_VCL;ZLIB_DLL -U$(BCB)\lib;$(RELEASELIBPATH) -I$(BCB)\include -$I- -v \ + -JPHN -M +RFLAGS = -D_NO_VCL;ZLIB_DLL -i$(BCB)\include +AFLAGS = /i$(BCB)\include /d_NO_VCL /dZLIB_DLL /mx /w2 /zn +LFLAGS = -L$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpd -x -Gi +IFLAGS = -Gn -g +# --------------------------------------------------------------------------- +ALLOBJ = c0d32.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) import32.lib cw32mt.lib +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=1 +Locale=1040 +CodePage=1252 + +[Version Info Keys] +CompanyName= +FileDescription=DLL (GUI) +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=1 +Item0=$(BCB)\include + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib + +[HistoryLists\hlConditionals] +Count=1 +Item0=_NO_VCL;ZLIB_DLL + +[Debugging] +DebugSourceDirs= + +[Parameters] +RunParams= +HostApplication= + +!endif + +# --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = ilink32 +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) $(IFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- diff --git a/zlib-1.1.4/contrib/delphi2/zlib32.cpp b/zlib-1.1.4/contrib/delphi2/zlib32.cpp new file mode 100644 index 0000000..7372f6b --- /dev/null +++ b/zlib-1.1.4/contrib/delphi2/zlib32.cpp @@ -0,0 +1,42 @@ + +#include +#pragma hdrstop +#include + + +//--------------------------------------------------------------------------- +// Important note about DLL memory management in a VCL DLL: +// +// +// +// If your DLL uses VCL and exports any functions that pass VCL String objects +// (or structs/classes containing nested Strings) as parameter or function +// results, you will need to build both your DLL project and any EXE projects +// that use your DLL with the dynamic RTL (the RTL DLL). This will change your +// DLL and its calling EXE's to use BORLNDMM.DLL as their memory manager. In +// these cases, the file BORLNDMM.DLL should be deployed along with your DLL +// and the RTL DLL (CP3240MT.DLL). To avoid the requiring BORLNDMM.DLL in +// these situations, pass string information using "char *" or ShortString +// parameters and then link with the static RTL. +// +//--------------------------------------------------------------------------- +USEUNIT("adler32.c"); +USEUNIT("compress.c"); +USEUNIT("crc32.c"); +USEUNIT("deflate.c"); +USEUNIT("gzio.c"); +USEUNIT("infblock.c"); +USEUNIT("infcodes.c"); +USEUNIT("inffast.c"); +USEUNIT("inflate.c"); +USEUNIT("inftrees.c"); +USEUNIT("infutil.c"); +USEUNIT("trees.c"); +USEUNIT("uncompr.c"); +USEUNIT("zutil.c"); +//--------------------------------------------------------------------------- +#pragma argsused +int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) +{ + return 1; +} diff --git a/zlib-1.1.4/contrib/iostream/test.cpp b/zlib-1.1.4/contrib/iostream/test.cpp new file mode 100644 index 0000000..7d265b3 --- /dev/null +++ b/zlib-1.1.4/contrib/iostream/test.cpp @@ -0,0 +1,24 @@ + +#include "zfstream.h" + +int main() { + + // Construct a stream object with this filebuffer. Anything sent + // to this stream will go to standard out. + gzofstream os( 1, ios::out ); + + // This text is getting compressed and sent to stdout. + // To prove this, run 'test | zcat'. + os << "Hello, Mommy" << endl; + + os << setcompressionlevel( Z_NO_COMPRESSION ); + os << "hello, hello, hi, ho!" << endl; + + setcompressionlevel( os, Z_DEFAULT_COMPRESSION ) + << "I'm compressing again" << endl; + + os.close(); + + return 0; + +} diff --git a/zlib-1.1.4/contrib/iostream/zfstream.cpp b/zlib-1.1.4/contrib/iostream/zfstream.cpp new file mode 100644 index 0000000..a690bbe --- /dev/null +++ b/zlib-1.1.4/contrib/iostream/zfstream.cpp @@ -0,0 +1,329 @@ + +#include +#include "zfstream.h" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( short comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( short comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() { + + return &buffer; + +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/zlib-1.1.4/contrib/iostream/zfstream.h b/zlib-1.1.4/contrib/iostream/zfstream.h new file mode 100644 index 0000000..c87fa08 --- /dev/null +++ b/zlib-1.1.4/contrib/iostream/zfstream.h @@ -0,0 +1,142 @@ + +#ifndef _zfstream_h +#define _zfstream_h + +#include +#include "zlib.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( short comp_level ); + int setcompressionstrategy( short comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + + friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + +private: + gzfilebuf *rdbuf(); + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator<<(gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, + const gzomanip &m) { + return (*m.func)(s, m.val); + +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif + + + + + + + + + + + + + + + diff --git a/zlib-1.1.4/contrib/iostream2/zstream.h b/zlib-1.1.4/contrib/iostream2/zstream.h new file mode 100644 index 0000000..861ef2b --- /dev/null +++ b/zlib-1.1.4/contrib/iostream2/zstream.h @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 1997 + * Christian Michelsen Research AS + * Advanced Computing + * Fantoftvegen 38, 5036 BERGEN, Norway + * http://www.cmr.no + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Christian Michelsen Research AS makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef ZSTREAM__H +#define ZSTREAM__H + +/* + * zstream.h - C++ interface to the 'zlib' general purpose compression library + * $Id$ + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(_WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +class zstringlen { +public: + zstringlen(class izstream&); + zstringlen(class ozstream&, const char*); + size_t value() const { return val.word; } +private: + struct Val { unsigned char byte; size_t word; } val; +}; + +// ----------------------------- izstream ----------------------------- + +class izstream +{ + public: + izstream() : m_fp(0) {} + izstream(FILE* fp) : m_fp(0) { open(fp); } + izstream(const char* name) : m_fp(0) { open(name); } + ~izstream() { close(); } + + /* Opens a gzip (.gz) file for reading. + * open() can be used to read a file which is not in gzip format; + * in this case read() will directly read from the file without + * decompression. errno can be checked to distinguish two error + * cases (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name) { + if (m_fp) close(); + m_fp = ::gzopen(name, "rb"); + } + + void open(FILE* fp) { + SET_BINARY_MODE(fp); + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), "rb"); + } + + /* Flushes all pending input if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + int r = ::gzclose(m_fp); + m_fp = 0; return r; + } + + /* Binary read the given number of bytes from the compressed file. + */ + int read(void* buf, size_t len) { + return ::gzread(m_fp, buf, len); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + private: + gzFile m_fp; +}; + +/* + * Binary read the given (array of) object(s) from the compressed file. + * If the input file was not in gzip format, read() copies the objects number + * of bytes into the buffer. + * returns the number of uncompressed bytes actually read + * (0 for end of file, -1 for error). + */ +template +inline int read(izstream& zs, T* x, Items items) { + return ::gzread(zs.fp(), x, items*sizeof(T)); +} + +/* + * Binary input with the '>' operator. + */ +template +inline izstream& operator>(izstream& zs, T& x) { + ::gzread(zs.fp(), &x, sizeof(T)); + return zs; +} + + +inline zstringlen::zstringlen(izstream& zs) { + zs > val.byte; + if (val.byte == 255) zs > val.word; + else val.word = val.byte; +} + +/* + * Read length of string + the string with the '>' operator. + */ +inline izstream& operator>(izstream& zs, char* x) { + zstringlen len(zs); + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return zs; +} + +inline char* read_string(izstream& zs) { + zstringlen len(zs); + char* x = new char[len.value()+1]; + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return x; +} + +// ----------------------------- ozstream ----------------------------- + +class ozstream +{ + public: + ozstream() : m_fp(0), m_os(0) { + } + ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(fp, level); + } + ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(name, level); + } + ~ozstream() { + close(); + } + + /* Opens a gzip (.gz) file for writing. + * The compression level parameter should be in 0..9 + * errno can be checked to distinguish two error cases + * (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name, int level = Z_DEFAULT_COMPRESSION) { + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzopen(name, mode); + } + + /* open from a FILE pointer. + */ + void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) { + SET_BINARY_MODE(fp); + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), mode); + } + + /* Flushes all pending output if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + if (m_os) { + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = 0; + } + int r = ::gzclose(m_fp); m_fp = 0; return r; + } + + /* Binary write the given number of bytes into the compressed file. + */ + int write(const void* buf, size_t len) { + return ::gzwrite(m_fp, (voidp) buf, len); + } + + /* Flushes all pending output into the compressed file. The parameter + * _flush is as in the deflate() function. The return value is the zlib + * error number (see function gzerror below). flush() returns Z_OK if + * the flush_ parameter is Z_FINISH and all output could be flushed. + * flush() should be called only when strictly necessary because it can + * degrade compression. + */ + int flush(int _flush) { + os_flush(); + return ::gzflush(m_fp, _flush); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + ostream& os() { + if (m_os == 0) m_os = new ostrstream; + return *m_os; + } + + void os_flush() { + if (m_os && m_os->pcount()>0) { + ostrstream* oss = new ostrstream; + oss->fill(m_os->fill()); + oss->flags(m_os->flags()); + oss->precision(m_os->precision()); + oss->width(m_os->width()); + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = oss; + } + } + + private: + gzFile m_fp; + ostrstream* m_os; +}; + +/* + * Binary write the given (array of) object(s) into the compressed file. + * returns the number of uncompressed bytes actually written + * (0 in case of error). + */ +template +inline int write(ozstream& zs, const T* x, Items items) { + return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T)); +} + +/* + * Binary output with the '<' operator. + */ +template +inline ozstream& operator<(ozstream& zs, const T& x) { + ::gzwrite(zs.fp(), (voidp) &x, sizeof(T)); + return zs; +} + +inline zstringlen::zstringlen(ozstream& zs, const char* x) { + val.byte = 255; val.word = ::strlen(x); + if (val.word < 255) zs < (val.byte = val.word); + else zs < val; +} + +/* + * Write length of string + the string with the '<' operator. + */ +inline ozstream& operator<(ozstream& zs, const char* x) { + zstringlen len(zs, x); + ::gzwrite(zs.fp(), (voidp) x, len.value()); + return zs; +} + +#ifdef _MSC_VER +inline ozstream& operator<(ozstream& zs, char* const& x) { + return zs < (const char*) x; +} +#endif + +/* + * Ascii write with the << operator; + */ +template +inline ostream& operator<<(ozstream& zs, const T& x) { + zs.os_flush(); + return zs.os() << x; +} + +#endif diff --git a/zlib-1.1.4/contrib/iostream2/zstream_test.cpp b/zlib-1.1.4/contrib/iostream2/zstream_test.cpp new file mode 100644 index 0000000..5bbd56c --- /dev/null +++ b/zlib-1.1.4/contrib/iostream2/zstream_test.cpp @@ -0,0 +1,25 @@ +#include "zstream.h" +#include +#include +#include + +void main() { + char h[256] = "Hello"; + char* g = "Goodbye"; + ozstream out("temp.gz"); + out < "This works well" < h < g; + out.close(); + + izstream in("temp.gz"); // read it back + char *x = read_string(in), *y = new char[256], z[256]; + in > y > z; + in.close(); + cout << x << endl << y << endl << z << endl; + + out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results + out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl; + out << z << endl << y << endl << x << endl; + out << 1.1234567890123456789 << endl; + + delete[] x; delete[] y; +} diff --git a/zlib-1.1.4/contrib/minizip/ChangeLogUnzip b/zlib-1.1.4/contrib/minizip/ChangeLogUnzip new file mode 100644 index 0000000..9987c54 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/ChangeLogUnzip @@ -0,0 +1,38 @@ +Change in 0.15: (19 Mar 98) +- fix memory leak in minizip.c + +Change in 0.14: (10 Mar 98) +- fix bugs in minizip.c sample for zipping big file +- fix problem in month in date handling +- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for + comment handling + +Change in 0.13: (6 Mar 98) +- fix bugs in zip.c +- add real minizip sample + +Change in 0.12: (4 Mar 98) +- add zip.c and zip.h for creates .zip file +- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) +- fix miniunz.c for file without specific record for directory + +Change in 0.11: (3 Mar 98) +- fix bug in unzGetCurrentFileInfo for get extra field and comment +- enhance miniunz sample, remove the bad unztst.c sample + +Change in 0.10: (2 Mar 98) +- fix bug in unzReadCurrentFile +- rename unzip* to unz* function and structure +- remove Windows-like hungary notation variable name +- modify some structure in unzip.h +- add somes comment in source +- remove unzipGetcCurrentFile function +- replace ZUNZEXPORT by ZEXPORT +- add unzGetLocalExtrafield for get the local extrafield info +- add a new sample, miniunz.c + +Change in 0.4: (25 Feb 98) +- suppress the type unzipFileInZip. + Only on file in the zipfile can be open at the same time +- fix somes typo in code +- added tm_unz structure in unzip_file_info (date/time in readable format) diff --git a/zlib-1.1.4/contrib/minizip/Makefile b/zlib-1.1.4/contrib/minizip/Makefile new file mode 100644 index 0000000..a1dfc16 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/Makefile @@ -0,0 +1,25 @@ +CC=cc +CFLAGS=-O -I../.. + +UNZ_OBJS = miniunz.o unzip.o ../../libz.a +ZIP_OBJS = minizip.o zip.o ../../libz.a + +.c.o: + $(CC) -c $(CFLAGS) $*.c + +all: miniunz minizip + +miniunz: $(UNZ_OBJS) + $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) + +minizip: $(ZIP_OBJS) + $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) + +test: miniunz minizip + ./minizip test readme.txt + ./miniunz -l test.zip + mv readme.txt readme.old + ./miniunz test.zip + +clean: + /bin/rm -f *.o *~ minizip miniunz diff --git a/zlib-1.1.4/contrib/minizip/miniunz.c b/zlib-1.1.4/contrib/minizip/miniunz.c new file mode 100644 index 0000000..f3b7832 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/miniunz.c @@ -0,0 +1,508 @@ +#include +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +#else +# include +# include +#endif + +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) + +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#ifdef unix + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef WIN32 + ret = mkdir(dirname); +#else +#ifdef unix + ret = mkdir (dirname,0775); +#endif +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +void do_banner() +{ + printf("MiniUnz 0.15, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n"); +} + +void do_help() +{ + printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]\n\n") ; +} + + +int do_list(uf) + unzFile uf; +{ + uLong i; + unz_global_info gi; + int err; + + err = unzGetGlobalInfo (uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); + printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); + for (i=0;i0) + ratio = (file_info.compressed_size*100)/file_info.uncompressed_size; + + if (file_info.compression_method==0) + string_method="Stored"; + else + if (file_info.compression_method==Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + string_method="Unkn. "; + + printf("%7lu %6s %7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + file_info.uncompressed_size,string_method,file_info.compressed_size, + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1)='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + } + + if (rep == 'N') + skip = 1; + + if (rep == 'A') + *popt_overwrite=1; + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=fopen(write_filename,"wb"); + + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && ((*popt_extract_without_path)==0) && + (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=fopen(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + fclose(fout); + if (err==0) + change_file_date(write_filename,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(uf,opt_extract_without_path,opt_overwrite) + unzFile uf; + int opt_extract_without_path; + int opt_overwrite; +{ + uLong i; + unz_global_info gi; + int err; + FILE* fout=NULL; + + err = unzGetGlobalInfo (uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i +#include +#include +#include +#include +#include + +#ifdef unix +# include +# include +# include +# include +#else +# include +# include +#endif + +#include "zip.h" + + +#define WRITEBUFFERSIZE (16384) +#define MAXFILENAME (256) + +#ifdef WIN32 +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret = 0; + { + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATA ff32; + + hFind = FindFirstFile(f,&ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + ret = 1; + } + } + return ret; +} +#else +#ifdef unix +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret=0; + struct stat s; /* results of stat() */ + struct tm* filedate; + time_t tm_t=0; + + if (strcmp(f,"-")!=0) + { + char name[MAXFILENAME]; + int len = strlen(f); + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (stat(name,&s)==0) + { + tm_t = s.st_mtime; + ret = 1; + } + } + filedate = localtime(&tm_t); + + tmzip->tm_sec = filedate->tm_sec; + tmzip->tm_min = filedate->tm_min; + tmzip->tm_hour = filedate->tm_hour; + tmzip->tm_mday = filedate->tm_mday; + tmzip->tm_mon = filedate->tm_mon ; + tmzip->tm_year = filedate->tm_year; + + return ret; +} +#else +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + return 0; +} +#endif +#endif + + + + +int check_exist_file(filename) + const char* filename; +{ + FILE* ftestexist; + int ret = 1; + ftestexist = fopen(filename,"rb"); + if (ftestexist==NULL) + ret = 0; + else + fclose(ftestexist); + return ret; +} + +void do_banner() +{ + printf("MiniZip 0.15, demo of zLib + Zip package written by Gilles Vollant\n"); + printf("more info at http://wwww.winimage/zLibDll/unzip.htm\n\n"); +} + +void do_help() +{ + printf("Usage : minizip [-o] file.zip [files_to_add]\n\n") ; +} + +int main(argc,argv) + int argc; + char *argv[]; +{ + int i; + int opt_overwrite=0; + int opt_compress_level=Z_DEFAULT_COMPRESSION; + int zipfilenamearg = 0; + char filename_try[MAXFILENAME]; + int zipok; + int err=0; + int size_buf=0; + void* buf=NULL, + + + do_banner(); + if (argc==1) + { + do_help(); + exit(0); + return 0; + } + else + { + for (i=1;i='0') && (c<='9')) + opt_compress_level = c-'0'; + } + } + else + if (zipfilenamearg == 0) + zipfilenamearg = i ; + } + } + + size_buf = WRITEBUFFERSIZE; + buf = (void*)malloc(size_buf); + if (buf==NULL) + { + printf("Error allocating memory\n"); + return ZIP_INTERNALERROR; + } + + if (zipfilenamearg==0) + zipok=0; + else + { + int i,len; + int dot_found=0; + + zipok = 1 ; + strcpy(filename_try,argv[zipfilenamearg]); + len=strlen(filename_try); + for (i=0;i='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N')); + if (rep=='N') + zipok = 0; + } + } + + if (zipok==1) + { + zipFile zf; + int errclose; + zf = zipOpen(filename_try,0); + if (zf == NULL) + { + printf("error opening %s\n",filename_try); + err= ZIP_ERRNO; + } + else + printf("creating %s\n",filename_try); + + for (i=zipfilenamearg+1;(i0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + fclose(fin); + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } + } + } + errclose = zipClose(zf,NULL); + if (errclose != ZIP_OK) + printf("error in closing %s\n",filename_try); + } + + free(buf); + exit(0); + return 0; /* to avoid warning */ +} diff --git a/zlib-1.1.4/contrib/minizip/readme.txt b/zlib-1.1.4/contrib/minizip/readme.txt new file mode 100644 index 0000000..1fc023c --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/readme.txt @@ -0,0 +1,37 @@ + +UnZip 0.15 additionnal library + + + This unzip package allow extract file from .ZIP file, compatible with +PKZip 2.04g, WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported, and old compression used by old +PKZip 1.x are not supported. + +See probdesc.zip from PKWare for specification of .ZIP format. + +What is Unzip + The Zlib library support the deflate compression and the creation of gzip (.gz) +file. Zlib is free and small. + The .Zip format, which can contain several compressed files (.gz can containt +only one file) is a very popular format. This is why I've written a package for reading file compressed in Zipfile. + +Using Unzip package + +You need source of Zlib (get zlib111.zip and read zlib.h). +Get unzlb015.zip and read unzip.h (whith documentation of unzip functions) + +The Unzip package is only two file : unzip.h and unzip.c. But it use the Zlib + files. +unztst.c is a simple sample program, which list file in a zipfile and display + README.TXT or FILE_ID.DIZ (if these files are found). +miniunz.c is a mini unzip program. + +I'm also currenlyt writing a zipping portion (zip.h, zip.c and test with minizip.c) + +Please email me for feedback. +I hope my source is compatible with Unix system, but I need your help for be sure + +Latest revision : Mar 04th, 1998 + +Check http://www.winimage.com/zLibDll/unzip.html for up to date info. diff --git a/zlib-1.1.4/contrib/minizip/unzip.c b/zlib-1.1.4/contrib/minizip/unzip.c new file mode 100644 index 0000000..ff71a47 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/unzip.c @@ -0,0 +1,1294 @@ +/* unzip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read unzip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + + +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ + !defined(CASESENSITIVITYDEFAULT_NO) +#define CASESENSITIVITYDEFAULT_NO +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char unz_copyright[] = + " unzip 0.15 Copyright 1998 Gilles Vollant "; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + FILE* file; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + FILE* file; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ +} unz_s; + + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte(fin,pi) + FILE *fin; + int *pi; +{ + unsigned char c; + int err = fread(&c, 1, 1, fin); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ferror(fin)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong (fin,pX) + FILE* fin; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir(fin) + FILE *fin; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (fseek(fin,0,SEEK_END) != 0) + return 0; + + + uSizeFile = ftell( fin ); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (fseek(fin,uReadPos,SEEK_SET)!=0) + break; + + if (fread(buf,(uInt)uReadSize,1,fin)!=1) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer + "zlib/zlib109.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen (path) + const char *path; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + FILE * fin ; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + fin=fopen(path,"rb"); + if (fin==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) + err=UNZ_ERRNO; + + if (fseek(fin,central_pos,SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + fclose(s->file); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (fseek(s->file,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, + pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { + uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (fseek(pfile_in_zip_read_info->file, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} diff --git a/zlib-1.1.4/contrib/minizip/unzip.def b/zlib-1.1.4/contrib/minizip/unzip.def new file mode 100644 index 0000000..f6ede89 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/unzip.def @@ -0,0 +1,15 @@ + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 diff --git a/zlib-1.1.4/contrib/minizip/unzip.h b/zlib-1.1.4/contrib/minizip/unzip.h new file mode 100644 index 0000000..76692cb --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/unzip.h @@ -0,0 +1,275 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip */ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer + "zlib/zlib111.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/zlib-1.1.4/contrib/minizip/zip.c b/zlib-1.1.4/contrib/minizip/zip.c new file mode 100644 index 0000000..0cae64a --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zip.c @@ -0,0 +1,718 @@ +/* zip.c -- IO on .zip files using zlib + Version 0.15 beta, Mar 19th, 1998, + + Read zip.h for more info +*/ + + +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +const char zip_copyright[] = + " zip 0.15 Copyright 1998 Gilles Vollant "; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + uLong pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralheader; /* size of the central header for cur file */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; +} curfile_info; + +typedef struct +{ + FILE * filezip; + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile_info ci; /* info on the file curretly writing */ + + uLong begin_pos; /* position of the beginning of the zipfile */ + uLong number_entry; +} zip_internal; + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(ldi) + linkedlist_datablock_internal* ldi; +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(ll) + linkedlist_data* ll; +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(ll) + linkedlist_data* ll; +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(ll,buf,len) + linkedlist_data* ll; + const void* buf; + uLong len; +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + +local int write_datablock(fout,ll) + FILE * fout; + linkedlist_data* ll; +{ + linkedlist_datablock_internal* ldi; + ldi = ll->first_block; + while (ldi!=NULL) + { + if (ldi->filled_in_this_block > 0) + if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1) + return ZIP_ERRNO; + ldi = ldi->next_datablock; + } + return ZIP_OK; +} + +/****************************************************************************/ + +/* =========================================================================== + Outputs a long in LSB order to the given file + nbByte == 1, 2 or 4 (byte, short or long) +*/ + +local int ziplocal_putValue OF((FILE *file, uLong x, int nbByte)); +local int ziplocal_putValue (file, x, nbByte) + FILE *file; + uLong x; + int nbByte; +{ + unsigned char buf[4]; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (fwrite(buf,nbByte,1,file)!=1) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); +local void ziplocal_putValue_inmemory (dest, x, nbByte) + void* dest; + uLong x; + int nbByte; +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } +} +/****************************************************************************/ + + +local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) + tm_zip* ptm; + uLong dosDate; +{ + uLong year = (uLong)ptm->tm_year; + if (year>1980) + year-=1980; + else if (year>80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +extern zipFile ZEXPORT zipOpen (pathname, append) + const char *pathname; + int append; +{ + zip_internal ziinit; + zip_internal* zi; + + ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab"); + if (ziinit.filezip == NULL) + return NULL; + ziinit.begin_pos = ftell(ziinit.filezip); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + init_linkedlist(&(ziinit.central_dir)); + + + zi = (zip_internal*)ALLOC(sizeof(zip_internal)); + if (zi==NULL) + { + fclose(ziinit.filezip); + return NULL; + } + + *zi = ziinit; + return (zipFile)zi; +} + +extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; +{ + zip_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; + + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = strlen(comment); + + size_filename = strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); + } + + zi->ci.flag = 0; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.pos_local_header = ftell(zi->filezip); + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + + size_extrafield_global + size_comment; + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); + + ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); + ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(filename+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + /* write the local header */ + err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)20,2);/* version needed to extract */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* compressed size, unknown */ + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* uncompressed size, unknown */ + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2); + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2); + + if ((err==ZIP_OK) && (size_filename>0)) + if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1) + err = ZIP_ERRNO; + + if ((err==ZIP_OK) && (size_extrafield_local>0)) + if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED)) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + err = deflateInit2(&zi->ci.stream, level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + + if (err==Z_OK) + zi->ci.stream_initialised = 1; + } + + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (file, buf, len) + zipFile file; + const voidp buf; + unsigned len; +{ + zip_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.stream.next_in = buf; + zi->ci.stream.avail_in = len; + zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + if (zi->ci.method == Z_DEFLATED) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + for (i=0;ici.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + } + + return 0; +} + +extern int ZEXPORT zipCloseFileInZip (file) + zipFile file; +{ + zip_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if (zi->ci.method == Z_DEFLATED) + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) + !=1) + err = ZIP_ERRNO; + + if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK)) + { + err=deflateEnd(&zi->ci.stream); + zi->ci.stream_initialised = 0; + } + + ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4); /*crc*/ + ziplocal_putValue_inmemory(zi->ci.central_header+20, + (uLong)zi->ci.stream.total_out,4); /*compr size*/ + ziplocal_putValue_inmemory(zi->ci.central_header+24, + (uLong)zi->ci.stream.total_in,4); /*uncompr size*/ + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, + (uLong)zi->ci.size_centralheader); + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + long cur_pos_inzip = ftell(zi->filezip); + if (fseek(zi->filezip, + zi->ci.pos_local_header + 14,SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4); /* crc 32, unknown */ + + if (err==ZIP_OK) /* compressed size, unknown */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4); + + if (fseek(zi->filezip, + cur_pos_inzip,SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipClose (file, global_comment) + zipFile file; + const char* global_comment; +{ + zip_internal* zi; + int err = 0; + uLong size_centraldir = 0; + uLong centraldir_pos_inzip ; + uInt size_global_comment; + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + + if (global_comment==NULL) + size_global_comment = 0; + else + size_global_comment = strlen(global_comment); + + + centraldir_pos_inzip = ftell(zi->filezip); + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block, + 1,zi->filezip) !=1 ) + err = ZIP_ERRNO; + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_datablock(zi->central_dir.first_block); + + if (err==ZIP_OK) /* Magic End */ + err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = ziplocal_putValue(zi->filezip,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = ziplocal_putValue(zi->filezip,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + + if (err==ZIP_OK) /* size of the central directory */ + err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the + starting disk number */ + err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4); + + if (err==ZIP_OK) /* zipfile comment length */ + err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2); + + if ((err==ZIP_OK) && (size_global_comment>0)) + if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 ) + err = ZIP_ERRNO; + fclose(zi->filezip); + TRYFREE(zi); + + return err; +} diff --git a/zlib-1.1.4/contrib/minizip/zip.def b/zlib-1.1.4/contrib/minizip/zip.def new file mode 100644 index 0000000..5d5079f --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zip.def @@ -0,0 +1,5 @@ + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/zlib-1.1.4/contrib/minizip/zip.h b/zlib-1.1.4/contrib/minizip/zip.h new file mode 100644 index 0000000..678260b --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zip.h @@ -0,0 +1,150 @@ +/* zip.h -- IO for compress .zip files using zlib + Version 0.15 alpha, Mar 19th, 1998, + + Copyright (C) 1998 Gilles Vollant + + This unzip package allow creates .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. + Old compressions used by old PKZip 1.x are not supported + + For uncompress .zip file, look at unzip.h + + THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE + CAN CHANGE IN FUTURE VERSION !! + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/zip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _zip_H +#define _zip_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_INTERNALERROR (-104) + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows NT a filename like "c:\\zlib\\zlib111.zip" or on + an Unix computer "zlib/zlib111.zip". + if the file pathname exist and append=1, the zip will be created at the end + of the file. (useful if the file contain a self extractor code) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. + + +*/ + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) +*/ + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const voidp buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip_H */ diff --git a/zlib-1.1.4/contrib/minizip/zlibvc.def b/zlib-1.1.4/contrib/minizip/zlibvc.def new file mode 100644 index 0000000..7e9d60d --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zlibvc.def @@ -0,0 +1,74 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + + +VERSION 1.11 + + +HEAPSIZE 1048576,8192 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 diff --git a/zlib-1.1.4/contrib/minizip/zlibvc.dsp b/zlib-1.1.4/contrib/minizip/zlibvc.dsp new file mode 100644 index 0000000..a70d4d4 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/zlib-1.1.4/contrib/minizip/zlibvc.dsw b/zlib-1.1.4/contrib/minizip/zlibvc.dsw new file mode 100644 index 0000000..493cd87 --- /dev/null +++ b/zlib-1.1.4/contrib/minizip/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/zlib-1.1.4/contrib/untgz/Makefile b/zlib-1.1.4/contrib/untgz/Makefile new file mode 100644 index 0000000..409b4bd --- /dev/null +++ b/zlib-1.1.4/contrib/untgz/Makefile @@ -0,0 +1,14 @@ +CC=cc +CFLAGS=-g + +untgz: untgz.o ../../libz.a + $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz + +untgz.o: untgz.c ../../zlib.h + $(CC) $(CFLAGS) -c -I../.. untgz.c + +../../libz.a: + cd ../..; make + +clean: + rm -f untgz untgz.o *~ diff --git a/zlib-1.1.4/contrib/untgz/makefile.w32 b/zlib-1.1.4/contrib/untgz/makefile.w32 new file mode 100644 index 0000000..c99dc28 --- /dev/null +++ b/zlib-1.1.4/contrib/untgz/makefile.w32 @@ -0,0 +1,63 @@ +# Makefile for zlib. Modified for mingw32 +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, +# +# make -fmakefile.w32 +# + +CC=gcc + +# Generate dependencies (see end of the file) + +CPPFLAGS=-MMD + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is not found, replace with copy /Y . +CP=cp -f + +# The default value of RM is "rm -f." +# If "rm.exe" is not found, uncomment: +# RM=del + +LD=gcc +LDLIBS=-L. -lz +LDFLAGS=-s + + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o \ + inffast.o + +TEST_OBJS = minigzip.o untgz.o + +all: minigzip.exe untgz.exe + +rebuild: clean all + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $(LDFLAGS) -o $@ $< $(LDLIBS) + +.PHONY : clean + +clean: + $(RM) *.d *.o *.exe libz.a foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif + diff --git a/zlib-1.1.4/contrib/untgz/untgz.c b/zlib-1.1.4/contrib/untgz/untgz.c new file mode 100644 index 0000000..4a431ff --- /dev/null +++ b/zlib-1.1.4/contrib/untgz/untgz.c @@ -0,0 +1,522 @@ +/* + * untgz.c -- Display contents and/or extract file from + * a gzip'd TAR file + * written by "Pedro A. Aranda Guti\irrez" + * adaptation to Unix by Jean-loup Gailly + */ + +#include +#include +#include +#include +#include +#include +#ifdef unix +# include +#else +# include +# include +#endif + +#include "zlib.h" + +#ifdef WIN32 +# ifndef F_OK +# define F_OK (0) +# endif +# ifdef _MSC_VER +# define mkdir(dirname,mode) _mkdir(dirname) +# define strdup(str) _strdup(str) +# define unlink(fn) _unlink(fn) +# define access(path,mode) _access(path,mode) +# else +# define mkdir(dirname,mode) _mkdir(dirname) +# endif +#else +# include +#endif + + +/* Values used in typeflag field. */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved */ + +#define BLOCKSIZE 512 + +struct tar_header +{ /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union tar_buffer { + char buffer[BLOCKSIZE]; + struct tar_header header; +}; + +enum { TGZ_EXTRACT = 0, TGZ_LIST }; + +static char *TGZfname OF((const char *)); +void TGZnotfound OF((const char *)); + +int getoct OF((char *, int)); +char *strtime OF((time_t *)); +int ExprMatch OF((char *,char *)); + +int makedir OF((char *)); +int matchname OF((int,int,char **,char *)); + +void error OF((const char *)); +int tar OF((gzFile, int, int, int, char **)); + +void help OF((int)); +int main OF((int, char **)); + +char *prog; + +/* This will give a benign warning */ + +static char *TGZprefix[] = { "\0", ".tgz", ".tar.gz", ".tar", NULL }; + +/* Return the real name of the TGZ archive */ +/* or NULL if it does not exist. */ + +static char *TGZfname OF((const char *fname)) +{ + static char buffer[1024]; + int origlen,i; + + strcpy(buffer,fname); + origlen = strlen(buffer); + + for (i=0; TGZprefix[i]; i++) + { + strcpy(buffer+origlen,TGZprefix[i]); + if (access(buffer,F_OK) == 0) + return buffer; + } + return NULL; +} + +/* error message for the filename */ + +void TGZnotfound OF((const char *fname)) +{ + int i; + + fprintf(stderr,"%s : couldn't find ",prog); + for (i=0;TGZprefix[i];i++) + fprintf(stderr,(TGZprefix[i+1]) ? "%s%s, " : "or %s%s\n", + fname, + TGZprefix[i]); + exit(1); +} + + +/* help functions */ + +int getoct(char *p,int width) +{ + int result = 0; + char c; + + while (width --) + { + c = *p++; + if (c == ' ') + continue; + if (c == 0) + break; + result = result * 8 + (c - '0'); + } + return result; +} + +char *strtime (time_t *t) +{ + struct tm *local; + static char result[32]; + + local = localtime(t); + sprintf(result,"%2d/%02d/%4d %02d:%02d:%02d", + local->tm_mday, local->tm_mon+1, local->tm_year+1900, + local->tm_hour, local->tm_min, local->tm_sec); + return result; +} + + +/* regular expression matching */ + +#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) + +int ExprMatch(char *string,char *expr) +{ + while (1) + { + if (ISSPECIAL(*expr)) + { + if (*expr == '/') + { + if (*string != '\\' && *string != '/') + return 0; + string ++; expr++; + } + else if (*expr == '*') + { + if (*expr ++ == 0) + return 1; + while (*++string != *expr) + if (*string == 0) + return 0; + } + } + else + { + if (*string != *expr) + return 0; + if (*expr++ == 0) + return 1; + string++; + } + } +} + +/* recursive make directory */ +/* abort if you get an ENOENT errno somewhere in the middle */ +/* e.g. ignore error "mkdir on existing directory" */ +/* */ +/* return 1 if OK */ +/* 0 on error */ + +int makedir (char *newdir) +{ + char *buffer = strdup(newdir); + char *p; + int len = strlen(buffer); + + if (len <= 0) { + free(buffer); + return 0; + } + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mkdir(buffer, 0775) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mkdir(buffer, 0775) == -1) && (errno == ENOENT)) + { + fprintf(stderr,"%s: couldn't create directory %s\n",prog,buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +int matchname (int arg,int argc,char **argv,char *fname) +{ + if (arg == argc) /* no arguments given (untgz tgzarchive) */ + return 1; + + while (arg < argc) + if (ExprMatch(fname,argv[arg++])) + return 1; + + return 0; /* ignore this for the moment being */ +} + + +/* Tar file list or extract */ + +int tar (gzFile in,int action,int arg,int argc,char **argv) +{ + union tar_buffer buffer; + int len; + int err; + int getheader = 1; + int remaining = 0; + FILE *outfile = NULL; + char fname[BLOCKSIZE]; + time_t tartime; + + if (action == TGZ_LIST) + printf(" day time size file\n" + " ---------- -------- --------- -------------------------------------\n"); + while (1) + { + len = gzread(in, &buffer, BLOCKSIZE); + if (len < 0) + error (gzerror(in, &err)); + /* + * Always expect complete blocks to process + * the tar information. + */ + if (len != BLOCKSIZE) + error("gzread: incomplete block read"); + + /* + * If we have to get a tar header + */ + if (getheader == 1) + { + /* + * if we met the end of the tar + * or the end-of-tar block, + * we are done + */ + if ((len == 0) || (buffer.header.name[0]== 0)) break; + + tartime = (time_t)getoct(buffer.header.mtime,12); + strcpy(fname,buffer.header.name); + + switch (buffer.header.typeflag) + { + case DIRTYPE: + if (action == TGZ_LIST) + printf(" %s %s\n",strtime(&tartime),fname); + if (action == TGZ_EXTRACT) + makedir(fname); + break; + case REGTYPE: + case AREGTYPE: + remaining = getoct(buffer.header.size,12); + if (action == TGZ_LIST) + printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); + if (action == TGZ_EXTRACT) + { + if ((remaining) && (matchname(arg,argc,argv,fname))) + { + outfile = fopen(fname,"wb"); + if (outfile == NULL) { + /* try creating directory */ + char *p = strrchr(fname, '/'); + if (p != NULL) { + *p = '\0'; + makedir(fname); + *p = '/'; + outfile = fopen(fname,"wb"); + } + } + fprintf(stderr, + "%s %s\n", + (outfile) ? "Extracting" : "Couldn't create", + fname); + } + else + outfile = NULL; + } + /* + * could have no contents + */ + getheader = (remaining) ? 0 : 1; + break; + default: + if (action == TGZ_LIST) + printf(" %s <---> %s\n",strtime(&tartime),fname); + break; + } + } + else + { + unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; + + if ((action == TGZ_EXTRACT) && (outfile != NULL)) + { + if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) + { + fprintf(stderr,"%s : error writing %s skipping...\n",prog,fname); + fclose(outfile); + unlink(fname); + } + } + remaining -= bytes; + if (remaining == 0) + { + getheader = 1; + if ((action == TGZ_EXTRACT) && (outfile != NULL)) + { +#ifdef WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal; + SYSTEMTIME st; + struct tm localt; + + fclose(outfile); + + localt = *localtime(&tartime); + + hFile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + st.wYear = (WORD)localt.tm_year+1900; + st.wMonth = (WORD)localt.tm_mon; + st.wDayOfWeek = (WORD)localt.tm_wday; + st.wDay = (WORD)localt.tm_mday; + st.wHour = (WORD)localt.tm_hour; + st.wMinute = (WORD)localt.tm_min; + st.wSecond = (WORD)localt.tm_sec; + st.wMilliseconds = 0; + SystemTimeToFileTime(&st,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,NULL,&ftm); + CloseHandle(hFile); + + outfile = NULL; +#else + struct utimbuf settime; + + settime.actime = settime.modtime = tartime; + + fclose(outfile); + outfile = NULL; + utime(fname,&settime); +#endif + } + } + } + } + + if (gzclose(in) != Z_OK) + error("failed gzclose"); + + return 0; +} + + +/* =========================================================== */ + +void help(int exitval) +{ + fprintf(stderr, + "untgz v 0.1\n" + " an sample application of zlib 1.0.4\n\n" + "Usage : untgz TGZfile to extract all files\n" + " untgz TGZfile fname ... to extract selected files\n" + " untgz -l TGZfile to list archive contents\n" + " untgz -h to display this help\n\n"); + exit(exitval); +} + +void error(const char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + + +/* ====================================================================== */ + +int _CRT_glob = 0; /* disable globbing of the arguments */ + +int main(int argc,char **argv) +{ + int action = TGZ_EXTRACT; + int arg = 1; + char *TGZfile; + gzFile *f; + + + prog = strrchr(argv[0],'\\'); + if (prog == NULL) + { + prog = strrchr(argv[0],'/'); + if (prog == NULL) + { + prog = strrchr(argv[0],':'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + } + else + prog++; + } + else + prog++; + + if (argc == 1) + help(0); + + if (strcmp(argv[arg],"-l") == 0) + { + action = TGZ_LIST; + if (argc == ++arg) + help(0); + } + else if (strcmp(argv[arg],"-h") == 0) + { + help(0); + } + + if ((TGZfile = TGZfname(argv[arg])) == NULL) + TGZnotfound(argv[arg]); + + ++arg; + if ((action == TGZ_LIST) && (arg != argc)) + help(1); + +/* + * Process the TGZ file + */ + switch(action) + { + case TGZ_LIST: + case TGZ_EXTRACT: + f = gzopen(TGZfile,"rb"); + if (f == NULL) + { + fprintf(stderr,"%s: Couldn't gzopen %s\n", + prog, + TGZfile); + return 1; + } + exit(tar(f, action, arg, argc, argv)); + break; + + default: + error("Unknown option!"); + exit(1); + } + + return 0; +} diff --git a/zlib-1.1.4/contrib/visual-basic.txt b/zlib-1.1.4/contrib/visual-basic.txt new file mode 100644 index 0000000..10fb44b --- /dev/null +++ b/zlib-1.1.4/contrib/visual-basic.txt @@ -0,0 +1,69 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member diff --git a/zlib-1.1.4/crc32.c b/zlib-1.1.4/crc32.c new file mode 100644 index 0000000..60deca2 --- /dev/null +++ b/zlib-1.1.4/crc32.c @@ -0,0 +1,162 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define local static + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local const uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const uLongf * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (const uLongf *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/zlib-1.1.4/deflate.c b/zlib-1.1.4/deflate.c new file mode 100644 index 0000000..16ebdad --- /dev/null +++ b/zlib-1.1.4/deflate.c @@ -0,0 +1,1350 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + static const char* my_version = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#ifdef FASTEST + level = 1; +#endif + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +#ifndef FASTEST +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return len <= s->lookahead ? len : s->lookahead; +} +#endif /* FASTEST */ +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/zlib-1.1.4/deflate.h b/zlib-1.1.4/deflate.h new file mode 100644 index 0000000..b99a48a --- /dev/null +++ b/zlib-1.1.4/deflate.h @@ -0,0 +1,318 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif diff --git a/zlib-1.1.4/descrip.mms b/zlib-1.1.4/descrip.mms new file mode 100644 index 0000000..9d36459 --- /dev/null +++ b/zlib-1.1.4/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/zlib-1.1.4/example.c b/zlib-1.1.4/example.c new file mode 100644 index 0000000..e7e3673 --- /dev/null +++ b/zlib-1.1.4/example.c @@ -0,0 +1,556 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *out, const char *in, + Byte *uncompr, int uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in, uncompr, uncomprLen) + const char *out; /* compressed output file */ + const char *in; /* compressed input file */ + Byte *uncompr; + int uncomprLen; +{ + int err; + int len = strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char *)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, uncomprLen); + uncomprLen = strlen((char*)uncompr); + if (uncomprLen != 6) { /* "hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello+7)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char *)uncompr); + } + + gzclose(file); +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + (argc > 2 ? argv[2] : TESTFILE), + uncompr, (int)uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + exit(0); + return 0; /* to avoid warning */ +} diff --git a/zlib-1.1.4/gzio.c b/zlib-1.1.4/gzio.c new file mode 100644 index 0000000..09e0a20 --- /dev/null +++ b/zlib-1.1.4/gzio.c @@ -0,0 +1,875 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_DEFLATE to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + long startpos; /* start of compressed data in file (header skipped) */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->startpos = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * startpos anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->startpos = (ftell(s->file) - s->stream.avail_in); + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + if (len != 0) s->stream.avail_in++, s->stream.next_in--; + if (c != EOF) { + s->stream.avail_in++, s->stream.next_in--; + s->transparent = 1; + } + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_DEFLATE + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + len -= s->stream.avail_out; + s->stream.total_in += (uLong)len; + s->stream.total_out += (uLong)len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may + * be different from s->stream.total_out) in case of + * concatenated .gz files. Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + uLong total_in = s->stream.total_in; + uLong total_out = s->stream.total_out; + + inflateReset(&(s->stream)); + s->stream.total_in = total_in; + s->stream.total_out = total_out; + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_DEFLATE +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + const voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + va_start(va, format); +#ifdef HAS_vsnprintf + (void)vsnprintf(buf, sizeof(buf), format, va); +#else + (void)vsprintf(buf, format, va); +#endif + va_end(va); + len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + +#ifdef HAS_snprintf + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#else + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#endif + len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ + if (len <= 0) return 0; + + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_DEFLATE */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->stream.total_in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return (z_off_t)s->stream.total_in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->stream.total_out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->stream.total_in = s->stream.total_out = (uLong)offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if ((uLong)offset >= s->stream.total_out) { + offset -= s->stream.total_out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return (z_off_t)s->stream.total_out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + + if (s->startpos == 0) { /* not a compressed file */ + rewind(s->file); + return 0; + } + + (void) inflateReset(&s->stream); + return fseek(s->file, s->startpos, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_DEFLATE + return Z_STREAM_ERROR; +#else + err = do_flush (file, Z_FINISH); + if (err != Z_OK) return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); +#endif + } + return destroy((gz_stream*)file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char* ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} diff --git a/zlib-1.1.4/infblock.c b/zlib-1.1.4/infblock.c new file mode 100644 index 0000000..dd7a6d4 --- /dev/null +++ b/zlib-1.1.4/infblock.c @@ -0,0 +1,403 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z) +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(s) +inflate_blocks_statef *s; +{ + return s->mode == LENS; +} diff --git a/zlib-1.1.4/infblock.h b/zlib-1.1.4/infblock.h new file mode 100644 index 0000000..173b226 --- /dev/null +++ b/zlib-1.1.4/infblock.h @@ -0,0 +1,39 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); diff --git a/zlib-1.1.4/infcodes.c b/zlib-1.1.4/infcodes.c new file mode 100644 index 0000000..9abe541 --- /dev/null +++ b/zlib-1.1.4/infcodes.c @@ -0,0 +1,251 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/zlib-1.1.4/infcodes.h b/zlib-1.1.4/infcodes.h new file mode 100644 index 0000000..46821a0 --- /dev/null +++ b/zlib-1.1.4/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/zlib-1.1.4/inffast.c b/zlib-1.1.4/inffast.c new file mode 100644 index 0000000..aa7f1d4 --- /dev/null +++ b/zlib-1.1.4/inffast.c @@ -0,0 +1,183 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + r = q - d; + if (r < s->window) /* wrap if needed */ + { + do { + r += s->end - s->window; /* force pointer in window */ + } while (r < s->window); /* covers invalid distances */ + e = s->end - r; + if (c > e) + { + c -= e; /* wrapped copy */ + do { + *q++ = *r++; + } while (--e); + r = s->window; + do { + *q++ = *r++; + } while (--c); + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff --git a/zlib-1.1.4/inffast.h b/zlib-1.1.4/inffast.h new file mode 100644 index 0000000..a31a4bb --- /dev/null +++ b/zlib-1.1.4/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/zlib-1.1.4/inffixed.h b/zlib-1.1.4/inffixed.h new file mode 100644 index 0000000..77f7e76 --- /dev/null +++ b/zlib-1.1.4/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/zlib-1.1.4/inflate.c b/zlib-1.1.4/inflate.c new file mode 100644 index 0000000..dfb2e86 --- /dev/null +++ b/zlib-1.1.4/inflate.c @@ -0,0 +1,366 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int ZEXPORT inflateReset(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int ZEXPORT inflateEnd(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +int ZEXPORT inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int ZEXPORT inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int ZEXPORT inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int ZEXPORT inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); +} diff --git a/zlib-1.1.4/inftrees.c b/zlib-1.1.4/inftrees.c new file mode 100644 index 0000000..4c32ca3 --- /dev/null +++ b/zlib-1.1.4/inftrees.c @@ -0,0 +1,454 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + +const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= 288) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +inflate_huft *hp; /* space for trees */ +uInt *hn; /* hufts used in space */ +uIntf *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, hp, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +int inflate_trees_fixed(bl, bd, tl, td, z) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for memory allocation */ +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff --git a/zlib-1.1.4/inftrees.h b/zlib-1.1.4/inftrees.h new file mode 100644 index 0000000..04b73b7 --- /dev/null +++ b/zlib-1.1.4/inftrees.h @@ -0,0 +1,58 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ diff --git a/zlib-1.1.4/infutil.c b/zlib-1.1.4/infutil.c new file mode 100644 index 0000000..9a07622 --- /dev/null +++ b/zlib-1.1.4/infutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/zlib-1.1.4/infutil.h b/zlib-1.1.4/infutil.h new file mode 100644 index 0000000..4401df8 --- /dev/null +++ b/zlib-1.1.4/infutil.h @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/zlib-1.1.4/maketree.c b/zlib-1.1.4/maketree.c new file mode 100644 index 0000000..a16d4b1 --- /dev/null +++ b/zlib-1.1.4/maketree.c @@ -0,0 +1,85 @@ +/* maketree.c -- make inffixed.h table for decoding fixed codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* This program is included in the distribution for completeness. + You do not need to compile or run this program since inffixed.h + is already included in the distribution. To use this program + you need to compile zlib with BUILDFIXED defined and then compile + and link this program with the zlib library. Then the output of + this program can be piped to inffixed.h. */ + +#include +#include +#include "zutil.h" +#include "inftrees.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* generate initialization table for an inflate_huft structure array */ +void maketree(uInt b, inflate_huft *t) +{ + int i, e; + + i = 0; + while (1) + { + e = t[i].exop; + if (e && (e & (16+64)) == 0) /* table pointer */ + { + fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); + exit(1); + } + if (i % 4 == 0) + printf("\n "); + printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); + if (++i == (1< +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...] + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + char outmode[20]; + + strcpy(outmode, "wb6 "); + + prog = argv[0]; + argc--, argv++; + + while (argc > 0) { + if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv, outmode); + } + } while (argv++, --argc); + } + exit(0); + return 0; /* to avoid warning */ +} diff --git a/zlib-1.1.4/msdos/Makefile.b32 b/zlib-1.1.4/msdos/Makefile.b32 new file mode 100644 index 0000000..f476da9 --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.b32 @@ -0,0 +1,104 @@ +# Makefile for zlib +# Borland C++ + +# This version of the zlib makefile was adapted by Chris Young for use +# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode +# flat memory model. It was created for use with POV-Ray ray tracer and +# you may choose to edit the CFLAGS to suit your needs but the +# switches -WX and -DMSDOS are required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "make -fmakefile.b32" + +# See zconf.h for details about the memory requirements. + +# ------------- Borland C++ ------------- +MODEL=-WX +CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS +CC=bcc32 +LD=bcc32 +LIB=tlib +LDFLAGS= $(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + del zlib.lib + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/Makefile.bor b/zlib-1.1.4/msdos/Makefile.bor new file mode 100644 index 0000000..f5651b4 --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.bor @@ -0,0 +1,125 @@ +# Makefile for zlib +# Borland C++ ************ UNTESTED *********** + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C++, Borland C++ ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of s, m, c, l (small, medium, compact, large) +MODEL=l + +CC=bcc +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +LD=$(CC) +AR=tlib + +# compiler flags +CFLAGS=-O2 -Z -m$(MODEL) $(LOC) +# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 + +LDFLAGS=-m$(MODEL) + +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: test + +# individual dependencies and action rules: +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) +$(OBJP1) + $(AR) $(ZLIB_LIB) +$(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/Makefile.dj2 b/zlib-1.1.4/msdos/Makefile.dj2 new file mode 100644 index 0000000..0ab431c --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.dj2 @@ -0,0 +1,100 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while 'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +# INCLUDE_PATH=c:\usr\include +# LIBRARY_PATH=c:\usr\lib + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/zlib-1.1.4/msdos/Makefile.emx b/zlib-1.1.4/msdos/Makefile.emx new file mode 100644 index 0000000..0e5e5cc --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/zlib-1.1.4/msdos/Makefile.msc b/zlib-1.1.4/msdos/Makefile.msc new file mode 100644 index 0000000..562201d --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.msc @@ -0,0 +1,121 @@ +# Makefile for zlib +# Microsoft C 5.1 or later + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=S + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of S, M, C, L (small, medium, compact, large) +MODEL=L + +CC=cl +CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) +#-Ox generates bad code with MSC 5.1 +LIB_CFLAGS=-Zl $(CFLAGS) + +LD=link +LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode +# "/farcall/packcode" are only useful for `large code' memory models +# but should be a "no-op" for small code models. + +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: $(ZLIB_LIB) example.exe minigzip.exe + +# individual dependencies and action rules: +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(LIB_CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(LIB_CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(LIB_CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(LIB_CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(LIB_CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + if exist $(ZLIB_LIB) del $(ZLIB_LIB) + lib $(ZLIB_LIB) $(OBJ1); + lib $(ZLIB_LIB) $(OBJ2); + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/Makefile.tc b/zlib-1.1.4/msdos/Makefile.tc new file mode 100644 index 0000000..63e0550 --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.tc @@ -0,0 +1,108 @@ +# Makefile for zlib +# TurboC 2.0 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=-ms + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C 2.0 ------------- +MODEL=l +# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z -m$(MODEL) +CC=tcc -I\tc\include +LD=tcc -L\tc\lib +AR=tlib +LDFLAGS=-m$(MODEL) -f- +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +ZLIB_H = zlib.h zconf.h +ZUTIL_H = zutil.h $(ZLIB_H) + +ZLIB_LIB = zlib_$(MODEL).lib + +all: test + +adler32.obj: adler32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c $(ZUTIL_H) infblock.h inftrees.h infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c $(ZUTIL_H) inftrees.h infutil.h infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c $(ZUTIL_H) infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c $(ZUTIL_H) inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c $(ZUTIL_H) inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c $(ZUTIL_H) inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c $(ZUTIL_H) + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c $(ZLIB_H) + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) +$(OBJP1) + $(AR) $(ZLIB_LIB) +$(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) -eexample.exe example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/Makefile.w32 b/zlib-1.1.4/msdos/Makefile.w32 new file mode 100644 index 0000000..0a05fa9 --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.w32 @@ -0,0 +1,97 @@ +# Makefile for zlib +# Microsoft 32-bit Visual C++ 4.0 or later (may work on earlier versions) + +# To use, do "nmake /f makefile.w32" + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft Visual C++ 4.0 and later ------------- +MODEL= +CFLAGS=-Ox -GA3s -nologo -W3 +CC=cl +LD=link +LDFLAGS= +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: zlib.lib example.exe minigzip.exe + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zlib.lib: $(OBJ1) $(OBJ2) + if exist zlib.lib del zlib.lib + lib /OUT:zlib.lib $(OBJ1) $(OBJ2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib /OUT:example.exe /SUBSYSTEM:CONSOLE + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib /OUT:minigzip.exe /SUBSYSTEM:CONSOLE + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/Makefile.wat b/zlib-1.1.4/msdos/Makefile.wat new file mode 100644 index 0000000..44bf860 --- /dev/null +++ b/zlib-1.1.4/msdos/Makefile.wat @@ -0,0 +1,103 @@ +# Makefile for zlib +# Watcom 10a + +# This version of the zlib makefile was adapted by Chris Young for use +# with Watcom 10a 32-bit protected mode flat memory model. It was created +# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to +# suit your needs but the -DMSDOS is required. +# -- Chris Young 76702.1655@compuserve.com + +# To use, do "wmake -f makefile.wat" + +# See zconf.h for details about the memory requirements. + +# ------------- Watcom 10a ------------- +MODEL=-mf +CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS +CC=wcc386 +LD=wcl386 +LIB=wlib -b -c +LDFLAGS= +O=.obj + +# variables +OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) +OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) +OBJ3=infutil$(O) inffast$(O) +OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O) +OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O) +OBJP3=infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +crc32.obj: crc32.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h & + infcodes.h infutil.h + $(CC) $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h & + infcodes.h inffast.h + $(CC) $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3) + del zlib.lib + $(LIB) zlib.lib +$(OBJP1) + $(LIB) zlib.lib +$(OBJP2) + $(LIB) zlib.lib +$(OBJP3) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: minigzip.exe example.exe + example + echo hello world | minigzip | minigzip -d >test + type test + +#clean: +# del *.obj +# del *.exe diff --git a/zlib-1.1.4/msdos/zlib.def b/zlib-1.1.4/msdos/zlib.def new file mode 100644 index 0000000..6c04412 --- /dev/null +++ b/zlib-1.1.4/msdos/zlib.def @@ -0,0 +1,60 @@ +LIBRARY "zlib" + +DESCRIPTION '"""zlib data compression library"""' + +EXETYPE NT + +SUBSYSTEM WINDOWS + +STUB 'WINSTUB.EXE' + +VERSION 1.13 + +CODE EXECUTE READ + +DATA READ WRITE + +HEAPSIZE 1048576,4096 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 diff --git a/zlib-1.1.4/msdos/zlib.rc b/zlib-1.1.4/msdos/zlib.rc new file mode 100644 index 0000000..556d4ff --- /dev/null +++ b/zlib-1.1.4/msdos/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,1,3,0 + PRODUCTVERSION 1,1,3,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", "1.1.3\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-1998 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/zlib-1.1.4/nt/Makefile.emx b/zlib-1.1.4/nt/Makefile.emx new file mode 100644 index 0000000..2d475b1 --- /dev/null +++ b/zlib-1.1.4/nt/Makefile.emx @@ -0,0 +1,138 @@ +# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc -Zwin32 + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/zlib-1.1.4/nt/Makefile.gcc b/zlib-1.1.4/nt/Makefile.gcc new file mode 100644 index 0000000..cdd652f --- /dev/null +++ b/zlib-1.1.4/nt/Makefile.gcc @@ -0,0 +1,87 @@ +# Makefile for zlib. Modified for mingw32 by C. Spieler, 6/16/98. +# (This Makefile is directly derived from Makefile.dj2) +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.gcc; make test -fmakefile.gcc +# +# To install libz.a, zconf.h and zlib.h in the mingw32 directories, type: +# +# make install -fmakefile.gcc +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/zlib-1.1.4/nt/Makefile.nt b/zlib-1.1.4/nt/Makefile.nt new file mode 100644 index 0000000..b250f2a --- /dev/null +++ b/zlib-1.1.4/nt/Makefile.nt @@ -0,0 +1,88 @@ +# Makefile for zlib + +!include + +CC=cl +LD=link +CFLAGS=-O -nologo +LDFLAGS= +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) + +all: zlib.dll example.exe minigzip.exe + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(cvarsdll) $(CFLAGS) $*.c + +zlib.dll: $(OBJ1) $(OBJ2) zlib.dnt + link $(dlllflags) -out:$@ -def:zlib.dnt $(OBJ1) $(OBJ2) $(guilibsdll) + +zlib.lib: zlib.dll + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + del *.obj + del *.exe + del *.dll + del *.lib diff --git a/zlib-1.1.4/nt/zlib.dnt b/zlib-1.1.4/nt/zlib.dnt new file mode 100644 index 0000000..7f9475c --- /dev/null +++ b/zlib-1.1.4/nt/zlib.dnt @@ -0,0 +1,47 @@ +LIBRARY zlib.dll +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 diff --git a/zlib-1.1.4/os2/Makefile.os2 b/zlib-1.1.4/os2/Makefile.os2 new file mode 100644 index 0000000..4f56947 --- /dev/null +++ b/zlib-1.1.4/os2/Makefile.os2 @@ -0,0 +1,136 @@ +# Makefile for zlib under OS/2 using GCC (PGCC) +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# cp Makefile.os2 .. +# cd .. +# make -f Makefile.os2 test + +# This makefile will build a static library z.lib, a shared library +# z.dll and a import library zdll.lib. You can use either z.lib or +# zdll.lib by specifying either -lz or -lzdll on gcc's command line + +CC=gcc -Zomf -s + +CFLAGS=-O6 -Wall +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +#################### BUG WARNING: ##################### +## infcodes.c hits a bug in pgcc-1.0, so you have to use either +## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) +## This bug is reportedly fixed in pgcc >1.0, but this was not tested +CFLAGS+=-fno-force-mem + +LDFLAGS=-s -L. -lzdll -Zcrtdll +LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll + +VER=1.1.0 +ZLIB=z.lib +SHAREDLIB=z.dll +SHAREDLIBIMP=zdll.lib +LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +AR=emxomfar cr +IMPLIB=emximp +RANLIB=echo +TAR=tar +SHELL=bash + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ + algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ + contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 + +all: example.exe minigzip.exe + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +$(ZLIB): $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +$(SHAREDLIB): $(OBJS) os2/z.def + $(LDSHARED) -o $@ $^ + +$(SHAREDLIBIMP): os2/z.def + $(IMPLIB) -o $@ $^ + +example.exe: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip.exe: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib-1.1.4/os2/zlib.def b/zlib-1.1.4/os2/zlib.def new file mode 100644 index 0000000..4c753f1 --- /dev/null +++ b/zlib-1.1.4/os2/zlib.def @@ -0,0 +1,51 @@ +; +; Slightly modified version of ../nt/zlib.dnt :-) +; + +LIBRARY Z +DESCRIPTION "Zlib compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 + compress + crc32 + deflate + deflateCopy + deflateEnd + deflateInit2_ + deflateInit_ + deflateParams + deflateReset + deflateSetDictionary + gzclose + gzdopen + gzerror + gzflush + gzopen + gzread + gzwrite + inflate + inflateEnd + inflateInit2_ + inflateInit_ + inflateReset + inflateSetDictionary + inflateSync + uncompress + zlibVersion + gzprintf + gzputc + gzgetc + gzseek + gzrewind + gztell + gzeof + gzsetparams + zError + inflateSyncPoint + get_crc_table + compress2 + gzputs + gzgets diff --git a/zlib-1.1.4/trees.c b/zlib-1.1.4/trees.c new file mode 100644 index 0000000..0a98405 --- /dev/null +++ b/zlib-1.1.4/trees.c @@ -0,0 +1,1214 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/zlib-1.1.4/trees.h b/zlib-1.1.4/trees.h new file mode 100644 index 0000000..72facf9 --- /dev/null +++ b/zlib-1.1.4/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/zlib-1.1.4/uncompr.c b/zlib-1.1.4/uncompr.c new file mode 100644 index 0000000..a287714 --- /dev/null +++ b/zlib-1.1.4/uncompr.c @@ -0,0 +1,58 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/zlib-1.1.4/zconf.h b/zlib-1.1.4/zconf.h new file mode 100644 index 0000000..eb0ae2e --- /dev/null +++ b/zlib-1.1.4/zconf.h @@ -0,0 +1,279 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/zlib-1.1.4/zlib.3 b/zlib-1.1.4/zlib.3 new file mode 100644 index 0000000..3a6e450 --- /dev/null +++ b/zlib-1.1.4/zlib.3 @@ -0,0 +1,107 @@ +.TH ZLIB 3 "11 March 2002" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.I gzip +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. The decoder checks +the consistency of the compressed data, so the library should never +crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h. +The distribution source includes examples of use of the library +the files +.I example.c +and +.IR minigzip.c . +.LP +A Java implementation of +.IR zlib +is available in the Java Development Kit 1.1 +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmarquess@bfsec.bt.co.uk) +is available at CPAN (Comprehensive Perl Archive Network) sites, +such as: +.IP +ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* +.LP +A Python interface to +.IR zlib +written by A.M. Kuchling +is available from the Python Software Association sites, such as: +.IP +ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz +.SH "SEE ALSO" +Questions about zlib should be sent to: +.IP +zlib@quest.jpl.nasa.gov +or, if this fails, to the author addresses given below. +The zlib home page is: +.IP +http://www.cdrom.com/pub/infozip/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) +.br +rfc1951.txt (deflate format) +.br +rfc1952.txt (gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.SH AUTHORS +Version 1.1.4 +Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/zlib-1.1.4/zlib.h b/zlib-1.1.4/zlib.h new file mode 100644 index 0000000..52cb529 --- /dev/null +++ b/zlib-1.1.4/zlib.h @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/zlib-1.1.4/zlib.html b/zlib-1.1.4/zlib.html new file mode 100644 index 0000000..c343703 --- /dev/null +++ b/zlib-1.1.4/zlib.html @@ -0,0 +1,971 @@ + + + + zlib general purpose compression library version 1.1.4 + + + + + +

    zlib 1.1.4 Manual

    +
    +

    Contents

    +
      +
    1. Prologue +
    2. Introduction +
    3. Utility functions +
    4. Basic functions +
    5. Advanced functions +
    6. Constants +
    7. struct z_stream_s +
    8. Checksum functions +
    9. Misc +
    +
    +

    Prologue

    + 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 +

    + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler +

    + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. +

    + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: +

      +
    1. The origin of this software must not be misrepresented ; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +
    2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +
    3. This notice may not be removed or altered from any source distribution. +
    + +
    +
    Jean-loup Gailly +
    jloup@gzip.org +
    Mark Adler +
    madler@alumni.caltech.edu +
    + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files + + ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), + + rfc1951.txt + (deflate format) and + + rfc1952.txt + (gzip format). +

    + This manual is converted from zlib.h by + piaip +

    + Visit + http://ftp.cdrom.com/pub/infozip/zlib/ + for the official zlib web page. +

    + +


    +

    Introduction

    + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. +

    + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +

    + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. +

    + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +

    + +


    +

    Utility functions

    + The following utility functions are implemented on top of the +
    basic stream-oriented functions. + To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +

    Function list

    +
      +
    • int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
    • int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
    • int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
    • typedef voidp gzFile; +
    • gzFile gzopen (const char *path, const char *mode); +
    • gzFile gzdopen (int fd, const char *mode); +
    • int gzsetparams (gzFile file, int level, int strategy); +
    • int gzread (gzFile file, voidp buf, unsigned len); +
    • int gzwrite (gzFile file, const voidp buf, unsigned len); +
    • int VA gzprintf (gzFile file, const char *format, ...); +
    • int gzputs (gzFile file, const char *s); +
    • char * gzgets (gzFile file, char *buf, int len); +
    • int gzputc (gzFile file, int c); +
    • int gzgetc (gzFile file); +
    • int gzflush (gzFile file, int flush); +
    • z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
    • z_off_t gztell (gzFile file); +
    • int gzrewind (gzFile file); +
    • int gzeof (gzFile file); +
    • int gzclose (gzFile file); +
    • const char * gzerror (gzFile file, int *errnum); +
    +

    Function description

    +
    +
    int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
    + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer.

    + This function can be used to compress a whole file at once if the + input file is mmap'ed.

    + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer.

    + +

    int compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +
    + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. +

    + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +

    + +

    int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +
    + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer.

    + This function can be used to decompress a whole file at once if the + input file is mmap'ed. +

    + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +

    + +

    typedef voidp gzFile; +

    + +

    gzFile gzopen (const char *path, const char *mode); +
    + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) +

    + + gzopen can be used to read a file which is not in gzip format ; in this + case gzread will directly read from the file without decompression. +

    + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state ; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +

    + +

    gzFile gzdopen (int fd, const char *mode); +
    + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. +

    + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +

    + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +

    + +

    int gzsetparams (gzFile file, int level, int strategy); +
    + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. +

    + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +

    + +

    int gzread (gzFile file, voidp buf, unsigned len); +
    + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. +

    + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). +

    + +

    int gzwrite (gzFile file, const voidp buf, unsigned len); +
    + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +

    + +

    int VA gzprintf (gzFile file, const char *format, ...); +
    + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +

    + +

    int gzputs (gzFile file, const char *s); +
    + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. +

    + gzputs returns the number of characters written, or -1 in case of error. +

    + +

    char * gzgets (gzFile file, char *buf, int len); +
    + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. +

    + gzgets returns buf, or Z_NULL in case of error. +

    + +

    int gzputc (gzFile file, int c); +
    + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +

    + +

    int gzgetc (gzFile file); +
    + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +

    + +

    int gzflush (gzFile file, int flush); +
    + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. +

    + gzflush should be called only when strictly necessary because it can + degrade compression. +

    + +

    z_off_t gzseek (gzFile file, z_off_t offset, int whence); +
    + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. +

    + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported ; gzseek then compresses a sequence of zeroes up to the new + starting position. +

    + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +

    + +

    int gzrewind (gzFile file); +
    + Rewinds the given file. This function is supported only for reading. +

    + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +

    + +

    z_off_t gztell (gzFile file); +
    + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +

    + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +

    + +

    int gzeof (gzFile file); +
    + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +

    + +

    int gzclose (gzFile file); +
    + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +

    + +

    const char * gzerror (gzFile file, int *errnum); +
    + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +

    +

    +
    +

    Basic functions

    +

    Function list

    +
    + +

    Function description

    +
    +
    const char * zlibVersion (void); +
    The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. +

    + +

    int deflateInit (z_streamp strm, int level); +
    + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. +

    + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). +

    + + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). +

    + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +

    + +

    int deflate (z_streamp strm, int flush); +
    + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush.

    + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + +

      +
    • Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + +
    • + Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. +

    + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly ; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. +

    + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. +

    + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. +

    + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). +

    + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space ; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. +

    + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. +

    + + deflate() sets strm-> adler to the adler32 checksum of all input read + so far (that is, total_in bytes). +

    + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. +

    + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +

    + +

    int deflateEnd (z_streamp strm); +
    + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

    + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +

    + +

    int inflateInit (z_streamp strm); +
    + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly ; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. +

    + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +

    + +

    int inflate (z_streamp strm, int flush); +
    + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. +

    + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + +

      +
    • Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + +
    • Provide more output starting at next_out and update next_out and + avail_out accordingly. inflate() provides as much output as possible, + until there is no more input data or no more space in the output buffer + (see below about the flush parameter). +

    + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. +

    + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. +

    + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed ; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. +

    + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT ; otherwise + it sets strm-> adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. +

    + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +

    + +

    int inflateEnd (z_streamp strm); +
    + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. +

    + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +

    +
    +

    Advanced functions

    + The following functions are needed only in some special applications. +

    Function list

    +
    +

    Function description

    +
    +
    int deflateInit2 (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); + +
    This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller.

    + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library.

    + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead.

    + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio ; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel.

    + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching ; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately.

    + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate().

    + +

    int deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
    + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary).

    + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy ; the data can then be compressed better than + with the default empty dictionary.

    + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front.

    + + Upon return of this function, strm-> adler is set to the Adler32 value + of the dictionary ; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.)

    + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate().

    + +

    int deflateCopy (z_streamp dest, z_streamp source); +
    + Sets the destination stream as a complete copy of the source stream.

    + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory.

    + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination.

    + +

    int deflateReset (z_streamp strm); +
    This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2.

    + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL).

    + +

    int deflateParams (z_streamp strm, int level, int strategy); +
    + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate().

    + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm-> avail_out must be + non-zero.

    + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero.

    + +

    int inflateInit2 (z_streamp strm, int windowBits); + +
    This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller.

    + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window.

    + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.)

    + +

    int inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength); +
    + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary).

    + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate().

    + +

    int inflateSync (z_streamp strm); + +
    Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided.

    + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data.

    + +

    int inflateReset (z_streamp strm); +
    + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. +

    + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +

    +

    + +
    +

    Checksum functions

    + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +

    Function list

    +
    +

    Function description

    +
    +
    uLong adler32 (uLong adler, const Bytef *buf, uInt len); +
    + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. +

    + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: +

    +
    +     uLong adler = adler32(0L, Z_NULL, 0);
    +
    +     while (read_buffer(buffer, length) != EOF) {
    +       adler = adler32(adler, buffer, length);
    +     }
    +     if (adler != original_adler) error();
    +   
    + +
    uLong crc32 (uLong crc, const Bytef *buf, uInt len); +
    + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: +
    +
    +     uLong crc = crc32(0L, Z_NULL, 0);
    +
    +     while (read_buffer(buffer, length) != EOF) {
    +       crc = crc32(crc, buffer, length);
    +     }
    +     if (crc != original_crc) error();
    +   
    +
    +
    +

    struct z_stream_s

    + +
    +
    +typedef struct z_stream_s {
    +    Bytef    *next_in;  /* next input byte */
    +    uInt     avail_in;  /* number of bytes available at next_in */
    +    uLong    total_in;  /* total nb of input bytes read so far */
    +
    +    Bytef    *next_out; /* next output byte should be put there */
    +    uInt     avail_out; /* remaining free space at next_out */
    +    uLong    total_out; /* total nb of bytes output so far */
    +
    +    char     *msg;      /* last error message, NULL if no error */
    +    struct internal_state FAR *state; /* not visible by applications */
    +
    +    alloc_func zalloc;  /* used to allocate the internal state */
    +    free_func  zfree;   /* used to free the internal state */
    +    voidpf     opaque;  /* private data object passed to zalloc and zfree */
    +
    +    int     data_type;  /* best guess about the data type: ascii or binary */
    +    uLong   adler;      /* adler32 value of the uncompressed data */
    +    uLong   reserved;   /* reserved for future use */
    +} z_stream ;
    +
    +typedef z_stream FAR * z_streamp;  ÿ 
    +
    +
    + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application.

    + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value.

    + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe.

    + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). +

    + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step).

    + +


    +

    Constants

    + +
    +#define Z_NO_FLUSH      0
    +#define Z_PARTIAL_FLUSH 1 
    +	/* will be removed, use Z_SYNC_FLUSH instead */
    +#define Z_SYNC_FLUSH    2
    +#define Z_FULL_FLUSH    3
    +#define Z_FINISH        4
    +/* Allowed flush values ; see deflate() below for details */
    +
    +#define Z_OK            0
    +#define Z_STREAM_END    1
    +#define Z_NEED_DICT     2
    +#define Z_ERRNO        (-1)
    +#define Z_STREAM_ERROR (-2)
    +#define Z_DATA_ERROR   (-3)
    +#define Z_MEM_ERROR    (-4)
    +#define Z_BUF_ERROR    (-5)
    +#define Z_VERSION_ERROR (-6)
    +/* Return codes for the compression/decompression functions. Negative
    + * values are errors, positive values are used for special but normal events.
    + */
    +
    +#define Z_NO_COMPRESSION         0
    +#define Z_BEST_SPEED             1
    +#define Z_BEST_COMPRESSION       9
    +#define Z_DEFAULT_COMPRESSION  (-1)
    +/* compression levels */
    +
    +#define Z_FILTERED            1
    +#define Z_HUFFMAN_ONLY        2
    +#define Z_DEFAULT_STRATEGY    0
    +/* compression strategy ; see deflateInit2() below for details */
    +
    +#define Z_BINARY   0
    +#define Z_ASCII    1
    +#define Z_UNKNOWN  2
    +/* Possible values of the data_type field */
    +
    +#define Z_DEFLATED   8
    +/* The deflate compression method (the only one supported in this version) */
    +
    +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
    +
    +#define zlib_version zlibVersion()
    +/* for compatibility with versions less than 1.0.2 */
    +
    +
    + +
    +

    Misc

    +
    deflateInit and inflateInit are macros to allow checking the zlib version + and the compiler's view of z_stream. +

    + Other functions: +

    +
    const char * zError (int err); +
    int inflateSyncPoint (z_streamp z); +
    const uLongf * get_crc_table (void); +
    +
    + + Last update: Wed Oct 13 20:42:34 1999
    + piapi@csie.ntu.edu.tw +
    + + + diff --git a/zlib-1.1.4/zutil.c b/zlib-1.1.4/zutil.c new file mode 100644 index 0000000..dfc38ec --- /dev/null +++ b/zlib-1.1.4/zutil.c @@ -0,0 +1,225 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/zlib-1.1.4/zutil.h b/zlib-1.1.4/zutil.h new file mode 100644 index 0000000..718ebc1 --- /dev/null +++ b/zlib-1.1.4/zutil.h @@ -0,0 +1,220 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ -- cgit v1.2.3